diff --git a/AUTHORS b/AUTHORS
index 3b74ab59..114a021 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1201,6 +1201,7 @@
 Waihung Fu <fufranci@amazon.com>
 wafuwafu13 <mariobaske@i.softbank.jp>
 Wojciech Bielawski <wojciech.bielawski@gmail.com>
+Wang Weiwei <wangww@dingdao.com>
 Wanming Lin <wanming.lin@intel.com>
 Wei Li <wei.c.li@intel.com>
 Wen Fan <fanwen1@huawei.com>
@@ -1322,6 +1323,7 @@
 CoSMo Software pvt ltd <*@cosmosoftware.io>
 Cosium <*@cosium.com>
 Dell Technologies Inc. <*@dell.corp-partner.google.com>
+Ding (Beijing) Intelligent Technology Co. Ltd <*@dingdao.com>
 Duck Duck Go, Inc. <*@duckduckgo.com>
 Endless Mobile, Inc. <*@endlessm.com>
 EngFlow, Inc. <*@engflow.com>
diff --git a/DEPS b/DEPS
index 62219e6b..a31ae90 100644
--- a/DEPS
+++ b/DEPS
@@ -253,23 +253,23 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'd48eb476974ef37cbe91e76e3cebe25d8e984618',
+  'skia_revision': '557f2795f2497cf2b742eeeebefee55fe10fb68c',
   # 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': 'a58f124b22e45cfe9cdacfb6275a4e61f556f17c',
+  'v8_revision': 'fbc6a09b6f5a0d1951f41de413a4e3f1fce5ca76',
   # 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': '7f03fb5d8c18f802a91f494ce792204f06864508',
+  'angle_revision': '8390196a308b611abf9f5364c210478e4ce25f92',
   # 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': '5ff2f732f22209099eeb63d25255bc032513a650',
+  'swiftshader_revision': '310874c922a83b44ab8e3d32cd5f240e8065fdae',
   # 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': 'b94a462ff2cb708a2e99f9c994dfef41326ce4e2',
+  'pdfium_revision': '8bc6915d4bac163b72fc2db031f5aa0369905129',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -320,7 +320,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': '392c66f379f22799379b5d10d577bb2a73b2723c',
+  'catapult_revision': '666eff907b58ca7b4c82c0fae4c6e1d24f223ea0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -328,7 +328,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': '4704d83e802a322e5925559d2049d391de44dc34',
+  'devtools_frontend_revision': '02c8529ba050f8c2c6a53f7819485a37280e4ded',
   # 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.
@@ -368,7 +368,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'ec3e4b05108e5300d0ff29c09bc637489565df81',
+  'dawn_revision': 'f0544b87bc75382d170af711ef8b01ae259182ef',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -416,7 +416,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.
-  'libunwind_revision':    '8cd7191937c9341646c88e39eae63ccd692ace91',
+  'libunwind_revision':    '2ea265b95a08e4a98fab16b327119788b8e50a69',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1514,7 +1514,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '7a29efcb91ff562d9fbb61b9490ef8f71983b9f2',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5b5f79bbdb2a2d59c88f02394cac1b08298a3da7',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1592,7 +1592,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/android/aemu/release/linux-amd64',
-              'version': '5nrz36x1BPEiBNihW7PradI5DX-aYmpWseto1xMeFpIC'
+              'version': '5oOn194ItrPuR5B-IrGTR0tFqinYs3tfonzbKESY3EQC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1732,10 +1732,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'cf04aebdf9b53bb2853f22a81465688daf879ec6',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '96e54a1b92e78f651941f64c703b98a34df37a1f',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '48cf29b0b746a3d74cdbb75ae4124a29be15bd14',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '83829687815e5d72234e24bf23b31140a8e830be',
+    Var('webrtc_git') + '/src.git' + '@' + '7c2e958711aaa17fc03b937bf0657230e7bb1dde',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1805,7 +1805,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@431c4a2d1aaca07f8f8309e7f195be161194f732',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c98a47bd27b987fae010f2858916ab485bd31c83',
     'condition': 'checkout_src_internal',
   },
 
@@ -1857,7 +1857,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'PYuNrTlHOcXoN756Ls6NheL3fUbyrEJpZssl-TB_13kC',
+        'version': 'E4fDrVqxPQU3eACEOcotbl_cPmAhOxPmtj0yvQW3c_AC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc
index 12d9709..56e69c9 100644
--- a/android_webview/browser/aw_contents.cc
+++ b/android_webview/browser/aw_contents.cc
@@ -418,18 +418,6 @@
   return render_process->GetJavaObject();
 }
 
-ScopedJavaLocalRef<jstring> AwContents::GetVariationsHeader(JNIEnv* env) {
-  const bool is_signed_in = false;
-  auto headers =
-      variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders(
-          is_signed_in);
-  if (!headers)
-    return ConvertUTF8ToJavaString(env, "");
-  return ConvertUTF8ToJavaString(
-      env,
-      headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY));
-}
-
 void AwContents::Destroy(JNIEnv* env) {
   java_ref_.reset();
   delete this;
diff --git a/android_webview/browser/aw_contents.h b/android_webview/browser/aw_contents.h
index 9674bb99..d10b619e 100644
--- a/android_webview/browser/aw_contents.h
+++ b/android_webview/browser/aw_contents.h
@@ -111,7 +111,6 @@
   base::android::ScopedJavaLocalRef<jobject> GetRenderProcess(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
-  base::android::ScopedJavaLocalRef<jstring> GetVariationsHeader(JNIEnv* env);
 
   void Destroy(JNIEnv* env);
   void DocumentHasImages(JNIEnv* env,
diff --git a/android_webview/browser/aw_contents_statics.cc b/android_webview/browser/aw_contents_statics.cc
index a595ed1..00a9c1c 100644
--- a/android_webview/browser/aw_contents_statics.cc
+++ b/android_webview/browser/aw_contents_statics.cc
@@ -17,6 +17,7 @@
 #include "components/flags_ui/flags_ui_metrics.h"
 #include "components/google/core/common/google_util.h"
 #include "components/security_interstitials/core/urls.h"
+#include "components/variations/variations_ids_provider.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -161,4 +162,18 @@
   return !content::RenderProcessHost::run_renderer_in_process();
 }
 
+// static
+ScopedJavaLocalRef<jstring> JNI_AwContentsStatics_GetVariationsHeader(
+    JNIEnv* env) {
+  const bool is_signed_in = false;
+  auto headers =
+      variations::VariationsIdsProvider::GetInstance()->GetClientDataHeaders(
+          is_signed_in);
+  if (!headers)
+    return base::android::ConvertUTF8ToJavaString(env, "");
+  return base::android::ConvertUTF8ToJavaString(
+      env,
+      headers->headers_map.at(variations::mojom::GoogleWebVisibility::ANY));
+}
+
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_dark_mode.cc b/android_webview/browser/aw_dark_mode.cc
index c39a948a..c38a1d1 100644
--- a/android_webview/browser/aw_dark_mode.cc
+++ b/android_webview/browser/aw_dark_mode.cc
@@ -138,9 +138,7 @@
         break;
       }
     }
-  } else if (prefers_dark_from_theme_ &&
-             base::FeatureList::IsEnabled(
-                 android_webview::features::kWebViewDarkModeMatchTheme)) {
+  } else if (prefers_dark_from_theme_) {
     web_prefs->preferred_color_scheme =
         blink::mojom::PreferredColorScheme::kDark;
     if (base::FeatureList::IsEnabled(
diff --git a/android_webview/browser/aw_feature_entries.cc b/android_webview/browser/aw_feature_entries.cc
index b76bf16a..03950e8 100644
--- a/android_webview/browser/aw_feature_entries.cc
+++ b/android_webview/browser/aw_feature_entries.cc
@@ -31,7 +31,7 @@
 // preferred variation if it is turned on.
 constexpr flags_ui::FeatureEntry::FeatureVariation kForceDarkVariations[] = {
     {"with selective image inversion", kForceDark_SelectiveImageInversion,
-     base::size(kForceDark_SelectiveImageInversion), nullptr}};
+     std::size(kForceDark_SelectiveImageInversion), nullptr}};
 
 // Not for display, set the descriptions to empty.
 constexpr flags_ui::FeatureEntry kForceDark = {
diff --git a/android_webview/browser/aw_feature_entries_unittest.cc b/android_webview/browser/aw_feature_entries_unittest.cc
index ff9ccc5..d2f3e094 100644
--- a/android_webview/browser/aw_feature_entries_unittest.cc
+++ b/android_webview/browser/aw_feature_entries_unittest.cc
@@ -43,11 +43,11 @@
 
 const flags_ui::FeatureEntry::FeatureVariation kForceDarkVariations[] = {
     {"with simple HSL-based inversion", kForceDark_SimpleHsl,
-     base::size(kForceDark_SimpleHsl), nullptr},
+     std::size(kForceDark_SimpleHsl), nullptr},
     {"with simple CIELAB-based inversion", kForceDark_SimpleCielab,
-     base::size(kForceDark_SimpleCielab), nullptr},
+     std::size(kForceDark_SimpleCielab), nullptr},
     {"with simple RGB-based inversion", kForceDark_SimpleRgb,
-     base::size(kForceDark_SimpleRgb), nullptr}};
+     std::size(kForceDark_SimpleRgb), nullptr}};
 
 // Not for display, set the descriptions to empty.
 flags_ui::FeatureEntry kForceDark = {
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 3b8d6ff..1a88635 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
@@ -12,7 +12,6 @@
 
 #include "android_webview/common/metrics/app_package_name_logging_rule.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -77,7 +76,7 @@
 
   void WritePackageNamesAllowListToFile() {
     auto filter = std::make_unique<optimization_guide::BloomFilter>(
-        kNumHash, kNumBitsPerEntry * base::size(kTestAllowlist));
+        kNumHash, kNumBitsPerEntry * std::size(kTestAllowlist));
     for (const auto& package : kTestAllowlist) {
       filter->Add(package);
     }
diff --git a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc
index 081c26eb..77b5f85 100644
--- a/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc
+++ b/android_webview/browser/component_updater/loader_policies/empty_component_loader_policy.cc
@@ -13,7 +13,6 @@
 
 #include "android_webview/common/aw_features.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/scoped_file.h"
 #include "base/values.h"
@@ -46,7 +45,7 @@
 
 void EmptyComponentLoaderPolicy::GetHash(std::vector<uint8_t>* hash) const {
   hash->assign(kFakePublicKeySHA256,
-               kFakePublicKeySHA256 + base::size(kFakePublicKeySHA256));
+               kFakePublicKeySHA256 + std::size(kFakePublicKeySHA256));
 }
 
 std::string EmptyComponentLoaderPolicy::GetMetricsSuffix() const {
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc
index e35cf44..5f5bb36 100644
--- a/android_webview/browser/gfx/aw_draw_fn_impl.cc
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -139,10 +139,10 @@
   if (color_space)
     hr_params.color_space = gfx::ColorSpace(*color_space);
 
-  static_assert(base::size(decltype(params->transform){}) ==
-                    base::size(hr_params.transform),
+  static_assert(std::size(decltype(params->transform){}) ==
+                    std::size(hr_params.transform),
                 "transform size mismatch");
-  for (size_t i = 0; i < base::size(hr_params.transform); ++i) {
+  for (size_t i = 0; i < std::size(hr_params.transform); ++i) {
     hr_params.transform[i] = params->transform[i];
   }
 
diff --git a/android_webview/browser/gfx/aw_gl_functor.cc b/android_webview/browser/gfx/aw_gl_functor.cc
index 22bd1e8..0c22357 100644
--- a/android_webview/browser/gfx/aw_gl_functor.cc
+++ b/android_webview/browser/gfx/aw_gl_functor.cc
@@ -6,7 +6,6 @@
 
 #include "android_webview/browser_jni_headers/AwGLFunctor_jni.h"
 #include "android_webview/public/browser/draw_gl.h"
-#include "base/cxx17_backports.h"
 #include "base/trace_event/trace_event.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -112,10 +111,10 @@
           draw_info->clip_left,   draw_info->clip_top, draw_info->clip_right,
           draw_info->clip_bottom, draw_info->width,    draw_info->height,
       };
-      static_assert(base::size(decltype(draw_info->transform){}) ==
-                        base::size(params.transform),
+      static_assert(std::size(decltype(draw_info->transform){}) ==
+                        std::size(params.transform),
                     "transform size mismatch");
-      for (unsigned int i = 0; i < base::size(params.transform); ++i) {
+      for (unsigned int i = 0; i < std::size(params.transform); ++i) {
         params.transform[i] = draw_info->transform[i];
       }
       render_thread_manager_.DrawOnRT(save_restore, params, OverlaysParams());
diff --git a/android_webview/browser/gfx/browser_view_renderer_unittest.cc b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
index 6598dd4d..ea03a35 100644
--- a/android_webview/browser/gfx/browser_view_renderer_unittest.cc
+++ b/android_webview/browser/gfx/browser_view_renderer_unittest.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "android_webview/browser/gfx/browser_view_renderer.h"
+
 #include <map>
 #include <memory>
 #include <queue>
 #include <utility>
 
-#include "android_webview/browser/gfx/browser_view_renderer.h"
 #include "android_webview/browser/gfx/child_frame.h"
 #include "android_webview/browser/gfx/compositor_frame_consumer.h"
 #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/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -493,7 +493,7 @@
         {1u, viz::ResourceId(3u)},
         {1u, viz::ResourceId(4u)},
     };
-    if (frame_number >= static_cast<int>(base::size(infos))) {
+    if (frame_number >= static_cast<int>(std::size(infos))) {
       return nullptr;
     }
 
diff --git a/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc b/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
index c9ce758..27f777cf 100644
--- a/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
+++ b/android_webview/browser/lifecycle/aw_contents_lifecycle_notifier.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "android_webview/browser_jni_headers/AwContentsLifecycleNotifier_jni.h"
-#include "base/cxx17_backports.h"
 #include "content/public/browser/browser_thread.h"
 
 using base::android::AttachCurrentThread;
@@ -153,7 +152,7 @@
 
 size_t AwContentsLifecycleNotifier::ToIndex(AwContentsState state) const {
   size_t index = static_cast<size_t>(state);
-  DCHECK(index < base::size(state_count_));
+  DCHECK(index < std::size(state_count_));
   return index;
 }
 
@@ -195,7 +194,7 @@
 }
 
 bool AwContentsLifecycleNotifier::HasAwContentsInstance() const {
-  for (size_t i = 0; i < base::size(state_count_); i++) {
+  for (size_t i = 0; i < std::size(state_count_); i++) {
     if (state_count_[i] > 0)
       return true;
   }
diff --git a/android_webview/browser/metrics/visibility_metrics_logger.cc b/android_webview/browser/metrics/visibility_metrics_logger.cc
index 8784c5ab..e1a85066 100644
--- a/android_webview/browser/metrics/visibility_metrics_logger.cc
+++ b/android_webview/browser/metrics/visibility_metrics_logger.cc
@@ -5,7 +5,6 @@
 #include "android_webview/browser/metrics/visibility_metrics_logger.h"
 
 #include "android_webview/common/aw_features.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_base.h"
@@ -166,7 +165,7 @@
   all_clients_tracker_.per_webview_untracked_duration_ +=
       delta * (client_visibility_.size() - all_clients_visible_count_);
 
-  for (size_t i = 0; i < base::size(per_scheme_visible_counts_); i++) {
+  for (size_t i = 0; i < std::size(per_scheme_visible_counts_); i++) {
     if (!per_scheme_visible_counts_[i])
       continue;
     per_scheme_trackers_[i].any_webview_tracked_duration_ += delta;
@@ -281,7 +280,7 @@
 }
 
 void VisibilityMetricsLogger::RecordVisibleSchemeMetrics() {
-  for (size_t i = 0; i < base::size(per_scheme_trackers_); i++) {
+  for (size_t i = 0; i < std::size(per_scheme_trackers_); i++) {
     Scheme scheme = static_cast<Scheme>(i);
     auto& tracker = per_scheme_trackers_[i];
 
@@ -304,7 +303,7 @@
 void VisibilityMetricsLogger::RecordScreenPortionMetrics() {
   if (!base::FeatureList::IsEnabled(features::kWebViewMeasureScreenCoverage))
     return;
-  for (size_t i = 0; i < base::size(open_web_screen_portion_tracked_duration_);
+  for (size_t i = 0; i < std::size(open_web_screen_portion_tracked_duration_);
        i++) {
     int32_t elapsed_seconds =
         open_web_screen_portion_tracked_duration_[i].InSeconds();
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc
index b7a19fa1..c6eb83e 100644
--- a/android_webview/common/aw_features.cc
+++ b/android_webview/common/aw_features.cc
@@ -20,11 +20,6 @@
 const base::Feature kWebViewConnectionlessSafeBrowsing{
     "WebViewConnectionlessSafeBrowsing", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enable WebView to set prefers-color-theme according to the app's theme unless
-// app specifies FORCE_DARK_OFF or DARK_STRATEGY_USER_AGENT_DARKENING_ONLY.
-const base::Feature kWebViewDarkModeMatchTheme{
-    "WebViewDarkModeMatchTheme", base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enable WebView to automatically darken the page in FORCE_DARK_AUTO mode if
 // the app's theme is dark.
 const base::Feature kWebViewForceDarkModeMatchTheme{
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h
index a102e4a..24cfb85 100644
--- a/android_webview/common/aw_features.h
+++ b/android_webview/common/aw_features.h
@@ -18,7 +18,6 @@
 extern const base::Feature kWebViewAppsPackageNamesAllowlist;
 extern const base::Feature kWebViewBrotliSupport;
 extern const base::Feature kWebViewConnectionlessSafeBrowsing;
-extern const base::Feature kWebViewDarkModeMatchTheme;
 extern const base::Feature kWebViewDisplayCutout;
 extern const base::Feature kWebViewEmptyComponentLoaderPolicy;
 extern const base::Feature kWebViewExtraHeadersSameOriginOnly;
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 1425b0b..fc0c3036 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
@@ -5,7 +5,6 @@
 #include "android_webview/common/components/aw_apps_package_names_allowlist_component_utils.h"
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 
 namespace android_webview {
 
@@ -25,10 +24,9 @@
 void GetWebViewAppsPackageNamesAllowlistPublicKeyHash(
     std::vector<uint8_t>* hash) {
   DCHECK(hash);
-  hash->assign(
-      kWebViewAppsPackageNamesAllowlistPublicKeySHA256,
-      kWebViewAppsPackageNamesAllowlistPublicKeySHA256 +
-          base::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256));
+  hash->assign(kWebViewAppsPackageNamesAllowlistPublicKeySHA256,
+               kWebViewAppsPackageNamesAllowlistPublicKeySHA256 +
+                   std::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
index 81911a1..8a2d1dad 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedStatics.java
@@ -122,4 +122,8 @@
     public boolean isMultiProcessEnabled() {
         return AwContentsStatics.isMultiProcessEnabled();
     }
+
+    public String getVariationsHeader() {
+        return AwContentsStatics.getVariationsHeader();
+    }
 }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
index cd31a2af..9f0a2a0e 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewChromium.java
@@ -174,14 +174,6 @@
         return mContentsClientAdapter.getWebViewRendererClientAdapter();
     }
 
-    public String getVariationsHeader() {
-        mAwInit.startYourEngines(true);
-        if (checkNeedsPost()) {
-            return mRunQueue.runOnUiThreadBlocking(() -> getVariationsHeader());
-        }
-        return mAwContents.getVariationsHeader();
-    }
-
     protected boolean checkNeedsPost() {
         boolean needsPost = !mRunQueue.chromiumHasStarted() || !ThreadUtils.runningOnUiThread();
         if (!needsPost && mAwContents == null) {
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
index b2ddbdb..ca52151 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -659,6 +659,10 @@
                     public boolean isMultiProcessEnabled() {
                         return sharedStatics.isMultiProcessEnabled();
                     }
+
+                    public String getVariationsHeader() {
+                        return sharedStatics.getVariationsHeader();
+                    }
                 };
             }
         }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 3020ed3..c165420 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -3512,13 +3512,6 @@
         return AwContentsJni.get().getRenderProcess(mNativeAwContents, AwContents.this);
     }
 
-    public String getVariationsHeader() {
-        if (isDestroyed(NO_WARN)) {
-            return "";
-        }
-        return AwContentsJni.get().getVariationsHeader(mNativeAwContents);
-    }
-
     @VisibleForTesting
     public AwDisplayCutoutController getDisplayCutoutController() {
         return mDisplayCutoutController;
@@ -4432,6 +4425,5 @@
         WebMessageListenerInfo[] getJsObjectsInfo(
                 long nativeAwContents, AwContents caller, Class clazz);
         void onConfigurationChanged(long nativeAwContents);
-        String getVariationsHeader(long nativeAwContents);
     }
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
index f4594c4..f973e50b 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -179,6 +179,13 @@
         return AwContentsStaticsJni.get().isMultiProcessEnabled();
     }
 
+    /**
+     * Returns the variations header used with the X-Client-Data header.
+     */
+    public static String getVariationsHeader() {
+        return AwContentsStaticsJni.get().getVariationsHeader();
+    }
+
     @NativeMethods
     interface Natives {
         void logCommandLineForDebugging();
@@ -193,5 +200,6 @@
         void setSafeBrowsingAllowlist(String[] urls, Callback<Boolean> callback);
         void setCheckClearTextPermitted(boolean permitted);
         boolean isMultiProcessEnabled();
+        String getVariationsHeader();
     }
 }
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 7e93ae5..b0708539 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
@@ -197,9 +197,6 @@
                     "Enables use selective image inversion to automatically darken page, it will be"
                             + " used when WebView is in dark mode, but website doesn't provide dark"
                             + " style."),
-            Flag.baseFeature(AwFeatures.WEBVIEW_DARK_MODE_MATCH_THEME,
-                    "Set prefers-color-theme according to the app's theme unless the app specifies"
-                            + " FORCE_DARK_OFF or DARK_STRATEGY_USER_AGENT_DARKENING_ONLY."),
             Flag.baseFeature(AwFeatures.WEBVIEW_FORCE_DARK_MODE_MATCH_THEME,
                     "Automatically darken page if"
                             + " WebView is set to FORCE_DARK_AUTO and the app has dark theme"),
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwDarkModeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwDarkModeTest.java
index 55471a0..8b49ea42 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwDarkModeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwDarkModeTest.java
@@ -93,10 +93,8 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    @CommandLineFlags.Add({"disable-features=WebViewForceDarkModeMatchTheme",
-            "enable-features=WebViewDarkModeMatchTheme"})
-    public void
-    testLightThemeFalseWithMatchThemeDisabled() throws Throwable {
+    @CommandLineFlags.Add({"disable-features=WebViewForceDarkModeMatchTheme"})
+    public void testLightThemeFalseWithMatchThemeDisabled() throws Throwable {
         DarkModeHelper.setsLightThemeForTesting(DarkModeHelper.LightTheme.LIGHT_THEME_FALSE);
         final String url = mWebServer.setResponse(FILE, DATA, null);
         loadUrlSync(url);
@@ -107,8 +105,7 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    @CommandLineFlags.
-    Add({"enable-features=WebViewForceDarkModeMatchTheme,WebViewDarkModeMatchTheme"})
+    @CommandLineFlags.Add({"enable-features=WebViewForceDarkModeMatchTheme"})
     public void testLightThemeFalse() throws Throwable {
         DarkModeHelper.setsLightThemeForTesting(DarkModeHelper.LightTheme.LIGHT_THEME_FALSE);
         final String url = mWebServer.setResponse(FILE, DATA, null);
@@ -120,7 +117,6 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView"})
-    @CommandLineFlags.Add({"enable-features=WebViewDarkModeMatchTheme"})
     public void testConfigurationChanged() throws Throwable {
         DarkModeHelper.setsLightThemeForTesting(DarkModeHelper.LightTheme.LIGHT_THEME_TRUE);
         final String url = mWebServer.setResponse(FILE, DATA, null);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
index a06fc9c..e826ed28 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
@@ -199,8 +199,8 @@
             boolean isSameDocument, boolean isFragmentNavigation, boolean isRendererInitiated,
             int transition) {
         NavigationHandle navigation = new NavigationHandle(0 /* navigationHandleProxy */, gurl,
-                null, null, isInPrimaryMainFrame, isSameDocument, isRendererInitiated, null, null,
-                transition, false, false, false, false, 0);
+                GURL.emptyGURL(), GURL.emptyGURL(), isInPrimaryMainFrame, isSameDocument,
+                isRendererInitiated, null, null, transition, false, false, false, false, 0);
         mWebContentsObserver.didStartNavigation(navigation);
 
         navigation.didFinish(gurl, isErrorPage, true /* hasCommitted */, isFragmentNavigation,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
index 9a94eaa..29a7a59b 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsHeadersTest.java
@@ -14,6 +14,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.AwContentsStatics;
 import org.chromium.android_webview.common.PlatformServiceBridge;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -82,7 +83,7 @@
     public void testMatchesApiValue() throws Throwable {
         mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), mUrl);
         String serverHeaderValue = mTestServer.getLastRequest(PATH).headerValue(HEADER_NAME);
-        Assert.assertEquals(serverHeaderValue, mAwContents.getVariationsHeader());
+        Assert.assertEquals(serverHeaderValue, AwContentsStatics.getVariationsHeader());
     }
 
     @CommandLineFlags.Add({"disable-features=WebViewSendVariationsHeaders"})
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 23ac395..d60c13b 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,7 +7,6 @@
 #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/test/task_environment.h"
@@ -44,7 +43,7 @@
   expected.assign(
       kWebViewAppsPackageNamesAllowlistPublicKeySHA256,
       kWebViewAppsPackageNamesAllowlistPublicKeySHA256 +
-          base::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256));
+          std::size(kWebViewAppsPackageNamesAllowlistPublicKeySHA256));
 
   std::vector<uint8_t> actual;
   policy->GetHash(&actual);
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java
index c2d3864..e13b77a 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java
@@ -20,4 +20,5 @@
     void setSafeBrowsingWhitelist(List<String> hosts, ValueCallback<Boolean> callback);
     Uri getSafeBrowsingPrivacyPolicyUrl();
     boolean isMultiProcessEnabled();
+    String getVariationsHeader();
 }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
index c59afcf..d524b31 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
@@ -28,5 +28,4 @@
     /* WebViewRendererClient */ InvocationHandler getWebViewRendererClient();
     void setWebViewRendererClient(
             /* WebViewRendererClient */ InvocationHandler webViewRendererClient);
-    String getVariationsHeader();
 }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java
index a52884070..0b0dd257 100644
--- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java
@@ -135,10 +135,4 @@
                         ? new SupportLibWebViewRendererClientAdapter(webViewRendererClient)
                         : null);
     }
-
-    @Override
-    public String getVariationsHeader() {
-        recordApiCall(ApiCall.GET_VARIATIONS_HEADER);
-        return mSharedWebViewChromium.getVariationsHeader();
-    }
 }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
index c26be720..e81724b 100644
--- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
@@ -284,6 +284,12 @@
             recordApiCall(ApiCall.IS_MULTI_PROCESS_ENABLED);
             return mSharedStatics.isMultiProcessEnabled();
         }
+
+        @Override
+        public String getVariationsHeader() {
+            recordApiCall(ApiCall.GET_VARIATIONS_HEADER);
+            return mSharedStatics.getVariationsHeader();
+        }
     }
 
     @Override
diff --git a/android_webview/tools/cts_config/webview_cts_gcs_path.json b/android_webview/tools/cts_config/webview_cts_gcs_path.json
index 5b768e8..c9ed03df 100644
--- a/android_webview/tools/cts_config/webview_cts_gcs_path.json
+++ b/android_webview/tools/cts_config/webview_cts_gcs_path.json
@@ -79,6 +79,10 @@
           {
             "match": "android.webkit.cts.WebSettingsTest#testAppCacheEnabled",
             "_bug_id": "crbug.com/1246334"
+          },
+          {
+            "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHit",
+            "_bug_id": "crbug.com/1300977"
           }
         ]
       },
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index c92c622..27eb90f 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/accelerators/accelerator_controller_impl.h"
-
 #include <utility>
 
+#include "ash/accelerators/accelerator_controller_impl.h"
 #include "ash/accelerators/accelerator_history_impl.h"
 #include "ash/accelerators/accelerator_notifications.h"
 #include "ash/accelerators/accelerator_table.h"
@@ -57,7 +56,6 @@
 #include "ash/wm/wm_event.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_writer.h"
@@ -1123,7 +1121,7 @@
       {true, ui::VKEY_J, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
       {true, ui::VKEY_K, ui::EF_ALT_DOWN, TOGGLE_FULLSCREEN},
   };
-  test_api_->RegisterAccelerators(accelerators, base::size(accelerators));
+  test_api_->RegisterAccelerators(accelerators, std::size(accelerators));
 
   views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
   params.bounds = gfx::Rect(5, 5, 20, 20);
diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc
index 59ea313..c3ade54 100644
--- a/ash/accelerators/accelerator_table.cc
+++ b/ash/accelerators/accelerator_table.cc
@@ -6,7 +6,6 @@
 
 #include "ash/public/cpp/accelerators.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "base/cxx17_backports.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 
 namespace ash {
@@ -40,8 +39,7 @@
     {true, ui::VKEY_K, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
      TOGGLE_IME_MENU_BUBBLE}};
 
-const size_t kDeprecatedAcceleratorsLength =
-    base::size(kDeprecatedAccelerators);
+const size_t kDeprecatedAcceleratorsLength = std::size(kDeprecatedAccelerators);
 
 const DeprecatedAcceleratorData kDeprecatedAcceleratorsData[] = {
     // The action for the old shortcut was stopped in M92. Delete
@@ -56,7 +54,7 @@
      IDS_SHORTCUT_IME_BUBBLE_NEW, false}};
 
 const size_t kDeprecatedAcceleratorsDataLength =
-    base::size(kDeprecatedAcceleratorsData);
+    std::size(kDeprecatedAcceleratorsData);
 
 static_assert(kDeprecatedAcceleratorsLength ==
                   kDeprecatedAcceleratorsDataLength,
@@ -84,7 +82,7 @@
     {true, ui::VKEY_G, kDebugModifier, DEBUG_TOGGLE_HUD_DISPLAY},
 };
 
-const size_t kDebugAcceleratorDataLength = base::size(kDebugAcceleratorData);
+const size_t kDebugAcceleratorDataLength = std::size(kDebugAcceleratorData);
 
 const AcceleratorData kDeveloperAcceleratorData[] = {
     // Extra shortcut for debug build to control magnifier on Linux desktop.
@@ -121,7 +119,7 @@
 };
 
 const size_t kDeveloperAcceleratorDataLength =
-    base::size(kDeveloperAcceleratorData);
+    std::size(kDeveloperAcceleratorData);
 
 const AcceleratorAction kPreferredActions[] = {
     // Window cycling accelerators.
@@ -129,7 +127,7 @@
     CYCLE_FORWARD_MRU,   // Alt+Tab
 };
 
-const size_t kPreferredActionsLength = base::size(kPreferredActions);
+const size_t kPreferredActionsLength = std::size(kPreferredActions);
 
 const AcceleratorAction kReservedActions[] = {
     POWER_PRESSED,
@@ -137,7 +135,7 @@
     SUSPEND,
 };
 
-const size_t kReservedActionsLength = base::size(kReservedActions);
+const size_t kReservedActionsLength = std::size(kReservedActions);
 
 const AcceleratorAction kActionsAllowedAtLoginOrLockScreen[] = {
     BRIGHTNESS_DOWN,
@@ -197,7 +195,7 @@
 };
 
 const size_t kActionsAllowedAtLoginOrLockScreenLength =
-    base::size(kActionsAllowedAtLoginOrLockScreen);
+    std::size(kActionsAllowedAtLoginOrLockScreen);
 
 const AcceleratorAction kActionsAllowedAtLockScreen[] = {
     EXIT,
@@ -205,14 +203,14 @@
 };
 
 const size_t kActionsAllowedAtLockScreenLength =
-    base::size(kActionsAllowedAtLockScreen);
+    std::size(kActionsAllowedAtLockScreen);
 
 const AcceleratorAction kActionsAllowedAtPowerMenu[] = {
     BRIGHTNESS_DOWN, BRIGHTNESS_UP, VOLUME_DOWN, VOLUME_UP, VOLUME_MUTE,
 };
 
 const size_t kActionsAllowedAtPowerMenuLength =
-    base::size(kActionsAllowedAtPowerMenu);
+    std::size(kActionsAllowedAtPowerMenu);
 
 const AcceleratorAction kActionsAllowedAtModalWindow[] = {
     BRIGHTNESS_DOWN,
@@ -272,7 +270,7 @@
 };
 
 const size_t kActionsAllowedAtModalWindowLength =
-    base::size(kActionsAllowedAtModalWindow);
+    std::size(kActionsAllowedAtModalWindow);
 
 const AcceleratorAction kRepeatableActions[] = {
     BRIGHTNESS_DOWN,
@@ -292,7 +290,7 @@
     VOLUME_UP,
 };
 
-const size_t kRepeatableActionsLength = base::size(kRepeatableActions);
+const size_t kRepeatableActionsLength = std::size(kRepeatableActions);
 
 const AcceleratorAction kActionsAllowedInAppModeOrPinnedMode[] = {
     BRIGHTNESS_DOWN,
@@ -347,7 +345,7 @@
 };
 
 const size_t kActionsAllowedInAppModeOrPinnedModeLength =
-    base::size(kActionsAllowedInAppModeOrPinnedMode);
+    std::size(kActionsAllowedInAppModeOrPinnedMode);
 
 const AcceleratorAction kActionsAllowedInPinnedMode[] = {
     LOCK_SCREEN,
@@ -359,14 +357,14 @@
 };
 
 const size_t kActionsAllowedInPinnedModeLength =
-    base::size(kActionsAllowedInPinnedMode);
+    std::size(kActionsAllowedInPinnedMode);
 
 const AcceleratorAction kActionsAllowedInAppMode[] = {
     FOCUS_SHELF,
 };
 
 const size_t kActionsAllowedInAppModeLength =
-    base::size(kActionsAllowedInAppMode);
+    std::size(kActionsAllowedInAppMode);
 
 const AcceleratorAction kActionsNeedingWindow[] = {
     // clang-format off
@@ -384,7 +382,7 @@
     // clang-format on
 };
 
-const size_t kActionsNeedingWindowLength = base::size(kActionsNeedingWindow);
+const size_t kActionsNeedingWindowLength = std::size(kActionsNeedingWindow);
 
 const AcceleratorAction kActionsKeepingMenuOpen[] = {
     BRIGHTNESS_DOWN,
@@ -435,7 +433,6 @@
     VOLUME_UP,
 };
 
-const size_t kActionsKeepingMenuOpenLength =
-    base::size(kActionsKeepingMenuOpen);
+const size_t kActionsKeepingMenuOpenLength = std::size(kActionsKeepingMenuOpen);
 
 }  // namespace ash
diff --git a/ash/accelerometer/accelerometer_file_reader.cc b/ash/accelerometer/accelerometer_file_reader.cc
index f277ad1e..a7059342 100644
--- a/ash/accelerometer/accelerometer_file_reader.cc
+++ b/ash/accelerometer/accelerometer_file_reader.cc
@@ -15,7 +15,6 @@
 #include "ash/shell.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
@@ -417,12 +416,12 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   size_t config_index = 0;
-  for (; config_index < base::size(kLocationStrings); ++config_index) {
+  for (; config_index < std::size(kLocationStrings); ++config_index) {
     if (location == kLocationStrings[config_index])
       break;
   }
 
-  if (config_index >= base::size(kLocationStrings)) {
+  if (config_index >= std::size(kLocationStrings)) {
     LOG(ERROR) << "Unrecognized location: " << location << " for device "
                << name.MaybeAsASCII() << "\n";
     return false;
@@ -432,7 +431,7 @@
   if (!ReadFileToDouble(iio_path.Append(kAccelerometerScaleFileName), &scale))
     return false;
 
-  const int kNumberAxes = base::size(kAccelerometerAxes);
+  const int kNumberAxes = std::size(kAccelerometerAxes);
   for (size_t i = 0; i < kNumberAxes; ++i) {
     std::string accelerometer_index_path = base::StringPrintf(
         kAccelerometerScanIndexPathFormatString, kAccelerometerAxes[i]);
@@ -468,7 +467,7 @@
       base::FilePath(kAccelerometerDevicePath).Append(name.BaseName());
   // Read configuration of each accelerometer axis from each accelerometer from
   // /sys/bus/iio/devices/iio:deviceX/.
-  for (size_t i = 0; i < base::size(kLocationStrings); ++i) {
+  for (size_t i = 0; i < std::size(kLocationStrings); ++i) {
     configuration_.has[i] = false;
     // Read scale of accelerometer.
     std::string accelerometer_scale_path =
@@ -486,7 +485,7 @@
     }
 
     configuration_.has[i] = true;
-    for (size_t j = 0; j < base::size(kLegacyAccelerometerAxes); ++j) {
+    for (size_t j = 0; j < std::size(kLegacyAccelerometerAxes); ++j) {
       configuration_.scale[i][j] = base::kMeanGravityFloat / scale_divisor;
       std::string accelerometer_index_path =
           base::StringPrintf(kLegacyAccelerometerScanIndexPathFormatString,
diff --git a/ash/accessibility/chromevox/touch_exploration_controller_unittest.cc b/ash/accessibility/chromevox/touch_exploration_controller_unittest.cc
index f7682544..dc09fad04 100644
--- a/ash/accessibility/chromevox/touch_exploration_controller_unittest.cc
+++ b/ash/accessibility/chromevox/touch_exploration_controller_unittest.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "ash/accessibility/chromevox/mock_touch_exploration_controller_delegate.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/test/simple_test_tick_clock.h"
 #include "base/time/time.h"
@@ -1154,7 +1153,7 @@
   // detector test, since it seems to be about the right amount to get a swipe.
   const int kSteps = 15;
 
-  for (size_t i = 0; i < base::size(gestures_to_test); ++i) {
+  for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
     const float distance = 2 * gesture_detector_config_.touch_slop + 1;
     int move_x = gestures_to_test[i].move_x * distance;
     int move_y = gestures_to_test[i].move_y * distance;
@@ -1215,7 +1214,7 @@
   // detector test, since it seems to be about the right amount to get a swipe.
   const int kSteps = 15;
 
-  for (size_t i = 0; i < base::size(gestures_to_test); ++i) {
+  for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
     const float distance = 2 * gesture_detector_config_.touch_slop + 1;
     int move_x = gestures_to_test[i].move_x * distance;
     int move_y = gestures_to_test[i].move_y * distance;
diff --git a/ash/app_list/app_list_bubble_presenter_unittest.cc b/ash/app_list/app_list_bubble_presenter_unittest.cc
index 1de6e19..fbd04ac3 100644
--- a/ash/app_list/app_list_bubble_presenter_unittest.cc
+++ b/ash/app_list/app_list_bubble_presenter_unittest.cc
@@ -204,6 +204,25 @@
   EXPECT_EQ(1u, NumberOfWidgetsInAppListContainer(GetPrimaryDisplay().id()));
 }
 
+TEST_F(AppListBubblePresenterTest, ToggleByFocusingWindowOnSecondaryDisplay) {
+  UpdateDisplay("1600x1200,1366x768");
+
+  std::unique_ptr<views::Widget> primary_display_widget = CreateTestWidget();
+  std::unique_ptr<views::Widget> secondary_display_widget = CreateTestWidget();
+  secondary_display_widget->SetBounds(
+      gfx::Rect(gfx::Point(1600, 0), gfx::Size(1366, 768)));
+
+  AppListBubblePresenter* presenter = GetBubblePresenter();
+  presenter->Show(GetPrimaryDisplay().id());
+
+  // Activate the window in secondary display, and verify the app list bubble
+  // gets hidden.
+  secondary_display_widget->Activate();
+
+  EXPECT_FALSE(presenter->IsShowing());
+  EXPECT_TRUE(secondary_display_widget->IsActive());
+}
+
 TEST_F(AppListBubblePresenterTest, DismissHidesWidget) {
   AppListBubblePresenter* presenter = GetBubblePresenter();
   presenter->Show(GetPrimaryDisplay().id());
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc
index 51053f4..f655cd1 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -66,10 +66,14 @@
 
 // The horizontal interior margin for the apps page container - i.e. the margin
 // between the apps page bounds and the page content.
-constexpr int kHorizontalInteriorMargin = 20;
+constexpr int kHorizontalInteriorMargin = 16;
+
+// Insets for the continue section. These insets are required to make the
+// suggestion icons visually align with the icons in the apps grid.
+constexpr gfx::Insets kContinueSectionInsets(0, 4);
 
 // Insets for the separator between the continue section and apps.
-constexpr gfx::Insets kSeparatorInsets(0, 12);
+constexpr gfx::Insets kSeparatorInsets(0, 16);
 
 // A slide animation's tween type.
 constexpr gfx::Tween::Type kSlideAnimationTweenType =
@@ -145,6 +149,8 @@
   continue_section_ =
       scroll_contents->AddChildView(std::make_unique<ContinueSectionView>(
           view_delegate, kContinueColumnCount, /*tablet_mode=*/false));
+  continue_section_->SetBorder(
+      views::CreateEmptyBorder(kContinueSectionInsets));
   continue_section_->SetNudgeController(app_list_nudge_controller_.get());
 
   // Observe changes in continue section visibility, to keep separator
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc
index 8115c60..17db8e3 100644
--- a/ash/app_list/views/app_list_bubble_view.cc
+++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -619,18 +619,8 @@
   if (folder_view_->IsAnimationRunning())
     return;
 
-  showing_folder_ = false;
-  Layout();
-  folder_background_view_->SetVisible(false);
-  apps_page_->scrollable_apps_grid_view()->ResetForShowApps();
-  folder_view_->ResetItemsGridForClose();
-  if (folder_item_view) {
-    folder_view_->ScheduleShowHideAnimation(/*show=*/false,
-                                            /*hide_for_reparent=*/false);
-  } else {
-    folder_view_->HideViewImmediately();
-  }
-  DisableFocusForShowingActiveFolder(false);
+  HideFolderView(/*animate=*/folder_item_view, /*hide_for_reparent=*/false);
+
   if (folder_item_view && select_folder)
     folder_item_view->RequestFocus();
   else
@@ -643,12 +633,7 @@
   if (folder_view_->IsAnimationRunning())
     return;
 
-  showing_folder_ = false;
-  Layout();
-  folder_background_view_->SetVisible(false);
-  folder_view_->ScheduleShowHideAnimation(/*show=*/false,
-                                          /*hide_for_reparent=*/true);
-  DisableFocusForShowingActiveFolder(false);
+  HideFolderView(/*animate=*/true, /*hide_for_reparent=*/true);
 }
 
 void AppListBubbleView::ReparentDragEnded() {
@@ -680,8 +665,8 @@
 
   search_box_view_->ClearSearch();
 
-  // Hide any open folder by showing the apps page.
-  ShowApps(/*folder_item_view=*/nullptr, /*select_folder=*/false);
+  // Hide any open folder.
+  HideFolderView(/*animate=*/false, /*hide_for_reparent=*/false);
 
   // Reset pages to default visibility.
   current_page_ = AppListBubblePage::kNone;
@@ -693,4 +678,20 @@
     std::move(on_hide_animation_ended_).Run();
 }
 
+void AppListBubbleView::HideFolderView(bool animate, bool hide_for_reparent) {
+  showing_folder_ = false;
+  Layout();
+  folder_background_view_->SetVisible(false);
+  if (!hide_for_reparent) {
+    apps_page_->scrollable_apps_grid_view()->ResetForShowApps();
+    folder_view_->ResetItemsGridForClose();
+  }
+  if (animate) {
+    folder_view_->ScheduleShowHideAnimation(/*show=*/false, hide_for_reparent);
+  } else {
+    folder_view_->HideViewImmediately();
+  }
+  DisableFocusForShowingActiveFolder(false);
+}
+
 }  // namespace ash
diff --git a/ash/app_list/views/app_list_bubble_view.h b/ash/app_list/views/app_list_bubble_view.h
index 903d744..8fce414 100644
--- a/ash/app_list/views/app_list_bubble_view.h
+++ b/ash/app_list/views/app_list_bubble_view.h
@@ -137,6 +137,14 @@
   // Called when the hide animation ends or aborts.
   void OnHideAnimationEnded(const gfx::Rect& layer_bounds);
 
+  // Hides the folder view if it's currently shown. It can be called if the
+  // folder is not currently shown.
+  // `animate` - Whether the folder view should be hidden using an animation.
+  // `hide_for_reparent` - Whether the folder view is being hidden to initiate
+  // item reparent user action (e.g. when dragging folder item out of the folder
+  // view bounds).
+  void HideFolderView(bool animate, bool hide_for_reparent);
+
   AppListViewDelegate* const view_delegate_;
 
   std::unique_ptr<AppListA11yAnnouncer> a11y_announcer_;
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc
index 176b26ed..d5558fcb 100644
--- a/ash/app_list/views/app_list_view_unittest.cc
+++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -3160,7 +3160,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        RegularLandscapeScreenAtMinPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/4, /*tile_size=*/120, /*tile_margin=*/8);
+      /*row_count=*/4, /*tile_height=*/120, /*tile_margins=*/8);
   EXPECT_EQ(680, window_height);
   const gfx::Size window_size = gfx::Size(800, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3195,7 +3195,7 @@
        RegularLandscapeScreenWithRemovedRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/4, /*tile_size=*/120, /*tile_margin=*/8) -
+          /*row_count=*/4, /*tile_height=*/120, /*tile_margins=*/8) -
       4;
   EXPECT_EQ(676, window_height);
   const gfx::Size window_size = gfx::Size(800, window_height);
@@ -3230,7 +3230,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        RegularLandscapeScreenAtMaxPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/4, /*tile_size=*/120, /*tile_margin=*/96);
+      /*row_count=*/4, /*tile_height=*/120, /*tile_margins=*/96);
   EXPECT_EQ(944, window_height);
   const gfx::Size window_size = gfx::Size(1000, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3265,7 +3265,7 @@
        RegularLandscapeScreenWithAddedRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/4, /*tile_size=*/120, /*tile_margin=*/96) +
+          /*row_count=*/4, /*tile_height=*/120, /*tile_margins=*/96) +
       6;
   EXPECT_EQ(950, window_height);
   const gfx::Size window_size = gfx::Size(1000, window_height);
@@ -3330,7 +3330,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        RegularPortraitScreenAtMinPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/5, /*tile_size=*/120, /*tile_margin=*/8);
+      /*row_count=*/5, /*tile_height=*/120, /*tile_margins=*/8);
   EXPECT_EQ(808, window_height);
   const gfx::Size window_size = gfx::Size(700, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3365,7 +3365,7 @@
        RegularPortraitScreenWithRemovedRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/5, /*tile_size=*/120, /*tile_margin=*/8) -
+          /*row_count=*/5, /*tile_height=*/120, /*tile_margins=*/8) -
       8;
   EXPECT_EQ(800, window_height);
   const gfx::Size window_size = gfx::Size(700, window_height);
@@ -3400,7 +3400,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        RegularPortraitScreenAtMaxPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/5, /*tile_size=*/120, /*tile_margin=*/96);
+      /*row_count=*/5, /*tile_height=*/120, /*tile_margins=*/96);
   EXPECT_EQ(1160, window_height);
   const gfx::Size window_size = gfx::Size(1200, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3434,7 +3434,7 @@
        RegularPortraitScreenWithExtraRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/5, /*tile_size=*/120, /*tile_margin=*/96) +
+          /*row_count=*/5, /*tile_height=*/120, /*tile_margins=*/96) +
       4;
   EXPECT_EQ(1164, window_height);
   const gfx::Size window_size = gfx::Size(1200, window_height);
@@ -3473,7 +3473,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3498,7 +3498,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        DenseLandscapeScreenAtMinPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/4, /*tile_size=*/88, /*tile_margin=*/8);
+      /*row_count=*/4, /*tile_height=*/88, /*tile_margins=*/8);
   EXPECT_EQ(552, window_height);
   const gfx::Size window_size = gfx::Size(800, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3507,7 +3507,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3533,7 +3533,7 @@
        DenseLandscapeScreenWithRemovedRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/4, /*tile_size=*/88, /*tile_margin=*/8) -
+          /*row_count=*/4, /*tile_height=*/88, /*tile_margins=*/8) -
       4;
   EXPECT_EQ(548, window_height);
   const gfx::Size window_size = gfx::Size(800, window_height);
@@ -3543,7 +3543,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3573,7 +3573,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3598,7 +3598,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        DensePortraitScreenAtMinPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/5, /*tile_size=*/88, /*tile_margin=*/8);
+      /*row_count=*/5, /*tile_height=*/88, /*tile_margins=*/8);
   EXPECT_EQ(648, window_height);
   const gfx::Size window_size = gfx::Size(600, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3607,7 +3607,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3633,17 +3633,17 @@
        DensePortraitScreenWithRemovedRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/5, /*tile_size=*/88, /*tile_margin=*/8) -
+          /*row_count=*/5, /*tile_height=*/88, /*tile_margins=*/8) -
       8;
   EXPECT_EQ(640, window_height);
-  const gfx::Size window_size = gfx::Size(500, window_height);
+  const gfx::Size window_size = gfx::Size(540, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
   InitializeAppList();
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3668,7 +3668,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        DensePortraitScreenAtMaxPreferredVerticalMargin) {
   const int window_height = GetExpectedProductivityLauncherAppsContainerHeight(
-      /*row_count=*/5, /*tile_size=*/88, /*tile_margin=*/96);
+      /*row_count=*/5, /*tile_height=*/88, /*tile_margins=*/96);
   EXPECT_EQ(1000, window_height);
   const gfx::Size window_size = gfx::Size(600, window_height);
   GetContext()->SetBounds(gfx::Rect(window_size));
@@ -3677,7 +3677,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3703,7 +3703,7 @@
        DensePortraitScreenWithExtraRows) {
   const int window_height =
       GetExpectedProductivityLauncherAppsContainerHeight(
-          /*row_count=*/5, /*tile_size=*/88, /*tile_margin=*/96) +
+          /*row_count=*/5, /*tile_height=*/88, /*tile_margins=*/96) +
       4;
   EXPECT_EQ(1004, window_height);
   const gfx::Size window_size = gfx::Size(600, window_height);
@@ -3713,7 +3713,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
 
   {
     SCOPED_TRACE("Only apps grid");
@@ -3739,14 +3739,14 @@
        DenseAppsGridPaddingScaledDownToMakeRoomForPageSwitcher) {
   // Select window width so using non-zero horizontal padding would result in
   // lack of space for the page switcher.
-  const gfx::Size window_size = gfx::Size(472, 800);
+  const gfx::Size window_size = gfx::Size(512, 800);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
   InitializeAppList();
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
   EXPECT_EQ(5, apps_grid_view()->GetRowsForTesting());
   VerifyAppsContainerLayoutForProductivityLauncher(
       window_size, /*row_count=*/5, expected_horizontal_margin,
@@ -3774,7 +3774,7 @@
 TEST_F(ProductivityLauncherAppListViewLayoutTest,
        DenseAppsGridWithMaxHorizontalItemMargins) {
   // Select window width that results in apps grid layout with max allowed
-  // horizontal margin (128): 2 * 56 (min horizontal margin) + 4 * 128 + 5 * 72
+  // horizontal margin (128): 2 * 56 (min horizontal margin) + 4 * 128 + 5 * 80
   const gfx::Size window_size = gfx::Size(984, 600);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
@@ -3782,7 +3782,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
   EXPECT_EQ(4, apps_grid_view()->GetRowsForTesting());
   VerifyAppsContainerLayoutForProductivityLauncher(
       window_size, /*row_count=*/4, expected_horizontal_margin,
@@ -3793,14 +3793,14 @@
        DenseAppsGridHorizontalItemMarginsBounded) {
   // Select window width that results in apps grid layout with max allowed
   // horizontal margin (128), i.e. larger than
-  // 2 * 56 (min horizontal margin) + 4 * 128 * 5 * 72
-  const gfx::Size window_size = gfx::Size(1000, 600);
+  // 2 * 56 (min horizontal margin) + 4 * 128 + 5 * 80
+  const gfx::Size window_size = gfx::Size(1040, 600);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
   InitializeAppList();
 
   const int expected_horizontal_margin = 64;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
   EXPECT_EQ(4, apps_grid_view()->GetRowsForTesting());
   VerifyAppsContainerLayoutForProductivityLauncher(
       window_size, /*row_count=*/4, expected_horizontal_margin,
@@ -3811,7 +3811,7 @@
        RegularAppsGridWithMaxHorizontalItemMargins) {
   // Select window width that results in apps grid layout with max allowed
   // horizontal margin (128):
-  // 2 * 56 (min horizontal margin) + 4 * 128 * 5 * 96
+  // 2 * 56 (min horizontal margin) + 4 * 128 + 5 * 96
   const gfx::Size window_size = gfx::Size(1104, 1200);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
@@ -3830,7 +3830,7 @@
        RegularAppsGridHorizontalItemMarginsBounded) {
   // Select window width that results in apps grid layout with max allowed
   // horizontal margin (128), i.e. larger than
-  // 2 * 56 (min horizontal margin) + 4 * 128 * 5 * 96
+  // 2 * 56 (min horizontal margin) + 4 * 128 + 5 * 96
   const gfx::Size window_size = gfx::Size(1116, 1200);
   GetContext()->SetBounds(gfx::Rect(window_size));
 
@@ -3852,7 +3852,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
   EXPECT_EQ(5, apps_grid_view()->GetRowsForTesting());
   VerifyAppsContainerLayoutForProductivityLauncher(
       window_size, /*row_count=*/5, expected_horizontal_margin,
@@ -3880,7 +3880,7 @@
 
   const int expected_horizontal_margin =
       kMinProductivityLauncherGridHorizontalMargin;
-  const gfx::Size expected_item_size(72, 88);
+  const gfx::Size expected_item_size(80, 88);
   EXPECT_EQ(5, apps_grid_view()->GetRowsForTesting());
   VerifyAppsContainerLayoutForProductivityLauncher(
       window_size, /*row_count=*/4, expected_horizontal_margin,
diff --git a/ash/app_list/views/pulsing_block_view.cc b/ash/app_list/views/pulsing_block_view.cc
index 3a4350b3..6dba650 100644
--- a/ash/app_list/views/pulsing_block_view.cc
+++ b/ash/app_list/views/pulsing_block_view.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/rand_util.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/compositor/layer.h"
@@ -34,12 +33,12 @@
 
 void SchedulePulsingAnimation(ui::Layer* layer) {
   DCHECK(layer);
-  DCHECK_EQ(base::size(kAnimationOpacity), base::size(kAnimationScale));
+  DCHECK_EQ(std::size(kAnimationOpacity), std::size(kAnimationScale));
 
   const gfx::Rect local_bounds(layer->bounds().size());
   views::AnimationBuilder builder;
   views::AnimationSequenceBlock block = builder.Repeatedly();
-  for (size_t i = 0; i < base::size(kAnimationOpacity); ++i) {
+  for (size_t i = 0; i < std::size(kAnimationOpacity); ++i) {
     block = block.SetDuration(base::Milliseconds(kAnimationDurationInMs))
                 .SetOpacity(layer, kAnimationOpacity[i])
                 .SetTransform(layer,
@@ -58,7 +57,7 @@
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
 
-  const int max_delay = kAnimationDurationInMs * base::size(kAnimationOpacity);
+  const int max_delay = kAnimationDurationInMs * std::size(kAnimationOpacity);
   const int delay = start_delay ? base::RandInt(0, max_delay) : 0;
   start_delay_timer_.Start(FROM_HERE, base::Milliseconds(delay), this,
                            &PulsingBlockView::OnStartDelayTimer);
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc
index 78fd2cba..b46a3de 100644
--- a/ash/app_list/views/search_result_view.cc
+++ b/ash/app_list/views/search_result_view.cc
@@ -77,8 +77,12 @@
 
 constexpr int kSearchRatingStarPadding = 4;
 constexpr int kSearchRatingStarSize = 16;
-constexpr gfx::Insets kAnswerCardBorder(12, 12, 12, 12);
-constexpr gfx::Insets kBigTitleBorder(0, 14, 0, 12);
+constexpr int kAnswerCardBorderMargin = 12;
+constexpr gfx::Insets kAnswerCardBorder(kAnswerCardBorderMargin,
+                                        kAnswerCardBorderMargin,
+                                        kAnswerCardBorderMargin,
+                                        kAnswerCardBorderMargin);
+constexpr gfx::Insets kBigTitleBorder(0, 0, 0, kAnswerCardBorderMargin);
 
 views::ImageView* SetupChildImageView(views::FlexLayoutView* parent) {
   views::ImageView* image_view =
@@ -730,7 +734,12 @@
   actions_view()->SetBoundsRect(actions_bounds);
 
   gfx::Rect text_bounds(rect);
-  text_bounds.set_x(kPreferredIconViewWidth);
+  // Text bounds need to be shifted over by kAnswerCardBorderMargin for answer
+  // card views to make room for the kAnswerCardBorder.
+  text_bounds.set_x(kPreferredIconViewWidth +
+                    (view_type_ == SearchResultViewType::kAnswerCard
+                         ? kAnswerCardBorderMargin
+                         : 0));
   if (actions_view()->GetVisible()) {
     text_bounds.set_width(
         rect.width() - kPreferredIconViewWidth - kTextTrailPadding -
diff --git a/ash/assistant/ui/main_stage/assistant_onboarding_suggestion_view.cc b/ash/assistant/ui/main_stage/assistant_onboarding_suggestion_view.cc
index eb9494da..929b80b 100644
--- a/ash/assistant/ui/main_stage/assistant_onboarding_suggestion_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_onboarding_suggestion_view.cc
@@ -11,7 +11,6 @@
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/style/color_provider.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/services/libassistant/public/cpp/assistant_suggestion.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -69,7 +68,7 @@
        SkColorSetA(gfx::kGoogleBlue600, 0x19)}};
 
   DCHECK_GE(index, 0);
-  DCHECK_LT(index, static_cast<int>(base::size(kBackgroundColors)));
+  DCHECK_LT(index, static_cast<int>(std::size(kBackgroundColors)));
 
   if (features::IsDarkLightModeEnabled()) {
     return ColorProvider::Get()->IsDarkModeEnabled()
@@ -91,7 +90,7 @@
       {gfx::kGoogleBlue800, gfx::kGoogleBlue200, gfx::kGoogleBlue800}};
 
   DCHECK_GE(index, 0);
-  DCHECK_LT(index, static_cast<int>(base::size(kForegroundColors)));
+  DCHECK_LT(index, static_cast<int>(std::size(kForegroundColors)));
 
   if (features::IsDarkLightModeEnabled()) {
     return ColorProvider::Get()->IsDarkModeEnabled()
diff --git a/ash/capture_mode/capture_mode_camera_controller.cc b/ash/capture_mode/capture_mode_camera_controller.cc
index 4a649da..b8a1dec 100644
--- a/ash/capture_mode/capture_mode_camera_controller.cc
+++ b/ash/capture_mode/capture_mode_camera_controller.cc
@@ -78,6 +78,8 @@
         found_info.camera_id.model_id_or_display_name() !=
             model_id_or_display_name ||
         found_info.camera_id.number() != cam_number) {
+      // It is unexpected that the supported formats of the same camera device
+      // change, so we ignore comparing them here.
       return true;
     }
   }
@@ -145,10 +147,18 @@
 
 CameraInfo::CameraInfo(CameraId camera_id,
                        std::string device_id,
-                       std::string display_name)
+                       std::string display_name,
+                       const media::VideoCaptureFormats& supported_formats)
     : camera_id(std::move(camera_id)),
       device_id(std::move(device_id)),
-      display_name(std::move(display_name)) {}
+      display_name(std::move(display_name)),
+      supported_formats(supported_formats) {}
+
+CameraInfo::CameraInfo(CameraInfo&&) = default;
+
+CameraInfo& CameraInfo::operator=(CameraInfo&&) = default;
+
+CameraInfo::~CameraInfo() = default;
 
 // -----------------------------------------------------------------------------
 // CaptureModeCameraController:
@@ -183,6 +193,8 @@
 
   selected_camera_ = std::move(camera_id);
   camera_reconnect_timer_.Stop();
+  camera_preview_widget_.reset();
+  camera_preview_view_ = nullptr;
 
   for (auto& observer : observers_)
     observer.OnSelectedCameraChanged(selected_camera_);
@@ -292,7 +304,7 @@
         GetNextCameraNumber(model_id_or_display_name, &cam_models_map);
     available_cameras_.emplace_back(
         CameraId(model_id_or_display_name, cam_number), descriptor.device_id,
-        descriptor.display_name());
+        descriptor.display_name(), device.supported_formats);
   }
 
   for (auto& observer : observers_)
@@ -364,18 +376,26 @@
   switch (camera_preview_snap_position_) {
     case CameraPreviewSnapPosition::kTopLeft:
       origin = confine_bounds.origin();
+      origin.Offset(capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                    capture_mode::kSpaceBetweenCameraPreviewAndEdges);
       break;
     case CameraPreviewSnapPosition::kBottomLeft:
-      origin = gfx::Point(confine_bounds.x(),
-                          confine_bounds.bottom() - preview_size.height());
+      origin = gfx::Point(
+          confine_bounds.x() + capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+          confine_bounds.bottom() - preview_size.height() -
+              capture_mode::kSpaceBetweenCameraPreviewAndEdges);
       break;
     case CameraPreviewSnapPosition::kBottomRight:
-      origin = gfx::Point(confine_bounds.right() - preview_size.width(),
-                          confine_bounds.bottom() - preview_size.height());
+      origin = gfx::Point(confine_bounds.right() - preview_size.width() -
+                              capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                          confine_bounds.bottom() - preview_size.height() -
+                              capture_mode::kSpaceBetweenCameraPreviewAndEdges);
       break;
     case CameraPreviewSnapPosition::kTopRight:
-      origin = gfx::Point(confine_bounds.right() - preview_size.width(),
-                          confine_bounds.y());
+      origin = gfx::Point(confine_bounds.right() - preview_size.width() -
+                              capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                          confine_bounds.y() +
+                              capture_mode::kSpaceBetweenCameraPreviewAndEdges);
       break;
   }
   return gfx::Rect(origin, preview_size);
diff --git a/ash/capture_mode/capture_mode_camera_controller.h b/ash/capture_mode/capture_mode_camera_controller.h
index 321fdeb2..311125f 100644
--- a/ash/capture_mode/capture_mode_camera_controller.h
+++ b/ash/capture_mode/capture_mode_camera_controller.h
@@ -17,6 +17,7 @@
 #include "base/system/system_monitor.h"
 #include "base/timer/timer.h"
 #include "media/capture/video/video_capture_device_info.h"
+#include "media/capture/video_capture_types.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/video_capture/public/mojom/video_source_provider.mojom.h"
 #include "ui/views/widget/unique_widget_ptr.h"
@@ -72,9 +73,11 @@
 struct CameraInfo {
   CameraInfo(CameraId camera_id,
              std::string device_id,
-             std::string display_name);
-  CameraInfo(CameraInfo&&) = default;
-  CameraInfo& operator=(CameraInfo&&) = default;
+             std::string display_name,
+             const media::VideoCaptureFormats& supported_formats);
+  CameraInfo(CameraInfo&&);
+  CameraInfo& operator=(CameraInfo&&);
+  ~CameraInfo();
 
   // The ID used to identify the camera device internally to the capture mode
   // code, which should be more stable than the below `device_id` which may
@@ -91,6 +94,11 @@
   // The name of the camera device as shown to the end user (e.g. "Integrated
   // Webcam").
   std::string display_name;
+
+  // A list of supported capture formats by this camera. This list is sorted
+  // (See `media::VideoCaptureSystemImpl::DevicesInfoReady()`) by the frame size
+  // area, then by frame width, then by the *largest* frame rate.
+  media::VideoCaptureFormats supported_formats;
 };
 
 using CameraInfoList = std::vector<CameraInfo>;
diff --git a/ash/capture_mode/capture_mode_camera_unittests.cc b/ash/capture_mode/capture_mode_camera_unittests.cc
index 213f46db..5a0be2b 100644
--- a/ash/capture_mode/capture_mode_camera_unittests.cc
+++ b/ash/capture_mode/capture_mode_camera_unittests.cc
@@ -4,6 +4,7 @@
 
 #include "ash/capture_mode/capture_mode_bar_view.h"
 #include "ash/capture_mode/capture_mode_camera_controller.h"
+#include "ash/capture_mode/capture_mode_constants.h"
 #include "ash/capture_mode/capture_mode_controller.h"
 #include "ash/capture_mode/capture_mode_menu_group.h"
 #include "ash/capture_mode/capture_mode_session.h"
@@ -168,6 +169,53 @@
                 GetEventGenerator());
   }
 
+  // Verifies that the camera preview is placed on the correct position based on
+  // current preview snap position and the given `confine_bounds_in_screen`.
+  void VerifyPreviewAlignment(const gfx::Rect& confine_bounds_in_screen) {
+    auto* camera_controller = GetCameraController();
+    const auto* preview_widget = camera_controller->camera_preview_widget();
+    DCHECK(preview_widget);
+    const gfx::Rect camera_preview_bounds =
+        preview_widget->GetWindowBoundsInScreen();
+
+    switch (camera_controller->camera_preview_snap_position()) {
+      case CameraPreviewSnapPosition::kTopLeft: {
+        gfx::Point expect_origin = confine_bounds_in_screen.origin();
+        expect_origin.Offset(capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                             capture_mode::kSpaceBetweenCameraPreviewAndEdges);
+        EXPECT_EQ(expect_origin, camera_preview_bounds.origin());
+        break;
+      }
+      case CameraPreviewSnapPosition::kBottomLeft: {
+        const gfx::Point expect_bottom_left =
+            gfx::Point(confine_bounds_in_screen.x() +
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                       confine_bounds_in_screen.bottom() -
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges);
+        EXPECT_EQ(expect_bottom_left, camera_preview_bounds.bottom_left());
+        break;
+      }
+      case CameraPreviewSnapPosition::kBottomRight: {
+        const gfx::Point expect_bottom_right =
+            gfx::Point(confine_bounds_in_screen.right() -
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                       confine_bounds_in_screen.bottom() -
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges);
+        EXPECT_EQ(expect_bottom_right, camera_preview_bounds.bottom_right());
+        break;
+      }
+      case CameraPreviewSnapPosition::kTopRight: {
+        const gfx::Point expect_top_right =
+            gfx::Point(confine_bounds_in_screen.right() -
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges,
+                       confine_bounds_in_screen.y() +
+                           capture_mode::kSpaceBetweenCameraPreviewAndEdges);
+        EXPECT_EQ(expect_top_right, camera_preview_bounds.top_right());
+        break;
+      }
+    }
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   base::SystemMonitor system_monitor_;
@@ -274,6 +322,28 @@
   EXPECT_FALSE(camera_controller->camera_preview_widget());
 }
 
+TEST_F(CaptureModeCameraTest, SelectingDifferentCameraCreatesNewPreviewWidget) {
+  AddDefaultCamera();
+  const std::string device_id = "/dev/video0";
+  const std::string display_name = "Integrated Webcam";
+  const std::string model_id = "0123:4567";
+  AddFakeCamera(device_id, display_name, model_id);
+
+  StartCaptureSession(CaptureModeSource::kFullscreen, CaptureModeType::kVideo);
+  auto* camera_controller = GetCameraController();
+  EXPECT_FALSE(camera_controller->camera_preview_widget());
+
+  camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
+  auto* current_preview_widget = camera_controller->camera_preview_widget();
+  EXPECT_TRUE(current_preview_widget);
+
+  // Selecting a different camera should result in the recreation of the preview
+  // widget.
+  camera_controller->SetSelectedCamera(CameraId(model_id, 1));
+  EXPECT_TRUE(camera_controller->camera_preview_widget());
+  EXPECT_NE(current_preview_widget, camera_controller->camera_preview_widget());
+}
+
 TEST_F(CaptureModeCameraTest, MultipleCamerasOfTheSameModel) {
   auto* camera_controller = GetCameraController();
 
@@ -656,13 +726,14 @@
   const auto* preview_widget = camera_controller->camera_preview_widget();
   EXPECT_TRUE(preview_widget);
 
-  // When snap position is `kBottomRight` and capture source is `kFullscreen`,
-  // the preview should at the bottom right corner of screen.
+  // Verifies the camera preview's alignment with `kBottomRight` snap position
+  // and `kFullscreen` capture source.
   const auto* capture_mode_session = controller->capture_mode_session();
-  const gfx::Rect screen_bounds =
-      capture_mode_session->current_root()->GetBoundsInScreen();
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_right(),
-            screen_bounds.bottom_right());
+  const gfx::Rect work_area =
+      display::Screen::GetScreen()
+          ->GetDisplayNearestWindow(capture_mode_session->current_root())
+          .work_area();
+  VerifyPreviewAlignment(work_area);
 
   // Switching to `kRegion` without capture region set, the preview widget
   // should not be shown.
@@ -670,45 +741,48 @@
   EXPECT_TRUE(controller->user_capture_region().IsEmpty());
   EXPECT_FALSE(preview_widget->IsVisible());
 
-  // The preview should be shown at the bottom right corner of the capture
-  // region when it is set.
+  // Verifies the camera preview's alignment with `kBottomRight` snap position
+  // and `kRegion` capture source.
   const gfx::Rect capture_region(10, 20, 300, 200);
   controller->SetUserCaptureRegion(capture_region, /*by_user=*/true);
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_right(),
-            capture_region.bottom_right());
+  VerifyPreviewAlignment(capture_region);
 
-  // Switching back to `kFullscreen`, the preview should be shown at the bottom
-  // right of the screen again.
+  // Verifies the camera preview's alignment after switching back to
+  // `kFullscreen.`
   controller->SetSource(CaptureModeSource::kFullscreen);
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_right(),
-            screen_bounds.bottom_right());
+  VerifyPreviewAlignment(work_area);
 
-  // Switching back to `kRegion`, the preview should be shown at the bottom
-  // right of the current capture region again.
+  // Verifies the camera preview's alignment with `kBottomLeft` snap position
+  // and `kRegion` capture source.
   controller->SetSource(CaptureModeSource::kRegion);
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_right(),
-            capture_region.bottom_right());
-
-  // Update the snap position should update the preview to the corresponding
-  // position.
   camera_controller->SetCameraPreviewSnapPosition(
       CameraPreviewSnapPosition::kBottomLeft);
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_left(),
-            capture_region.bottom_left());
+  VerifyPreviewAlignment(capture_region);
+
+  // Verifies the camera preview's alignment with `kTopLeft` snap position
+  // and `kRegion` capture source.
+  camera_controller->SetCameraPreviewSnapPosition(
+      CameraPreviewSnapPosition::kTopLeft);
+  VerifyPreviewAlignment(capture_region);
+
+  // Verifies the camera preview's alignment with `kTopRight` snap position
+  // and `kRegion` capture source.
+  camera_controller->SetCameraPreviewSnapPosition(
+      CameraPreviewSnapPosition::kTopRight);
+  VerifyPreviewAlignment(capture_region);
 
   // Set capture region to empty, the preview should be hidden again.
   controller->SetUserCaptureRegion(gfx::Rect(), /*by_user=*/true);
   EXPECT_FALSE(preview_widget->IsVisible());
 
-  // Switching to `kWindow` and start the video recording. The preview should
-  // stay at the bottom left corner of the recording window's bounds.
+  // Verifies the camera preview's alignment with `kTopRight` snap position and
+  // `kWindow` capture source.
   StartRecordingFromSource(CaptureModeSource::kWindow);
   const auto* window_being_recorded =
       controller->video_recording_watcher_for_testing()
           ->window_being_recorded();
   DCHECK(window_being_recorded);
-  EXPECT_EQ(preview_widget->GetWindowBoundsInScreen().bottom_left(),
-            window_being_recorded->GetBoundsInScreen().bottom_left());
+  VerifyPreviewAlignment(window_being_recorded->GetBoundsInScreen());
 }
 
 TEST_F(CaptureModeCameraTest, MultiDisplayCameraPreviewWidgetBounds) {
@@ -884,4 +958,32 @@
             saved_video_file.DirName());
 }
 
+// Tests that there is no crash if moving the mouse to be on the top of the
+// camera preview after capture type switching. Selected window should not be
+// changed in this process either.
+TEST_F(CaptureModeCameraTest, HoveringMouseOverCameraPreview) {
+  auto* controller =
+      StartCaptureSession(CaptureModeSource::kWindow, CaptureModeType::kVideo);
+  AddDefaultCamera();
+  auto* camera_controller = GetCameraController();
+  camera_controller->SetSelectedCamera(CameraId(kDefaultCameraModelId, 1));
+  auto* event_generator = GetEventGenerator();
+  event_generator->MoveMouseToCenterOf(window());
+  EXPECT_TRUE(camera_controller->camera_preview_widget());
+
+  // No camera preview when it is in `kImage`.
+  controller->SetType(CaptureModeType::kImage);
+  event_generator->MoveMouseToCenterOf(window());
+  EXPECT_FALSE(camera_controller->camera_preview_widget());
+
+  // The native window of camera preview widget should be ignored from the
+  // candidates of the selected window. So moving the mouse to be on top of the
+  // camera preview should not cause any crash or selected window changes.
+  controller->SetType(CaptureModeType::kVideo);
+  event_generator->MoveMouseTo(camera_controller->camera_preview_widget()
+                                   ->GetWindowBoundsInScreen()
+                                   .CenterPoint());
+  EXPECT_EQ(window(), controller->capture_mode_session()->GetSelectedWindow());
+}
+
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_constants.h b/ash/capture_mode/capture_mode_constants.h
index 9ad8e4c8..a1fa2e5 100644
--- a/ash/capture_mode/capture_mode_constants.h
+++ b/ash/capture_mode/capture_mode_constants.h
@@ -37,6 +37,10 @@
 
 constexpr gfx::Size kCameraPreviewSize{96, 96};
 
+// The space between the camera preview and edges of the bounds that will be
+// recorded.
+constexpr int kSpaceBetweenCameraPreviewAndEdges = 16;
+
 }  // namespace capture_mode
 
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc
index eec9739..c9239eb 100644
--- a/ash/capture_mode/capture_mode_session.cc
+++ b/ash/capture_mode/capture_mode_session.cc
@@ -847,7 +847,9 @@
     case CaptureModeSource::kFullscreen: {
       auto* parent = GetCameraPreviewParentWindow();
       DCHECK(parent);
-      return parent->GetBoundsInScreen();
+      return display::Screen::GetScreen()
+          ->GetDisplayNearestWindow(parent)
+          .work_area();
     }
     case CaptureModeSource::kWindow: {
       aura::Window* selected_window = GetSelectedWindow();
@@ -1001,8 +1003,9 @@
 void CaptureModeSession::OnDisplayMetricsChanged(
     const display::Display& display,
     uint32_t metrics) {
-  if (!(metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION |
-                   DISPLAY_METRIC_DEVICE_SCALE_FACTOR))) {
+  if (!(metrics &
+        (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION |
+         DISPLAY_METRIC_DEVICE_SCALE_FACTOR | DISPLAY_METRIC_WORK_AREA))) {
     return;
   }
 
@@ -1512,6 +1515,13 @@
           if (capture_label_widget_)
             ignore_windows.insert(capture_label_widget_->GetNativeWindow());
 
+          auto* camera_controller =
+              CaptureModeController::Get()->camera_controller();
+          if (camera_controller && camera_controller->camera_preview_widget()) {
+            ignore_windows.insert(
+                camera_controller->camera_preview_widget()->GetNativeWindow());
+          }
+
           capture_window_observer_->UpdateSelectedWindowAtPosition(
               screen_location, ignore_windows);
         }
diff --git a/ash/capture_mode/video_recording_watcher.cc b/ash/capture_mode/video_recording_watcher.cc
index c4c00db1..5c8d04c 100644
--- a/ash/capture_mode/video_recording_watcher.cc
+++ b/ash/capture_mode/video_recording_watcher.cc
@@ -291,7 +291,9 @@
   DCHECK(window_being_recorded_);
   switch (recording_source_) {
     case CaptureModeSource::kFullscreen:
-      return window_being_recorded_->GetBoundsInScreen();
+      return display::Screen::GetScreen()
+          ->GetDisplayNearestWindow(window_being_recorded_)
+          .work_area();
     case CaptureModeSource::kRegion: {
       gfx::Rect capture_region = partial_region_bounds_;
       wm::ConvertRectToScreen(current_root_, &capture_region);
@@ -437,8 +439,9 @@
   if (is_in_projector_mode_ && (metrics & DISPLAY_METRIC_WORK_AREA))
     recording_overlay_controller_->SetBounds(GetOverlayWidgetBounds());
 
-  if (!(metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION |
-                   DISPLAY_METRIC_DEVICE_SCALE_FACTOR))) {
+  if (!(metrics &
+        (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION |
+         DISPLAY_METRIC_DEVICE_SCALE_FACTOR | DISPLAY_METRIC_WORK_AREA))) {
     return;
   }
 
diff --git a/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc b/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc
index 90273ad..c2f99a6 100644
--- a/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc
+++ b/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc
@@ -7,7 +7,6 @@
 #include <string>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "device/bluetooth/public/cpp/bluetooth_uuid.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -123,7 +122,7 @@
       converted_service = advertisement->service_data();
   EXPECT_EQ(converted_service->size(), 1U);
   EXPECT_EQ(converted_service->begin()->first, kUuid16Str);
-  for (size_t i = 0; i < base::size(kServiceData); i++) {
+  for (size_t i = 0; i < std::size(kServiceData); i++) {
     EXPECT_EQ(kServiceData[i], converted_service->begin()->second[i]);
   }
 
@@ -134,7 +133,7 @@
   EXPECT_EQ(cic & 0xff, kManufacturerData[0]);
   EXPECT_EQ((cic >> 8) & 0xff, kManufacturerData[1]);
   EXPECT_EQ(converted_manufacturer->begin()->second.size(),
-            base::size(kManufacturerData) - sizeof(uint16_t));
+            std::size(kManufacturerData) - sizeof(uint16_t));
 }
 
 TEST(BluetoothStructTraitsTest, DeserializeBluetoothAdvertisementFailure) {
diff --git a/ash/components/arc/mojom/ime_mojom_traits_unittest.cc b/ash/components/arc/mojom/ime_mojom_traits_unittest.cc
index c9665bb7..30f8f0d 100644
--- a/ash/components/arc/mojom/ime_mojom_traits_unittest.cc
+++ b/ash/components/arc/mojom/ime_mojom_traits_unittest.cc
@@ -35,7 +35,7 @@
       {ui::ET_KEY_RELEASED, ui::VKEY_B, ui::DomCode::US_B, ui::EF_SHIFT_DOWN},
       {ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, ui::EF_CAPS_LOCK_ON},
   };
-  for (size_t idx = 0; idx < base::size(kTestData); ++idx) {
+  for (size_t idx = 0; idx < std::size(kTestData); ++idx) {
     auto copy = std::make_unique<ui::KeyEvent>(kTestData[idx]);
     std::unique_ptr<ui::KeyEvent> output;
     mojo::test::SerializeAndDeserialize<arc::mojom::KeyEventData>(copy, output);
diff --git a/ash/components/arc/session/arc_session_impl.cc b/ash/components/arc/session/arc_session_impl.cc
index 1d14afd..7c72f4d 100644
--- a/ash/components/arc/session/arc_session_impl.cc
+++ b/ash/components/arc/session/arc_session_impl.cc
@@ -22,7 +22,6 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/posix/eintr_wrapper.h"
@@ -75,7 +74,7 @@
       {raw_cancel_fd, POLLIN, 0},
   };
 
-  if (HANDLE_EINTR(poll(fds, base::size(fds), -1)) <= 0) {
+  if (HANDLE_EINTR(poll(fds, std::size(fds), -1)) <= 0) {
     PLOG(ERROR) << "poll()";
     return false;
   }
diff --git a/ash/components/disks/disk_mount_manager_unittest.cc b/ash/components/disks/disk_mount_manager_unittest.cc
index 40ef940..88084401 100644
--- a/ash/components/disks/disk_mount_manager_unittest.cc
+++ b/ash/components/disks/disk_mount_manager_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/components/disks/disk_mount_manager.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
@@ -11,9 +13,7 @@
 #include <vector>
 
 #include "ash/components/disks/disk.h"
-#include "ash/components/disks/disk_mount_manager.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
@@ -601,10 +601,10 @@
   void InitDisksAndMountPoints() {
     // Disks should be  added first (when adding device mount points it is
     // expected that the corresponding disk is already added).
-    for (size_t i = 0; i < base::size(kTestDisks); i++)
+    for (size_t i = 0; i < std::size(kTestDisks); i++)
       AddTestDisk(kTestDisks[i]);
 
-    for (size_t i = 0; i < base::size(kTestMountPoints); i++)
+    for (size_t i = 0; i < std::size(kTestMountPoints); i++)
       AddTestMountPoint(kTestMountPoints[i]);
   }
 
diff --git a/ash/components/geolocation/geoposition.cc b/ash/components/geolocation/geoposition.cc
index 653e9c2..5891ed9 100644
--- a/ash/components/geolocation/geoposition.cc
+++ b/ash/components/geolocation/geoposition.cc
@@ -4,7 +4,6 @@
 
 #include "ash/components/geolocation/geoposition.h"
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 
 namespace {
@@ -45,7 +44,7 @@
       "error_message='%s', status=%u (%s)",
       latitude, longitude, accuracy, error_code, error_message.c_str(),
       (unsigned)status,
-      (status < base::size(status2string) ? status2string[status] : "unknown"));
+      (status < std::size(status2string) ? status2string[status] : "unknown"));
 }
 
 }  // namespace ash
diff --git a/ash/components/proximity_auth/metrics.cc b/ash/components/proximity_auth/metrics.cc
index d89d3f68..7913f8f 100644
--- a/ash/components/proximity_auth/metrics.cc
+++ b/ash/components/proximity_auth/metrics.cc
@@ -25,7 +25,7 @@
   // First, copy to a uint32_t, since byte swapping and endianness conversions
   // expect unsigned integers.
   uint32_t unsigned_value;
-  DCHECK_GE(base::size(digest.a), sizeof(unsigned_value));
+  DCHECK_GE(std::size(digest.a), sizeof(unsigned_value));
   memcpy(&unsigned_value, digest.a, sizeof(unsigned_value));
   unsigned_value = base::ByteSwap(base::HostToNet32(unsigned_value));
 
diff --git a/ash/components/settings/timezone_settings.cc b/ash/components/settings/timezone_settings.cc
index d2f5758..e17c21a 100644
--- a/ash/components/settings/timezone_settings.cc
+++ b/ash/components/settings/timezone_settings.cc
@@ -11,7 +11,6 @@
 
 #include "ash/components/settings/timezone_settings_helper.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/i18n/unicodestring.h"
@@ -374,7 +373,7 @@
 }
 
 TimezoneSettingsBaseImpl::TimezoneSettingsBaseImpl() {
-  for (size_t i = 0; i < base::size(kTimeZones); ++i) {
+  for (size_t i = 0; i < std::size(kTimeZones); ++i) {
     timezones_.push_back(base::WrapUnique(icu::TimeZone::createTimeZone(
         icu::UnicodeString(kTimeZones[i], -1, US_INV))));
   }
diff --git a/ash/components/timezone/timezone_request.cc b/ash/components/timezone/timezone_request.cc
index 00da029..07545dd 100644
--- a/ash/components/timezone/timezone_request.cc
+++ b/ash/components/timezone/timezone_request.cc
@@ -5,11 +5,11 @@
 #include "ash/components/timezone/timezone_request.h"
 
 #include <stddef.h>
+
 #include <string>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -258,7 +258,7 @@
   }
 
   bool found = false;
-  for (size_t i = 0; i < base::size(statusString2Enum); ++i) {
+  for (size_t i = 0; i < std::size(statusString2Enum); ++i) {
     if (*status != statusString2Enum[i].string)
       continue;
 
@@ -486,7 +486,7 @@
       "error_message='%s', status=%u (%s)",
       dstOffset, rawOffset, timeZoneId.c_str(), timeZoneName.c_str(),
       error_message.c_str(), (unsigned)status,
-      (status < base::size(status2string) ? status2string[status] : "unknown"));
+      (status < std::size(status2string) ? status2string[status] : "unknown"));
 }
 
 }  // namespace ash
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 9a962123..f83ca77 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -547,10 +547,6 @@
 const base::Feature kEnableOobeNetworkScreenSkip{
     "EnableOobeNetworkScreenSkip", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Enables toggling Pciguard settings through Settings UI.
-const base::Feature kEnablePciguardUi{"EnablePciguardUi",
-                                      base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Enables showing notification after the password change for SAML users.
 const base::Feature kEnableSamlNotificationOnPasswordChangeSuccess{
     "EnableSamlNotificationOnPasswordChangeSuccess",
@@ -1860,9 +1856,6 @@
 bool IsPcieBillboardNotificationEnabled() {
   return base::FeatureList::IsEnabled(kPcieBillboardNotification);
 }
-bool IsPciguardUiEnabled() {
-  return base::FeatureList::IsEnabled(kEnablePciguardUi);
-}
 
 bool IsPerDeskShelfEnabled() {
   return base::FeatureList::IsEnabled(kPerDeskShelf);
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index ccb99ecf..8a701e7 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -863,7 +863,7 @@
     int64_t display_id) const {
   const display::Display& display =
       GetDisplayManager()->GetDisplayForId(display_id);
-  return display.id() == display::kInvalidDisplayId ? nullptr : &display;
+  return display.is_valid() ? &display : nullptr;
 }
 
 void WindowTreeHostManager::SetCurrentEventTargeterSourceHost(
diff --git a/ash/events/keyboard_driven_event_rewriter_unittest.cc b/ash/events/keyboard_driven_event_rewriter_unittest.cc
index 5f64a6a7..a7e580f 100644
--- a/ash/events/keyboard_driven_event_rewriter_unittest.cc
+++ b/ash/events/keyboard_driven_event_rewriter_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/events/keyboard_driven_event_rewriter.h"
+
 #include <stddef.h>
 
 #include <string>
 
-#include "ash/events/keyboard_driven_event_rewriter.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event.h"
@@ -114,7 +114,7 @@
     { ui::VKEY_RETURN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN },
   };
 
-  for (size_t i = 0; i < base::size(kTests); ++i) {
+  for (size_t i = 0; i < std::size(kTests); ++i) {
     EXPECT_EQ(base::StringPrintf("PassThrough ui_flags=%d", kTests[i].ui_flags),
               GetRewrittenEventAsString(kTests[i].ui_keycode,
                                         kTests[i].ui_flags, ui::ET_KEY_PRESSED))
@@ -137,7 +137,7 @@
     { ui::VKEY_F6, kModifierMask },
   };
 
-  for (size_t i = 0; i < base::size(kTests); ++i) {
+  for (size_t i = 0; i < std::size(kTests); ++i) {
     EXPECT_EQ("Rewritten ui_flags=0",
               GetRewrittenEventAsString(kTests[i].ui_keycode,
                                         kTests[i].ui_flags, ui::ET_KEY_PRESSED))
diff --git a/ash/keyboard/ui/resources/keyboard_resource_util.cc b/ash/keyboard/ui/resources/keyboard_resource_util.cc
index 1e11821..25c2c666 100644
--- a/ash/keyboard/ui/resources/keyboard_resource_util.cc
+++ b/ash/keyboard/ui/resources/keyboard_resource_util.cc
@@ -6,7 +6,6 @@
 
 #include "ash/keyboard/ui/grit/keyboard_resources.h"
 #include "ash/keyboard/ui/grit/keyboard_resources_map.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -93,7 +92,7 @@
       {"keyboard/sounds/keypress-standard.wav",
        IDR_KEYBOARD_SOUNDS_KEYPRESS_STANDARD},
   };
-  *size = base::size(kKeyboardResources);
+  *size = std::size(kKeyboardResources);
   return kKeyboardResources;
 }
 
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc
index 074c722..32c7b05 100644
--- a/ash/login/ui/lock_debug_view.cc
+++ b/ash/login/ui/lock_debug_view.cc
@@ -29,7 +29,6 @@
 #include "ash/style/ash_color_provider.h"
 #include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -141,8 +140,8 @@
   result.basic_user_info.display_name =
       is_public_account
           ? kDebugPublicAccountNames[user_index %
-                                     base::size(kDebugPublicAccountNames)]
-          : kDebugUserNames[user_index % base::size(kDebugUserNames)];
+                                     std::size(kDebugPublicAccountNames)]
+          : kDebugUserNames[user_index % std::size(kDebugUserNames)];
   result.basic_user_info.display_email =
       result.basic_user_info.account_id.GetUserEmail();
 
@@ -692,7 +691,7 @@
   // Calculates the debugging detachable base ID that should become the paired
   // base in the model when the button for cycling paired bases is clicked.
   int NextBaseId() const {
-    return (base_id_ + 1) % base::size(kDebugDetachableBases);
+    return (base_id_ + 1) % std::size(kDebugDetachableBases);
   }
 
   // Gets the descripting text for currently paired base, if any.
@@ -711,7 +710,7 @@
     pairing_status_ = pairing_status;
     if (pairing_status == DetachableBasePairingStatus::kAuthenticated) {
       CHECK_GE(base_id, 0);
-      CHECK_LT(base_id, static_cast<int>(base::size(kDebugDetachableBases)));
+      CHECK_LT(base_id, static_cast<int>(std::size(kDebugDetachableBases)));
       base_id_ = base_id;
     } else {
       base_id_ = kNullBaseId;
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc
index 634f7de..0654cec 100644
--- a/ash/login/ui/login_password_view.cc
+++ b/ash/login/ui/login_password_view.cc
@@ -412,7 +412,7 @@
         std::unique_ptr<ui::LayerAnimationSequence> opacity_sequence =
             std::make_unique<ui::LayerAnimationSequence>();
         opacity_sequence->set_is_repeating(true);
-        for (size_t i = 0; i < base::size(kSpinnerFramesParams); ++i) {
+        for (size_t i = 0; i < std::size(kSpinnerFramesParams); ++i) {
           opacity_sequence->AddElement(
               ui::LayerAnimationElement::CreateOpacityElement(
                   kSpinnerFramesParams[i].opacity,
@@ -515,7 +515,7 @@
     // the layer animator or the observer is destroyed.
     opacity_sequence->AddObserver(observer_.get());
     opacity_sequence->set_is_repeating(true);
-    for (size_t i = 0; i < base::size(kAlternateFramesParams); ++i) {
+    for (size_t i = 0; i < std::size(kAlternateFramesParams); ++i) {
       opacity_sequence->AddElement(
           ui::LayerAnimationElement::CreateOpacityElement(
               kAlternateFramesParams[i].opacity,
diff --git a/ash/login/ui/login_pin_view.cc b/ash/login/ui/login_pin_view.cc
index 9a1025df..1b7c1fa 100644
--- a/ash/login/ui/login_pin_view.cc
+++ b/ash/login/ui/login_pin_view.cc
@@ -12,7 +12,6 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/timer/timer.h"
 #include "ui/accessibility/ax_action_data.h"
@@ -67,12 +66,12 @@
 constexpr gfx::Size kButtonSize = gfx::Size(kButtonWidthDp, kButtonHeightDp);
 
 std::u16string GetButtonLabelForNumber(int value) {
-  DCHECK(value >= 0 && value < int{base::size(kPinLabels)});
+  DCHECK(value >= 0 && value < int{std::size(kPinLabels)});
   return base::ASCIIToUTF16(std::to_string(value));
 }
 
 std::u16string GetButtonSubLabelForNumber(int value) {
-  DCHECK(value >= 0 && value < int{base::size(kPinLabels)});
+  DCHECK(value >= 0 && value < int{std::size(kPinLabels)});
   return base::ASCIIToUTF16(kPinLabels[value]);
 }
 
diff --git a/ash/power/hid_battery_util.cc b/ash/power/hid_battery_util.cc
index b14cd5f..c388d6b0 100644
--- a/ash/power/hid_battery_util.cc
+++ b/ash/power/hid_battery_util.cc
@@ -16,9 +16,9 @@
 // /sys/class/power_supply/hid-{AA:BB:CC:DD:EE:FF|AAAA:BBBB:CCCC.DDDD}-battery.
 constexpr char kHIDBatteryPrefix[] = "/sys/class/power_supply/hid-";
 constexpr char kHIDBatterySuffix[] = "-battery";
-constexpr size_t kPrefixLen = base::size(kHIDBatteryPrefix) - 1;
+constexpr size_t kPrefixLen = std::size(kHIDBatteryPrefix) - 1;
 constexpr size_t kPrefixAndSuffixLen =
-    (base::size(kHIDBatteryPrefix) - 1) + (base::size(kHIDBatterySuffix) - 1);
+    (std::size(kHIDBatteryPrefix) - 1) + (std::size(kHIDBatterySuffix) - 1);
 
 // Regex to check for valid bluetooth addresses.
 constexpr char kBluetoothAddressRegex[] =
diff --git a/ash/projector/projector_annotation_tray.cc b/ash/projector/projector_annotation_tray.cc
index 15c8c69..918c58d 100644
--- a/ash/projector/projector_annotation_tray.cc
+++ b/ash/projector/projector_annotation_tray.cc
@@ -33,10 +33,10 @@
 constexpr int kPaddingBetweenBottomAndLastTrayItem = 4;
 
 // Width of the bubble itself (dp).
-constexpr int kBubbleWidth = 372;
+constexpr int kBubbleWidth = 288;
 
 // Insets for the views (dp).
-constexpr gfx::Insets kPenViewPadding(4, 0, 0, 24);
+constexpr gfx::Insets kPenViewPadding(4, 24, 0, 24);
 
 // Spacing between buttons (dp).
 constexpr int kButtonsPadding = 20;
@@ -51,6 +51,7 @@
 // Colors.
 constexpr SkColor kRedPenColor = SkColorSetRGB(0xEA, 0x43, 0x35);
 constexpr SkColor kYellowPenColor = SkColorSetRGB(0xFB, 0xBC, 0x04);
+constexpr SkColor kBluePenColor = SkColorSetRGB(0x1A, 0x73, 0xE8);
 
 // TODO(b/201664243): Use AnnotatorToolType.
 enum ProjectorTool { kToolNone, kToolPen };
@@ -179,17 +180,7 @@
     box_layout->set_cross_axis_alignment(
         views::BoxLayout::CrossAxisAlignment::kCenter);
     box_layout->set_minimum_cross_axis_size(kMenuRowHeight);
-    views::BoxLayout* layout_ptr =
-        marker_view_container->SetLayoutManager(std::move(box_layout));
-
-    SkColor icon_color = AshColorProvider::Get()->GetContentLayerColor(
-        AshColorProvider::ContentLayerType::kButtonIconColor);
-    gfx::ImageSkia icon =
-        CreateVectorIcon(kInkPenIcon, kMenuIconSize, icon_color);
-    pen_view_ = marker_view_container->AddChildView(
-        std::make_unique<HoverHighlightView>(this));
-    pen_view_->AddIconAndLabel(icon, l10n_util::GetStringUTF16(IDS_PEN_BUTTON));
-    layout_ptr->SetFlexForView(pen_view_, 1, true);
+    marker_view_container->SetLayoutManager(std::move(box_layout));
 
     // TODO(b/201664243): Only draw outer circle on hover or selection.
     marker_view_container->AddChildView(std::make_unique<ProjectorColorButton>(
@@ -199,6 +190,16 @@
         l10n_util::GetStringUTF16(IDS_RED_COLOR_BUTTON)));
     marker_view_container->AddChildView(std::make_unique<ProjectorColorButton>(
         base::BindRepeating(&ProjectorAnnotationTray::OnPenColorPressed,
+                            base::Unretained(this), kBluePenColor),
+        kBluePenColor, kColorButtonColorViewSize, kColorButtonViewRadius,
+        l10n_util::GetStringUTF16(IDS_BLUE_COLOR_BUTTON)));
+    marker_view_container->AddChildView(std::make_unique<ProjectorColorButton>(
+        base::BindRepeating(&ProjectorAnnotationTray::OnPenColorPressed,
+                            base::Unretained(this), SK_ColorWHITE),
+        SK_ColorWHITE, kColorButtonColorViewSize, kColorButtonViewRadius,
+        l10n_util::GetStringUTF16(IDS_WHITE_COLOR_BUTTON)));
+    marker_view_container->AddChildView(std::make_unique<ProjectorColorButton>(
+        base::BindRepeating(&ProjectorAnnotationTray::OnPenColorPressed,
                             base::Unretained(this), kYellowPenColor),
         kYellowPenColor, kColorButtonColorViewSize, kColorButtonViewRadius,
         l10n_util::GetStringUTF16(IDS_YELLOW_COLOR_BUTTON)));
@@ -207,11 +208,6 @@
                             base::Unretained(this), SK_ColorBLACK),
         SK_ColorBLACK, kColorButtonColorViewSize, kColorButtonViewRadius,
         l10n_util::GetStringUTF16(IDS_BLACK_COLOR_BUTTON)));
-    marker_view_container->AddChildView(std::make_unique<ProjectorColorButton>(
-        base::BindRepeating(&ProjectorAnnotationTray::OnPenColorPressed,
-                            base::Unretained(this), SK_ColorWHITE),
-        SK_ColorWHITE, kColorButtonColorViewSize, kColorButtonViewRadius,
-        l10n_util::GetStringUTF16(IDS_WHITE_COLOR_BUTTON)));
 
     setup_layered_view(marker_view_container);
   }
@@ -234,18 +230,6 @@
   UpdateIcon();
 }
 
-void ProjectorAnnotationTray::OnViewClicked(views::View* sender) {
-  auto* projector_controller = ProjectorControllerImpl::Get();
-  DCHECK(projector_controller);
-
-  if (sender == pen_view_) {
-    projector_controller->OnMarkerPressed();
-  }
-
-  CloseBubble();
-  UpdateIcon();
-}
-
 void ProjectorAnnotationTray::DeactivateActiveTool() {
   auto* controller = Shell::Get()->projector_controller();
   DCHECK(controller);
diff --git a/ash/projector/projector_annotation_tray.h b/ash/projector/projector_annotation_tray.h
index a0d3cd54..cc32db7 100644
--- a/ash/projector/projector_annotation_tray.h
+++ b/ash/projector/projector_annotation_tray.h
@@ -15,8 +15,7 @@
 
 // Status area tray which allows you to access the annotation tools for
 // Projector.
-class ProjectorAnnotationTray : public TrayBackgroundView,
-                                public ViewClickListener {
+class ProjectorAnnotationTray : public TrayBackgroundView {
  public:
   explicit ProjectorAnnotationTray(Shelf* shelf);
   ProjectorAnnotationTray(const ProjectorAnnotationTray&) = delete;
@@ -35,9 +34,6 @@
   views::Widget* GetBubbleWidget() const override;
   void OnThemeChanged() override;
 
-  // ViewClickListener:
-  void OnViewClicked(views::View* sender) override;
-
  private:
   // Deactives any annotation tool that is currently enabled and update the UI.
   void DeactivateActiveTool();
diff --git a/ash/public/cpp/accelerators.cc b/ash/public/cpp/accelerators.cc
index ca82431..009742b7 100644
--- a/ash/public/cpp/accelerators.cc
+++ b/ash/public/cpp/accelerators.cc
@@ -5,7 +5,6 @@
 #include "ash/public/cpp/accelerators.h"
 
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/no_destructor.h"
 
 namespace ash {
@@ -233,7 +232,7 @@
      TOGGLE_RESIZE_LOCK_MENU},
 };
 
-const size_t kAcceleratorDataLength = base::size(kAcceleratorData);
+const size_t kAcceleratorDataLength = std::size(kAcceleratorData);
 
 const AcceleratorData kDisableWithNewMappingAcceleratorData[] = {
     // Desk creation and removal:
@@ -249,7 +248,7 @@
 };
 
 const size_t kDisableWithNewMappingAcceleratorDataLength =
-    base::size(kDisableWithNewMappingAcceleratorData);
+    std::size(kDisableWithNewMappingAcceleratorData);
 
 const AcceleratorData kEnableWithNewMappingAcceleratorData[] = {
     // Desk creation and removal:
@@ -295,7 +294,7 @@
 };
 
 const size_t kEnableWithNewMappingAcceleratorDataLength =
-    base::size(kEnableWithNewMappingAcceleratorData);
+    std::size(kEnableWithNewMappingAcceleratorData);
 
 const AcceleratorData kEnableWithPositionalAcceleratorsData[] = {
     // These are the desk shortcuts as advertised, but previously
@@ -312,7 +311,7 @@
 };
 
 const size_t kEnableWithPositionalAcceleratorsDataLength =
-    base::size(kEnableWithPositionalAcceleratorsData);
+    std::size(kEnableWithPositionalAcceleratorsData);
 
 const AcceleratorData
     kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorData[] = {
@@ -339,7 +338,7 @@
 };
 
 const size_t kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorDataLength =
-    base::size(kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorData);
+    std::size(kEnabledWithImprovedDesksKeyboardShortcutsAcceleratorData);
 
 // static
 AcceleratorController* AcceleratorController::Get() {
diff --git a/ash/public/cpp/app_list/app_list_config.cc b/ash/public/cpp/app_list/app_list_config.cc
index e8df109..6a4bb5c 100644
--- a/ash/public/cpp/app_list/app_list_config.cc
+++ b/ash/public/cpp/app_list/app_list_config.cc
@@ -49,7 +49,7 @@
     case ash::AppListConfigType::kRegular:
       return 96;
     case ash::AppListConfigType::kDense:
-      return 72;
+      return 80;
   }
 }
 
diff --git a/ash/public/cpp/app_list/app_list_config_provider_unittest.cc b/ash/public/cpp/app_list/app_list_config_provider_unittest.cc
index 68ef9f3..33d1616 100644
--- a/ash/public/cpp/app_list/app_list_config_provider_unittest.cc
+++ b/ash/public/cpp/app_list/app_list_config_provider_unittest.cc
@@ -269,7 +269,7 @@
     AppListConfigType config_type;
   } test_cases[] = {
       {gfx::Size(900, 500), gfx::Size(788, 321), AppListConfigType::kDense},
-      {gfx::Size(500, 900), gfx::Size(388, 704), AppListConfigType::kDense},
+      {gfx::Size(540, 900), gfx::Size(428, 704), AppListConfigType::kDense},
       {gfx::Size(960, 600), gfx::Size(848, 412), AppListConfigType::kDense},
       {gfx::Size(1100, 700), gfx::Size(988, 504), AppListConfigType::kRegular},
       {gfx::Size(600, 960), gfx::Size(488, 764), AppListConfigType::kDense},
diff --git a/ash/public/cpp/desk_template.h b/ash/public/cpp/desk_template.h
index 0bd4607..fd0e4dc 100644
--- a/ash/public/cpp/desk_template.h
+++ b/ash/public/cpp/desk_template.h
@@ -65,12 +65,12 @@
     template_name_ = template_name;
   }
 
-  const app_restore::RestoreData* desk_restore_data() const {
+  const ::app_restore::RestoreData* desk_restore_data() const {
     return desk_restore_data_.get();
   }
 
   void set_desk_restore_data(
-      std::unique_ptr<app_restore::RestoreData> restore_data) {
+      std::unique_ptr<::app_restore::RestoreData> restore_data) {
     desk_restore_data_ = std::move(restore_data);
   }
 
@@ -117,7 +117,7 @@
   // Contains the app launching and window information that can be used to
   // create a new desk instance with the same set of apps/windows specified in
   // it.
-  std::unique_ptr<app_restore::RestoreData> desk_restore_data_;
+  std::unique_ptr<::app_restore::RestoreData> desk_restore_data_;
 };
 
 }  // namespace ash
diff --git a/ash/public/cpp/desks_templates_delegate.h b/ash/public/cpp/desks_templates_delegate.h
index 78f93f9..b4506ab3 100644
--- a/ash/public/cpp/desks_templates_delegate.h
+++ b/ash/public/cpp/desks_templates_delegate.h
@@ -88,6 +88,7 @@
   // debugging.
   virtual void LaunchAppsFromTemplate(
       std::unique_ptr<DeskTemplate> desk_template,
+      base::Time time_launch_started,
       base::TimeDelta delay) = 0;
 
   // Checks whether `window` is supported in the desks templates feature.
diff --git a/ash/public/cpp/login_accelerators.cc b/ash/public/cpp/login_accelerators.cc
index 4c50bce..0e9394e 100644
--- a/ash/public/cpp/login_accelerators.cc
+++ b/ash/public/cpp/login_accelerators.cc
@@ -6,8 +6,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
-
 namespace ash {
 namespace {
 
@@ -79,7 +77,7 @@
 };
 // clang-format on
 
-const size_t kLoginAcceleratorDataLength = base::size(kLoginAcceleratorData);
+const size_t kLoginAcceleratorDataLength = std::size(kLoginAcceleratorData);
 
 std::string MapToWebUIAccelerator(LoginAcceleratorAction action) {
   switch (action) {
diff --git a/ash/public/cpp/projector/projector_new_screencast_precondition.h b/ash/public/cpp/projector/projector_new_screencast_precondition.h
index 5aee910c..e5434b55 100644
--- a/ash/public/cpp/projector/projector_new_screencast_precondition.h
+++ b/ash/public/cpp/projector/projector_new_screencast_precondition.h
@@ -39,7 +39,9 @@
   kSodaDownloadInProgress = 5,
   kOutOfDiskSpace = 6,
   kNoMic = 7,
-  kOthers = 8
+  kDriveFsUnmounted = 8,    // Drive could be re-enabled from the Setting.
+  kDriveFsMountFailed = 9,  // Drive will not be automatically retried to mount.
+  kOthers = 10,
 };
 
 // Struct used to provide the new screen cast precondition state and the reasons
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.cc b/ash/public/cpp/test/test_desks_templates_delegate.cc
index 571c552c..889f534f 100644
--- a/ash/public/cpp/test/test_desks_templates_delegate.cc
+++ b/ash/public/cpp/test/test_desks_templates_delegate.cc
@@ -50,6 +50,7 @@
 
 void TestDesksTemplatesDelegate::LaunchAppsFromTemplate(
     std::unique_ptr<DeskTemplate> desk_template,
+    base::Time time_launch_started,
     base::TimeDelta delay) {}
 
 bool TestDesksTemplatesDelegate::IsWindowSupportedForDeskTemplate(
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.h b/ash/public/cpp/test/test_desks_templates_delegate.h
index ed9a727..d5042e9 100644
--- a/ash/public/cpp/test/test_desks_templates_delegate.h
+++ b/ash/public/cpp/test/test_desks_templates_delegate.h
@@ -57,6 +57,7 @@
       int desired_icon_size,
       base::OnceCallback<void(const gfx::ImageSkia&)> callback) const override;
   void LaunchAppsFromTemplate(std::unique_ptr<DeskTemplate> desk_template,
+                              base::Time time_launch_started,
                               base::TimeDelta delay) override;
   bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
   void OpenFeedbackDialog(const std::string& extra_diagnostics) override;
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc
index 9007ce1..678077e 100644
--- a/ash/quick_pair/message_stream/message_stream_lookup_impl.cc
+++ b/ash/quick_pair/message_stream/message_stream_lookup_impl.cc
@@ -210,6 +210,13 @@
     return;
   }
 
+  if (base::Contains(pending_connect_requests_, device->GetAddress())) {
+    QP_LOG(VERBOSE) << __func__ << ": Ignoring due to matching pending request";
+    return;
+  }
+
+  pending_connect_requests_.insert(device->GetAddress());
+
   device->ConnectToService(
       /*uuid=*/kMessageStreamUuid, /*callback=*/
       base::BindOnce(&MessageStreamLookupImpl::OnConnected,
@@ -217,7 +224,7 @@
                      base::TimeTicks::Now(), type),
       /*error_callback=*/
       base::BindOnce(&MessageStreamLookupImpl::OnConnectError,
-                     weak_ptr_factory_.GetWeakPtr(), type));
+                     weak_ptr_factory_.GetWeakPtr(), device_address, type));
 }
 
 void MessageStreamLookupImpl::OnConnected(
@@ -238,9 +245,11 @@
     observer.OnMessageStreamConnected(device_address, message_stream.get());
 
   message_streams_[device_address] = std::move(message_stream);
+  pending_connect_requests_.erase(device_address);
 }
 
 void MessageStreamLookupImpl::OnConnectError(
+    std::string device_address,
     const CreateMessageStreamAttemptType& type,
     const std::string& error_message) {
   // Because we need to attempt to create MessageStreams at many different
@@ -250,6 +259,7 @@
                << "]. Type = " << CreateMessageStreamAttemptTypeToString(type);
   RecordMessageStreamConnectToServiceResult(/*success=*/false);
   RecordMessageStreamConnectToServiceError(error_message);
+  pending_connect_requests_.erase(device_address);
 }
 
 }  // namespace quick_pair
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl.h b/ash/quick_pair/message_stream/message_stream_lookup_impl.h
index eae320d4b..41af3d9 100644
--- a/ash/quick_pair/message_stream/message_stream_lookup_impl.h
+++ b/ash/quick_pair/message_stream/message_stream_lookup_impl.h
@@ -11,6 +11,7 @@
 
 #include "ash/quick_pair/message_stream/message_stream.h"
 #include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
@@ -79,7 +80,8 @@
                    base::TimeTicks connect_to_service_start_time,
                    const CreateMessageStreamAttemptType& type,
                    scoped_refptr<device::BluetoothSocket> socket);
-  void OnConnectError(const CreateMessageStreamAttemptType& type,
+  void OnConnectError(std::string device_address,
+                      const CreateMessageStreamAttemptType& type,
                       const std::string& error_message);
 
   // Helper function to disconnect socket from a MessageStream instance and
@@ -99,6 +101,8 @@
   base::flat_map<std::string, std::unique_ptr<MessageStream>> message_streams_;
   scoped_refptr<device::BluetoothAdapter> adapter_;
 
+  base::flat_set<std::string> pending_connect_requests_;
+
   base::ScopedObservation<device::BluetoothAdapter,
                           device::BluetoothAdapter::Observer>
       adapter_observation_{this};
diff --git a/ash/quick_pair/message_stream/message_stream_lookup_impl_unittest.cc b/ash/quick_pair/message_stream/message_stream_lookup_impl_unittest.cc
index 899b995e..79e4d718 100644
--- a/ash/quick_pair/message_stream/message_stream_lookup_impl_unittest.cc
+++ b/ash/quick_pair/message_stream/message_stream_lookup_impl_unittest.cc
@@ -102,6 +102,12 @@
   void ConnectToService(const device::BluetoothUUID& uuid,
                         ConnectToServiceCallback callback,
                         ConnectToServiceErrorCallback error_callback) override {
+    connect_to_service_count_++;
+
+    if (dont_invoke_callback_) {
+      return;
+    }
+
     if (error_) {
       std::move(error_callback).Run(/*message=*/error_message_);
       return;
@@ -115,6 +121,10 @@
     error_message_ = error_message;
   }
 
+  int connect_to_service_count() { return connect_to_service_count_; }
+
+  void DontInvokeCallback() { dont_invoke_callback_ = true; }
+
   // Move-only class
   MessageStreamFakeBluetoothDevice(const MessageStreamFakeBluetoothDevice&) =
       delete;
@@ -122,6 +132,8 @@
       const MessageStreamFakeBluetoothDevice&) = delete;
 
  protected:
+  int connect_to_service_count_ = 0;
+  bool dont_invoke_callback_ = false;
   bool error_ = false;
   std::string error_message_;
   MessageStreamFakeBluetoothAdapter* fake_adapter_;
@@ -546,5 +558,18 @@
   EXPECT_EQ(GetMessageStream(), nullptr);
 }
 
+TEST_F(MessageStreamLookupImplTest, InFlightConnections) {
+  device_->AddUUID(kMessageStreamUuid);
+  device_->SetPaired(true);
+  device_->DontInvokeCallback();
+
+  EXPECT_EQ(GetMessageStream(), nullptr);
+  DeviceConnectedStateChanged(/*is_now_connected=*/true);
+  DeviceChanged();
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(device_->connect_to_service_count(), 1);
+}
+
 }  // namespace quick_pair
 }  // namespace ash
diff --git a/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc b/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
index dc7fa21e..a69308d 100644
--- a/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/bn_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/bn_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace bn_phone {
 
@@ -714,7 +714,7 @@
     u8"\\1\u09be\u09af\u09bc",
     u8"([\u0995-\u09b9\u09dc-\u09df])\u001daax",
     u8"\\1\u09be\u0995\u09cd\u09b7"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune =
     "a|aa|ac|aaC|aac|a\\.|aK|aC|aaK|aS|aaS|aa~|aa\\.|a~";
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc b/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
index 3125b2ad..a94a75d9 100644
--- a/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/deva_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/deva_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace deva_phone {
 
@@ -533,7 +533,7 @@
     u8"\u0965",
     u8"\u0964\u001d?\\.",
     u8"\u2026"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "n(\\.)?|c|ch|C|nc|nC|nch|\\.|a";
 
 }  // namespace deva_phone
diff --git a/ash/services/ime/public/cpp/rulebased/def/ethi.cc b/ash/services/ime/public/cpp/rulebased/def/ethi.cc
index dc87040..b04a39f 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ethi.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/ethi.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/ethi.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ethi {
 
@@ -1313,7 +1313,7 @@
                              u8"\u1370",
                              u8"'9",
                              u8"\u1371"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace ethi
diff --git a/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc b/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
index 80eae434..1c4a5bc 100644
--- a/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/gu_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/gu_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace gu_phone {
 
@@ -728,7 +728,7 @@
     u8"\\1\u0abe\u0aaf\u0abc",
     u8"([\u0a95-\u0ab9])\u001daax",
     u8"\\1\u0abe\u0a95\u0acd\u0ab7"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune =
     "a|aa|ac|aaC|aac|a\\.|aK|aC|aaK|aS|aaS|aa~|aa\\.|a~";
 
diff --git a/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc b/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
index df702fbd..c8f4d01 100644
--- a/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/kn_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/kn_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace kn_phone {
 
@@ -320,7 +320,7 @@
                              u8"\u0964",
                              u8"\u0964\u001d?\\|",
                              u8"\u0965"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "C|c";
 
 }  // namespace kn_phone
diff --git a/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc b/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
index c1cce410..1af84920 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/ml_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/ml_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ml_phone {
 
@@ -835,7 +835,7 @@
     u8"\u0d7b",
     u8"r",
     u8"\u0d7c"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "a|@|@a|c|R|_|~";
 
 }  // namespace ml_phone
diff --git a/ash/services/ime/public/cpp/rulebased/def/my.cc b/ash/services/ime/public/cpp/rulebased/def/my.cc
index d9a2fe6..b835a3f 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/my.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/my.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace my {
 
@@ -440,7 +440,7 @@
     u8"\\1\u1039\u1031",
     u8"\u1039\u1031\u001d([\u1000-\u1019\u101c\u101e\u1020\u1021])",
     u8"\u1039\\1\u1031"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace my
diff --git a/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc b/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
index a1ec7b9..27ef5146 100644
--- a/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/my_myansan.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/my_myansan.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace my_myansan {
 
@@ -440,7 +440,7 @@
     u8"\\1\u1039\u1031",
     u8"\u1039\u1031\u001d([\u1000-\u1019\u101c\u101e\u1020\u1021])",
     u8"\u1039\\1\u1031"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace my_myansan
diff --git a/ash/services/ime/public/cpp/rulebased/def/si.cc b/ash/services/ime/public/cpp/rulebased/def/si.cc
index 0fb88f6..f43b904 100644
--- a/ash/services/ime/public/cpp/rulebased/def/si.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/si.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/si.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace si {
 
@@ -457,7 +457,7 @@
                              u8"([\u0d9a-\u0dc6](\u0dca\u200d[\u0dba\u0dbb])|("
                              u8"\u0dbb\u0dca\u200d))\u0ddc\u001d\u0dca",
                              u8"\\1\u0ddd"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace si
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc b/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
index 453a8a7..bd20293 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/ta_itrans.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/ta_itrans.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ta_itrans {
 
@@ -83,7 +83,7 @@
                              u8"#",    u8"\u0bcd",
                              u8"\\$",  u8"\u0bb0",
                              u8"\\^",  u8"\u0ba4\u0bcd"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "[\\^lrshkdnJNtTaeiouAEIOU]|sh|ks|dn";
 
 }  // namespace ta_itrans
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc b/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
index e9f3537..912576c 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/ta_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/ta_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ta_phone {
 
@@ -544,7 +544,7 @@
                              u8"\u0ba9\u0bcd\u0b9f\u0bcd\u0bb0\u0bcd",
                              u8"\u0ba3\u0bcd\u0b9f\u0bcd\u001d?r",
                              u8"\u0ba9\u0bcd\u0bb1\u0bcd"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "t|dh|d";
 
 }  // namespace ta_phone
diff --git a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc b/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
index 5e5143f..6e2d15d 100644
--- a/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/ta_tamil99.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/ta_tamil99.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ta_tamil99 {
 
@@ -425,7 +425,7 @@
                              u8"([\u0b95-\u0bb9])\u0b92", u8"\\1\u0bca",
                              u8"([\u0b95-\u0bb9])\u0b93", u8"\\1\u0bcb",
                              u8"([\u0b95-\u0bb9])\u0b94", u8"\\1\u0bcc"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace ta_tamil99
diff --git a/ash/services/ime/public/cpp/rulebased/def/te_phone.cc b/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
index 58bc256..36e5a86 100644
--- a/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/te_phone.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/te_phone.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace te_phone {
 
@@ -302,7 +302,7 @@
                              u8"\u0964",
                              u8"\u0964\u001d?\\|",
                              u8"\u0965"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = "C|c";
 
 }  // namespace te_phone
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc b/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
index d34ac83..8f3eb72 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/vi_tcvn.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/vi_tcvn.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace vi_tcvn {
 
@@ -398,7 +398,7 @@
                              u8"\u1ef8",
                              u8"y\u0303",
                              u8"\u1ef9"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace vi_tcvn
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc b/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
index 174030c..c712acf 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/vi_telex.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/vi_telex.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace vi_telex {
 
@@ -113,7 +113,7 @@
     u8"\u0103\u00e2\u00ea\u00f4\u01a1\u01b0\u0102\u00c2\u00ca\u00d4\u01a0\u01af"
     u8"])\u001d?([a-zA-Z])",
     u8"\\2\\1\\3"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace vi_telex
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc b/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
index 1a1304b..a541343 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/vi_viqr.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/vi_viqr.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace vi_viqr {
 
@@ -20,7 +20,7 @@
     u8"\\\\\\'", u8"'",      u8"\\\\\\?", u8"?",      u8"\\\\\\~", u8"~",
     u8"\\\\\\.", u8".",      u8"\\`",     u8"\u0300", u8"\\'",     u8"\u0301",
     u8"\\?",     u8"\u0309", u8"\\~",     u8"\u0303", u8"\\.",     u8"\u0323"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace vi_viqr
diff --git a/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc b/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
index 687346d..17e6e4b 100644
--- a/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
+++ b/ash/services/ime/public/cpp/rulebased/def/vi_vni.cc
@@ -4,7 +4,7 @@
 
 #include "ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace vi_vni {
 
@@ -81,7 +81,7 @@
     u8"\u0103\u00e2\u00ea\u00f4\u01a1\u01b0\u0102\u00c2\u00ca\u00d4\u01a0\u01af"
     u8"])\u001d?([a-zA-Z])",
     u8"\\2\\1\\3"};
-const unsigned int kTransformsLen = base::size(kTransforms);
+const unsigned int kTransformsLen = std::size(kTransforms);
 const char* kHistoryPrune = nullptr;
 
 }  // namespace vi_vni
diff --git a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc b/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
index 9b3d6a4..3b63488 100644
--- a/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
+++ b/ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.cc
@@ -9,7 +9,6 @@
 #include "ash/services/ime/public/cpp/rulebased/engine.h"
 #include "ash/services/ime/public/cpp/rulebased/rulebased_fuzzer.pb.h"
 #include "ash/services/ime/public/cpp/rulebased/rules_data.h"
-#include "base/cxx17_backports.h"
 #include "testing/libfuzzer/proto/lpm_interface.h"
 
 namespace rulebased = chromeos::ime::rulebased;
@@ -83,7 +82,7 @@
     "vi_vni",
 };
 
-static rulebased::Engine engines[base::size(kEngineIds)];
+static rulebased::Engine engines[std::size(kEngineIds)];
 
 uint8_t GetModifierFromKeyEvent(const rulebased_fuzzer::KeyEvent& e) {
   uint8_t modifiers = 0;
diff --git a/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc b/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
index 2f8fb38..99ea83e 100644
--- a/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
+++ b/ash/services/ime/public/cpp/rulebased/rulebased_unittest.cc
@@ -8,7 +8,6 @@
 #include "ash/services/ime/public/cpp/rulebased/engine.h"
 #include "ash/services/ime/public/cpp/rulebased/rules_data.h"
 #include "ash/services/ime/public/mojom/input_method.mojom-shared.h"
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -165,7 +164,7 @@
   const char* transforms[] = {
       u8"a", u8"x", u8"x\u001dAA", u8"X", u8"(\\w)(\\w)[<>]", u8"\\2\\1"};
   auto data = rulebased::RulesData::Create(us::kKeyMap, false, transforms,
-                                           base::size(transforms), nullptr);
+                                           std::size(transforms), nullptr);
   std::string transformed;
   bool res = data->Transform("..", -1, "b", &transformed);
   EXPECT_FALSE(res);
@@ -185,7 +184,7 @@
       u8"10",        u8"A",           u8"([aeou])\u001d?`",
       u8"\\1\u0300", u8"[\\[\\]]{2}", u8"ʘ"};
   auto data = rulebased::RulesData::Create(us::kKeyMap, false, transforms,
-                                           base::size(transforms), nullptr);
+                                           std::size(transforms), nullptr);
   bool res = data->PredictTransform("..x", -1);
   EXPECT_FALSE(res);
   res = data->PredictTransform(u8"..0", -1);
diff --git a/ash/services/ime/public/cpp/rulebased/rules_data.cc b/ash/services/ime/public/cpp/rulebased/rules_data.cc
index 59d23483..dbabe72 100644
--- a/ash/services/ime/public/cpp/rulebased/rules_data.cc
+++ b/ash/services/ime/public/cpp/rulebased/rules_data.cc
@@ -39,7 +39,6 @@
 #include "ash/services/ime/public/cpp/rulebased/def/vi_vni.h"
 #include "ash/services/ime/public/mojom/input_method.mojom-shared.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "third_party/re2/src/re2/re2.h"
 
@@ -206,7 +205,7 @@
 // Parses the raw key mappings and generate a KeyMap instance.
 KeyMap ParseKeyMap(const char** raw_key_map, bool is_102) {
   const mojom::DomCode* std_keys = is_102 ? k102Keys : k101Keys;
-  size_t nkeys = is_102 ? base::size(k102Keys) : base::size(k101Keys);
+  size_t nkeys = is_102 ? std::size(k102Keys) : std::size(k101Keys);
   KeyMap key_map;
   for (size_t i = 0; i < nkeys; ++i)
     key_map[std_keys[i]] = raw_key_map[i];
diff --git a/ash/shelf/shelf_app_button.cc b/ash/shelf/shelf_app_button.cc
index b7519d8..11187a78 100644
--- a/ash/shelf/shelf_app_button.cc
+++ b/ash/shelf/shelf_app_button.cc
@@ -17,7 +17,6 @@
 #include "ash/style/default_colors.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/time.h"
@@ -284,7 +283,7 @@
       gfx::ShadowValue(gfx::Vector2d(0, 3), 1, SkColorSetARGB(0x1A, 0, 0, 0)),
       gfx::ShadowValue(gfx::Vector2d(0, 0), 1, SkColorSetARGB(0x54, 0, 0, 0)),
   };
-  icon_shadows_.assign(kShadows, kShadows + base::size(kShadows));
+  icon_shadows_.assign(kShadows, kShadows + std::size(kShadows));
 
   // TODO(crbug.com/1218186): Remove this, this is in place temporarily to be
   // able to submit accessibility checks. This crashes if fetching a11y node
diff --git a/ash/shell.cc b/ash/shell.cc
index 1fb62d5..1f07e60a 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -518,6 +518,16 @@
   shell_observers_.RemoveObserver(observer);
 }
 
+void Shell::ShutdownEventDispatch() {
+  for (aura::Window* root : GetAllRootWindows())
+    aura::client::SetDragDropClient(root, nullptr);
+
+  // Stop dispatching events (e.g. synthesized mouse exits from window close).
+  // https://crbug.com/874156
+  for (RootWindowController* rwc : GetAllRootWindowControllers())
+    rwc->GetHost()->dispatcher()->Shutdown();
+}
+
 void Shell::UpdateAfterLoginStatusChange(LoginStatus status) {
   for (auto* root_window_controller : GetAllRootWindowControllers())
     root_window_controller->UpdateAfterLoginStatusChange(status);
@@ -724,8 +734,6 @@
   logout_confirmation_controller_.reset();
 
   // Drag-and-drop must be canceled prior to close all windows.
-  for (aura::Window* root : GetAllRootWindows())
-    aura::client::SetDragDropClient(root, nullptr);
   drag_drop_controller_.reset();
 
   // Controllers who have WindowObserver added must be deleted
@@ -748,11 +756,6 @@
   window_cycle_controller_.reset();
   overview_controller_.reset();
 
-  // Stop dispatching events (e.g. synthesized mouse exits from window close).
-  // https://crbug.com/874156
-  for (RootWindowController* rwc : GetAllRootWindowControllers())
-    rwc->GetHost()->dispatcher()->Shutdown();
-
   // Close all widgets (including the shelf) and destroy all window containers.
   CloseAllRootWindowChildWindows();
 
diff --git a/ash/shell.h b/ash/shell.h
index 155381a..9e20e2c 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -655,6 +655,10 @@
   void AddShellObserver(ShellObserver* observer);
   void RemoveShellObserver(ShellObserver* observer);
 
+  // Disables event dispatch during shutdown so that Window events no longer
+  // propagate as they are being closed/destroyed.
+  void ShutdownEventDispatch();
+
   // Called when the login status changes.
   // TODO(oshima): Investigate if we can merge this and |OnLoginStateChanged|.
   void UpdateAfterLoginStatusChange(LoginStatus status);
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc
index 3623fe8..3432469 100644
--- a/ash/style/ash_color_provider.cc
+++ b/ash/style/ash_color_provider.cc
@@ -15,7 +15,6 @@
 #include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/prefs/pref_change_registrar.h"
@@ -324,7 +323,7 @@
                                                   bool inverted) const {
   constexpr int kAlphas[] = {kAlpha20, kAlpha40, kAlpha60,
                              kAlpha80, kAlpha90, kAlpha95};
-  DCHECK_LT(static_cast<size_t>(type), base::size(kAlphas));
+  DCHECK_LT(static_cast<size_t>(type), std::size(kAlphas));
   return SkColorSetA(
       inverted ? GetInvertedBackgroundColor() : GetBackgroundColor(),
       kAlphas[static_cast<int>(type)]);
@@ -334,7 +333,7 @@
                                                 bool inverted) const {
   constexpr int kAlphas[] = {kAlpha20, kAlpha40, kAlpha60, kAlpha80,
                              kAlpha90, kAlpha95, 0xFF};
-  DCHECK_LT(static_cast<size_t>(type), base::size(kAlphas));
+  DCHECK_LT(static_cast<size_t>(type), std::size(kAlphas));
   return SkColorSetA(
       inverted ? GetInvertedBackgroundColor() : GetBackgroundColor(),
       kAlphas[static_cast<int>(type)]);
diff --git a/ash/system/accessibility/floating_accessibility_controller_unittest.cc b/ash/system/accessibility/floating_accessibility_controller_unittest.cc
index 86da1ad..f076d21 100644
--- a/ash/system/accessibility/floating_accessibility_controller_unittest.cc
+++ b/ash/system/accessibility/floating_accessibility_controller_unittest.cc
@@ -427,7 +427,7 @@
 
   {
     base::RunLoop loop_enable;
-    SetOnLayoutCallback(base::BarrierClosure(base::size(kFeatureButtons),
+    SetOnLayoutCallback(base::BarrierClosure(std::size(kFeatureButtons),
                                              loop_enable.QuitClosure()));
     // Enable all features.
     for (FeatureWithButton feature : kFeatureButtons)
@@ -441,7 +441,7 @@
   EXPECT_TRUE(window_bounds.Contains(GetMenuViewBounds()));
   {
     base::RunLoop loop_disable;
-    SetOnLayoutCallback(base::BarrierClosure(base::size(kFeatureButtons),
+    SetOnLayoutCallback(base::BarrierClosure(std::size(kFeatureButtons),
                                              loop_disable.QuitClosure()));
     // Enable all features.
     // Dicable all features.
diff --git a/ash/system/accessibility/select_to_speak/select_to_speak_speed_view.cc b/ash/system/accessibility/select_to_speak/select_to_speak_speed_view.cc
index 5884f04..7b5170f 100644
--- a/ash/system/accessibility/select_to_speak/select_to_speak_speed_view.cc
+++ b/ash/system/accessibility/select_to_speak/select_to_speak_speed_view.cc
@@ -39,7 +39,7 @@
 void SelectToSpeakSpeedView::SetInitialSpeechRate(double initial_speech_rate) {
   RemoveAllChildViews();
 
-  for (size_t i = 0; i < base::size(kSelectToSpeakSpeechRates); i++) {
+  for (size_t i = 0; i < std::size(kSelectToSpeakSpeechRates); i++) {
     double option_speed = kSelectToSpeakSpeechRates[i];
     bool is_selected = option_speed == initial_speech_rate;
     // Add 1 to the index, because view IDs cannot be 0.
@@ -60,7 +60,7 @@
 
 void SelectToSpeakSpeedView::OnViewClicked(views::View* sender) {
   unsigned int speed_index = sender->GetID() - 1;
-  if (speed_index >= 0 && speed_index < base::size(kSelectToSpeakSpeechRates)) {
+  if (speed_index >= 0 && speed_index < std::size(kSelectToSpeakSpeechRates)) {
     delegate_->OnSpeechRateSelected(kSelectToSpeakSpeechRates[speed_index]);
   }
 }
diff --git a/ash/system/audio/unified_volume_view.cc b/ash/system/audio/unified_volume_view.cc
index 8be46c2..b3b144e 100644
--- a/ash/system/audio/unified_volume_view.cc
+++ b/ash/system/audio/unified_volume_view.cc
@@ -12,7 +12,6 @@
 #include "ash/style/ash_color_provider.h"
 #include "ash/system/tray/tray_popup_utils.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "components/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -44,7 +43,7 @@
 };
 
 // The maximum index of kVolumeLevelIcons.
-constexpr int kVolumeLevels = base::size(kVolumeLevelIcons) - 1;
+constexpr int kVolumeLevels = std::size(kVolumeLevelIcons) - 1;
 
 // Get vector icon reference that corresponds to the given volume level. |level|
 // is between 0.0 to 1.0.
diff --git a/ash/system/holding_space/holding_space_animation_registry_unittest.cc b/ash/system/holding_space/holding_space_animation_registry_unittest.cc
index 94ee4ef..d859dd4f 100644
--- a/ash/system/holding_space/holding_space_animation_registry_unittest.cc
+++ b/ash/system/holding_space/holding_space_animation_registry_unittest.cc
@@ -241,7 +241,7 @@
           item_1, future.GetCallback()),
       registry()->AddProgressRingAnimationChangedCallbackForKey(
           item_2, future.GetCallback())};
-  for (size_t i = 0u; i < base::size(subscriptions); ++i)
+  for (size_t i = 0u; i < std::size(subscriptions); ++i)
     EXPECT_EQ(future.Take(), nullptr);
 
   // Verify animation `registry()` state.
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index 468e20f..128ebb6 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -619,6 +619,9 @@
           message_center_style::kMaxGroupedNotificationsInCollapsedState ||
       IsExpanded());
   notification_view->SetGroupedChildExpanded(IsExpanded());
+  notification_view->set_scroller(
+      scroller() ? scroller() : grouped_notifications_scroll_view_);
+
   grouped_notifications_container_->AddChildViewAt(
       std::move(notification_view),
       newest_first ? 0 : grouped_notifications_container_->children().size());
@@ -645,6 +648,9 @@
             message_center_style::kMaxGroupedNotificationsInCollapsedState ||
         IsExpanded());
     notification_view->SetGroupedChildExpanded(IsExpanded());
+    notification_view->set_scroller(
+        scroller() ? scroller() : grouped_notifications_scroll_view_);
+
     grouped_notifications_container_->AddChildViewAt(
         std::move(notification_view), 0);
   }
diff --git a/ash/system/night_light/night_light_controller_impl.cc b/ash/system/night_light/night_light_controller_impl.cc
index d29a946..b36593b 100644
--- a/ash/system/night_light/night_light_controller_impl.cc
+++ b/ash/system/night_light/night_light_controller_impl.cc
@@ -475,7 +475,7 @@
                 {4200, 5500}, {4800, 5800}, {5300, 6000},
                 {6000, 6400}, {7000, 6800}, {8000, 7500}};
 
-  constexpr size_t kTableSize = base::size(kTable);
+  constexpr size_t kTableSize = std::size(kTable);
   // We clamp to a range defined by the minimum possible input value and the
   // maximum. Given that the interval kTable[i].input_temperature,
   // kTable[i+1].input_temperature exclude the upper bound, we clamp it to the
diff --git a/ash/system/progress_indicator/progress_ring_pulse_animation.cc b/ash/system/progress_indicator/progress_ring_pulse_animation.cc
index 23e9023..32e804ad 100644
--- a/ash/system/progress_indicator/progress_ring_pulse_animation.cc
+++ b/ash/system/progress_indicator/progress_ring_pulse_animation.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/progress_indicator/progress_ring_pulse_animation.h"
 
-#include "base/cxx17_backports.h"
 #include "base/dcheck_is_on.h"
 #include "base/notreached.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -45,7 +44,7 @@
                             base::Milliseconds(kAnimationDurationInMs),
                             /*is_cyclic=*/false) {
 #if DCHECK_IS_ON()
-  constexpr size_t kAnimationKeyFramesCount = base::size(kAnimationKeyFrames);
+  constexpr size_t kAnimationKeyFramesCount = std::size(kAnimationKeyFrames);
   DCHECK_GE(kAnimationKeyFramesCount, 2u);
   for (size_t i = 0u; i < kAnimationKeyFramesCount; ++i) {
     if (i == 0u) {
@@ -76,7 +75,7 @@
 
   // Loop over all animation key frames until the correct key frames for the
   // current animation `fraction` are found.
-  for (size_t i = 1u; i < base::size(kAnimationKeyFrames); ++i) {
+  for (size_t i = 1u; i < std::size(kAnimationKeyFrames); ++i) {
     if (fraction > kAnimationKeyFrames[i].fraction)
       continue;
 
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 6dba837..25f5ad6 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -149,6 +149,9 @@
   // owns, so shut the test helper down first.
   app_list_test_helper_.reset();
 
+  // Stop event dispatch like we do in ChromeBrowserMainExtraPartsAsh.
+  Shell::Get()->ShutdownEventDispatch();
+
   Shell::DeleteInstance();
   // Suspend the tear down until all resources are returned via
   // CompositorFrameSinkClient::ReclaimResources()
diff --git a/ash/touch/touch_hud_debug.cc b/ash/touch/touch_hud_debug.cc
index b8fab522..94e26db 100644
--- a/ash/touch/touch_hud_debug.cc
+++ b/ash/touch/touch_hud_debug.cc
@@ -45,7 +45,7 @@
     SkColorSetRGB(0xFF, 0xDE, 0xAD),
 };
 const int kAlpha = 0x60;
-const int kMaxPaths = base::size(kColors);
+const int kMaxPaths = std::size(kColors);
 const int kReducedScale = 10;
 
 const char* GetTouchEventLabel(ui::EventType type) {
diff --git a/ash/touch/touch_hud_renderer.cc b/ash/touch/touch_hud_renderer.cc
index f19afd5..3184028 100644
--- a/ash/touch/touch_hud_renderer.cc
+++ b/ash/touch/touch_hud_renderer.cc
@@ -86,7 +86,7 @@
 
     fill_flags.setShader(cc::PaintShader::MakeRadialGradient(
         gfx::PointToSkPoint(center), SkIntToScalar(kPointRadius),
-        gradient_colors, gradient_pos, base::size(gradient_colors),
+        gradient_colors, gradient_pos, std::size(gradient_colors),
         SkTileMode::kMirror));
     canvas->DrawCircle(center, SkIntToScalar(kPointRadius), fill_flags);
 
diff --git a/ash/wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc b/ash/wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc
index 84c5d91..b56b8f62 100644
--- a/ash/wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc
+++ b/ash/wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "ash/public/cpp/wallpaper/wallpaper_types.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer_observer.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread.h"
@@ -109,7 +108,7 @@
       WALLPAPER_LAYOUT_CENTER, WALLPAPER_LAYOUT_CENTER_CROPPED,
       WALLPAPER_LAYOUT_STRETCH, WALLPAPER_LAYOUT_TILE,
   };
-  const int length = base::size(layouts);
+  const int length = std::size(layouts);
 
   for (int i = 0; i < length; i++) {
     WallpaperLayout layout = layouts[i];
diff --git a/ash/webui/BUILD.gn b/ash/webui/BUILD.gn
index 0710b94..0309ab5 100644
--- a/ash/webui/BUILD.gn
+++ b/ash/webui/BUILD.gn
@@ -59,6 +59,7 @@
 group("closure_compile") {
   testonly = true
   deps = [
+    "//ash/webui/common:closure_compile",
     "//ash/webui/connectivity_diagnostics:closure_compile",
     "//ash/webui/diagnostics_ui:closure_compile",
     "//ash/webui/eche_app_ui:closure_compile",
diff --git a/ash/webui/color_internals/color_internals_ui.cc b/ash/webui/color_internals/color_internals_ui.cc
index ae37002..e551cf91 100644
--- a/ash/webui/color_internals/color_internals_ui.cc
+++ b/ash/webui/color_internals/color_internals_ui.cc
@@ -15,15 +15,14 @@
 
 ColorInternalsUI::ColorInternalsUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
-  auto data_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIColorInternalsHost));
+  content::WebUIDataSource* data_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIColorInternalsHost);
 
   data_source->AddResourcePath("", IDR_ASH_COLOR_INTERNALS_INDEX_HTML);
   data_source->AddResourcePaths(base::make_span(
       kAshColorInternalsResources, kAshColorInternalsResourcesSize));
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, data_source.release());
 }
 
 ColorInternalsUI::~ColorInternalsUI() = default;
diff --git a/ash/webui/common/BUILD.gn b/ash/webui/common/BUILD.gn
new file mode 100644
index 0000000..eb28305
--- /dev/null
+++ b/ash/webui/common/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/chromeos/ui_mode.gni")
+
+assert(is_chromeos_ash, "Non-ChromeOS builds cannot depend on //ash")
+
+static_library("common") {
+}
+
+group("closure_compile") {
+  deps = [ "resources:closure_compile_module" ]
+}
diff --git a/ash/webui/common/resources/BUILD.gn b/ash/webui/common/resources/BUILD.gn
index 0a45dbe..dd640be 100644
--- a/ash/webui/common/resources/BUILD.gn
+++ b/ash/webui/common/resources/BUILD.gn
@@ -30,6 +30,7 @@
   input_files = [
     "fake_observables.js",
     "fake_method_resolver.js",
+    "mojo_utils.js",
   ]
   input_files_base_dir = rebase_path(".", "//")
   deps = [ ":preprocess_generated" ]
@@ -47,6 +48,7 @@
     ":keyboard_diagram",
     ":keyboard_icons",
     ":keyboard_key",
+    ":mojo_utils",
     ":navigation_selector",
     ":navigation_view_panel",
     ":page_toolbar",
@@ -81,6 +83,10 @@
   ]
 }
 
+js_library("mojo_utils") {
+  deps = [ "//ash/webui/common/mojom:mojom_js_library_for_compile" ]
+}
+
 js_library("navigation_selector") {
   deps = [
     ":navigation_icons",
diff --git a/ash/webui/common/resources/mojo_utils.js b/ash/webui/common/resources/mojo_utils.js
new file mode 100644
index 0000000..ebdaf35
--- /dev/null
+++ b/ash/webui/common/resources/mojo_utils.js
@@ -0,0 +1,29 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '//resources/mojo/mojo/public/js/mojo_bindings_lite.js';
+import '//resources/mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js';
+import '//resources/mojo/mojo/public/mojom/base/string16.mojom-lite.js';
+
+/**
+ * Converts a JS string to mojo_base::mojom::String16 object.
+ * @param {string} str
+ * @return {!mojoBase.mojom.String16}
+ */
+export function stringToMojoString16(str) {
+  const arr = [];
+  for (let i = 0; i < str.length; i++) {
+    arr[i] = str.charCodeAt(i);
+  }
+  return {data: arr};
+}
+
+/**
+ * Converts mojo_base::mojom::String16 to a JS string.
+ * @param {!mojoBase.mojom.String16} str16
+ * @return {string}
+ */
+export function mojoString16ToString(str16) {
+  return str16.data.map(ch => String.fromCodePoint(ch)).join('');
+}
diff --git a/ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.cc b/ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.cc
index 62dbb0dc..3810b3e 100644
--- a/ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.cc
+++ b/ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.cc
@@ -104,8 +104,9 @@
   DCHECK(bind_network_diagnostics_service_callback_);
   DCHECK(bind_network_health_service_callback_);
   DCHECK(send_feedback_report_callback);
-  content::WebUIDataSource* source =
-      content::WebUIDataSource::Create(kChromeUIConnectivityDiagnosticsHost);
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      web_ui->GetWebContents()->GetBrowserContext(),
+      kChromeUIConnectivityDiagnosticsHost);
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -134,9 +135,6 @@
                              IDS_CONNECTIVITY_DIAGNOSTICS_SEND_FEEDBACK);
   chromeos::network_diagnostics::AddResources(source);
   chromeos::network_health::AddResources(source);
-
-  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                source);
 }
 
 ConnectivityDiagnosticsUI::~ConnectivityDiagnosticsUI() = default;
diff --git a/ash/webui/demo_mode_app_ui/demo_mode_app_ui.cc b/ash/webui/demo_mode_app_ui/demo_mode_app_ui.cc
index 0cce03c..842b9f8 100644
--- a/ash/webui/demo_mode_app_ui/demo_mode_app_ui.cc
+++ b/ash/webui/demo_mode_app_ui/demo_mode_app_ui.cc
@@ -18,7 +18,9 @@
 DemoModeAppUI::DemoModeAppUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
   content::WebUIDataSource* html_source =
-      content::WebUIDataSource::Create(kChromeUIDemoModeAppHost);
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIDemoModeAppHost);
 
   // Add required resources.
   for (size_t i = 0; i < kAshDemoModeAppResourcesSize; ++i) {
@@ -27,9 +29,6 @@
   }
 
   html_source->SetDefaultResource(IDR_ASH_DEMO_MODE_APP_DEMO_MODE_APP_HTML);
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, html_source);
 }
 
 DemoModeAppUI::~DemoModeAppUI() = default;
diff --git a/ash/webui/diagnostics_ui/backend/routine_properties.cc b/ash/webui/diagnostics_ui/backend/routine_properties.cc
index 5567e74..bff0f80 100644
--- a/ash/webui/diagnostics_ui/backend/routine_properties.cc
+++ b/ash/webui/diagnostics_ui/backend/routine_properties.cc
@@ -59,7 +59,7 @@
      /*duration_seconds=*/1, healthd::DiagnosticRoutineEnum::kArcDnsResolution},
 };
 
-const size_t kRoutinePropertiesLength = base::size(kRoutineProperties);
+const size_t kRoutinePropertiesLength = std::size(kRoutineProperties);
 
 static_assert(kRoutinePropertiesLength ==
                   static_cast<size_t>(mojom::RoutineType::kMaxValue) + 1,
diff --git a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.cc b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.cc
index d0bfc307..73b7407b 100644
--- a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.cc
@@ -94,7 +94,7 @@
 
 // Message Handlers:
 void DiagnosticsMetricsMessageHandler::HandleRecordNavigation(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   DCHECK_EQ(2u, args.size());
   DCHECK_NE(args[0], args[1]);
   const NavigationView from_view = ConvertToNavigationView(args[0]);
diff --git a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.h b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.h
index 9cff101..0a988e7d 100644
--- a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.h
+++ b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler.h
@@ -45,7 +45,7 @@
 
  private:
   // Records navigation events between screens within Diagnostics App.
-  void HandleRecordNavigation(base::Value::ConstListView args);
+  void HandleRecordNavigation(const base::Value::List& args);
 
   NavigationView current_view_;
   base::Time navigation_started_;
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc
index 7e80725..5c9af21 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -26,7 +26,6 @@
 #include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_piece_forward.h"
 #include "base/strings/string_util.h"
@@ -374,8 +373,10 @@
     HoldingSpaceClient* holding_space_client,
     const base::FilePath& log_directory_path)
     : ui::MojoWebDialogUI(web_ui) {
-  auto html_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIDiagnosticsAppHost));
+  content::WebUIDataSource* html_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIDiagnosticsAppHost);
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -383,8 +384,7 @@
 
   const auto resources = base::make_span(kAshDiagnosticsAppResources,
                                          kAshDiagnosticsAppResourcesSize);
-  SetUpWebUIDataSource(html_source.get(), resources,
-                       IDR_DIAGNOSTICS_APP_INDEX_HTML);
+  SetUpWebUIDataSource(html_source, resources, IDR_DIAGNOSTICS_APP_INDEX_HTML);
 
   SetUpPluralStringHandler(web_ui);
 
@@ -394,12 +394,10 @@
       session_log_handler.get(), web_ui);
   web_ui->AddMessageHandler(std::move(session_log_handler));
 
-  AddDiagnosticsStrings(html_source.get());
+  AddDiagnosticsStrings(html_source);
   // Add localized strings required for network-icon.
-  ui::network_element::AddLocalizedStrings(html_source.get());
-  ui::network_element::AddOncLocalizedStrings(html_source.get());
-  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                html_source.release());
+  ui::network_element::AddLocalizedStrings(html_source);
+  ui::network_element::AddOncLocalizedStrings(html_source);
 
   // Configure SFUL metrics.
   diagnostics_metrics_ =
diff --git a/ash/webui/eche_app_ui/eche_app_ui.cc b/ash/webui/eche_app_ui/eche_app_ui.cc
index db853dce..32d39a4 100644
--- a/ash/webui/eche_app_ui/eche_app_ui.cc
+++ b/ash/webui/eche_app_ui/eche_app_ui.cc
@@ -30,8 +30,10 @@
       bind_system_info_callback_(std::move(system_info_callback)),
       bind_generator_callback_(std::move(generator_callback)),
       bind_notification_callback_(std::move(notification_callback)) {
-  auto html_source =
-      base::WrapUnique(content::WebUIDataSource::Create(kChromeUIEcheAppHost));
+  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
+  content::WebUIDataSource* html_source =
+      content::WebUIDataSource::CreateAndAdd(browser_context,
+                                             kChromeUIEcheAppHost);
 
   html_source->AddResourcePath("", IDR_ASH_ECHE_INDEX_HTML);
   html_source->AddResourcePath("system_assets/app_icon_32.png",
@@ -66,8 +68,6 @@
   std::string csp = std::string("frame-src ") + kChromeUIEcheAppGuestURL + ";";
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::FrameSrc, csp);
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, html_source.release());
 
   // Add ability to request chrome-untrusted: URLs.
   web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
diff --git a/ash/webui/eche_app_ui/untrusted_eche_app_ui.cc b/ash/webui/eche_app_ui/untrusted_eche_app_ui.cc
index 6b2df83b..5b134f2 100644
--- a/ash/webui/eche_app_ui/untrusted_eche_app_ui.cc
+++ b/ash/webui/eche_app_ui/untrusted_eche_app_ui.cc
@@ -32,7 +32,9 @@
 UntrustedEcheAppUI::UntrustedEcheAppUI(content::WebUI* web_ui)
     : ui::UntrustedWebUIController(web_ui) {
   content::WebUIDataSource* html_source =
-      content::WebUIDataSource::Create(kChromeUIEcheAppGuestURL);
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIEcheAppGuestURL);
 
   html_source->AddResourcePath("untrusted_index.html",
                                IDR_ASH_ECHE_UNTRUSTED_INDEX_HTML);
@@ -58,9 +60,6 @@
   // TODO(b/194964287): Audit and tighten CSP.
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::DefaultSrc, "");
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, html_source);
 }
 
 UntrustedEcheAppUI::~UntrustedEcheAppUI() = default;
diff --git a/ash/webui/file_manager/file_manager_untrusted_ui.cc b/ash/webui/file_manager/file_manager_untrusted_ui.cc
index 7965e72..428eb90bf 100644
--- a/ash/webui/file_manager/file_manager_untrusted_ui.cc
+++ b/ash/webui/file_manager/file_manager_untrusted_ui.cc
@@ -30,7 +30,9 @@
 FileManagerUntrustedUI::FileManagerUntrustedUI(content::WebUI* web_ui)
     : ui::UntrustedWebUIController(web_ui) {
   content::WebUIDataSource* untrusted_source =
-      content::WebUIDataSource::Create(kChromeUIFileManagerUntrustedURL);
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIFileManagerUntrustedURL);
 
   untrusted_source->AddResourcePaths(base::make_span(
       kFileManagerUntrustedResources, kFileManagerUntrustedResourcesSize));
@@ -51,9 +53,6 @@
   untrusted_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::StyleSrc,
       "style-src 'unsafe-inline' 'self';");
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, untrusted_source);
 }
 
 FileManagerUntrustedUI::~FileManagerUntrustedUI() = default;
diff --git a/ash/webui/file_manager/resource_loader_unittest.cc b/ash/webui/file_manager/resource_loader_unittest.cc
index 99d709b4..6d1b442 100644
--- a/ash/webui/file_manager/resource_loader_unittest.cc
+++ b/ash/webui/file_manager/resource_loader_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/webui/file_manager/resource_loader.h"
 
-#include "base/cxx17_backports.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_web_ui_data_source.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -36,7 +35,7 @@
       {"file_manager/untrusted_resources/files_img_content.css", 11},
   };
 
-  const size_t kTestResourcesSize = base::size(kTestResources);
+  const size_t kTestResourcesSize = std::size(kTestResources);
 
   AddFilesAppResources(source()->GetWebUIDataSource(), kTestResources,
                        kTestResourcesSize);
diff --git a/ash/webui/firmware_update_ui/firmware_update_app_ui.cc b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc
index a63417f3..fb2adeb 100644
--- a/ash/webui/firmware_update_ui/firmware_update_app_ui.cc
+++ b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc
@@ -72,8 +72,9 @@
 
 FirmwareUpdateAppUI::FirmwareUpdateAppUI(content::WebUI* web_ui)
     : ui::MojoWebDialogUI(web_ui) {
-  auto source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIFirmwareUpdateAppHost));
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      web_ui->GetWebContents()->GetBrowserContext(),
+      kChromeUIFirmwareUpdateAppHost);
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -81,13 +82,10 @@
 
   const auto resources = base::make_span(kAshFirmwareUpdateAppResources,
                                          kAshFirmwareUpdateAppResourcesSize);
-  SetUpWebUIDataSource(source.get(), resources,
+  SetUpWebUIDataSource(source, resources,
                        IDR_ASH_FIRMWARE_UPDATE_APP_INDEX_HTML);
 
-  AddFirmwareUpdateAppStrings(source.get());
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source.release());
+  AddFirmwareUpdateAppStrings(source);
 }
 
 FirmwareUpdateAppUI::~FirmwareUpdateAppUI() = default;
diff --git a/ash/webui/multidevice_debug/proximity_auth_ui.cc b/ash/webui/multidevice_debug/proximity_auth_ui.cc
index e10699c..5ac591dc 100644
--- a/ash/webui/multidevice_debug/proximity_auth_ui.cc
+++ b/ash/webui/multidevice_debug/proximity_auth_ui.cc
@@ -26,8 +26,9 @@
     MultiDeviceSetupBinder multidevice_setup_binder)
     : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */),
       multidevice_setup_binder_(std::move(multidevice_setup_binder)) {
-  content::WebUIDataSource* source =
-      content::WebUIDataSource::Create(kChromeUIProximityAuthHost);
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      web_ui->GetWebContents()->GetBrowserContext(),
+      kChromeUIProximityAuthHost);
   source->SetDefaultResource(IDR_MULTIDEVICE_DEBUG_INDEX_HTML);
   source->AddResourcePath("common.css", IDR_MULTIDEVICE_DEBUG_COMMON_CSS);
   source->AddResourcePath("webui.js", IDR_MULTIDEVICE_DEBUG_WEBUI_JS);
@@ -39,9 +40,6 @@
   source->AddResourcePath("proximity_auth.js",
                           IDR_MULTIDEVICE_DEBUG_PROXIMITY_AUTH_JS);
 
-  content::BrowserContext* browser_context =
-      web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source);
   web_ui->AddMessageHandler(
       std::make_unique<ProximityAuthWebUIHandler>(device_sync_client));
 }
diff --git a/ash/webui/os_feedback_ui/os_feedback_ui.cc b/ash/webui/os_feedback_ui/os_feedback_ui.cc
index 19a7f28..633f248f8 100644
--- a/ash/webui/os_feedback_ui/os_feedback_ui.cc
+++ b/ash/webui/os_feedback_ui/os_feedback_ui.cc
@@ -12,7 +12,6 @@
 #include "ash/webui/os_feedback_ui/backend/help_content_provider.h"
 #include "ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom.h"
 #include "ash/webui/os_feedback_ui/url_constants.h"
-#include "base/memory/ptr_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -41,8 +40,9 @@
 
 OSFeedbackUI::OSFeedbackUI(content::WebUI* web_ui)
     : MojoWebUIController(web_ui) {
-  auto source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIOSFeedbackHost));
+  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      browser_context, kChromeUIOSFeedbackHost);
 
   // Add ability to request chrome-untrusted://os-feedback URLs.
   web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
@@ -60,10 +60,7 @@
 
   const auto resources =
       base::make_span(kAshOsFeedbackResources, kAshOsFeedbackResourcesSize);
-  SetUpWebUIDataSource(source.get(), resources, IDR_ASH_OS_FEEDBACK_INDEX_HTML);
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source.release());
+  SetUpWebUIDataSource(source, resources, IDR_ASH_OS_FEEDBACK_INDEX_HTML);
 
   // Register common permissions for chrome-untrusted:// pages.
   // TODO(https://crbug.com/1113568): Remove this after common permissions are
diff --git a/ash/webui/os_feedback_ui/os_feedback_untrusted_ui.cc b/ash/webui/os_feedback_ui/os_feedback_untrusted_ui.cc
index d69e3159..3ef8d786 100644
--- a/ash/webui/os_feedback_ui/os_feedback_untrusted_ui.cc
+++ b/ash/webui/os_feedback_ui/os_feedback_untrusted_ui.cc
@@ -11,7 +11,6 @@
 #include "ash/webui/grit/ash_os_feedback_untrusted_resources_map.h"
 #include "ash/webui/os_feedback_ui/url_constants.h"
 #include "base/containers/span.h"
-#include "base/memory/ptr_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -34,8 +33,10 @@
 
 OsFeedbackUntrustedUI::OsFeedbackUntrustedUI(content::WebUI* web_ui)
     : ui::UntrustedWebUIController(web_ui) {
-  auto untrusted_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIOSFeedbackUntrustedUrl));
+  content::WebUIDataSource* untrusted_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIOSFeedbackUntrustedUrl);
 
   untrusted_source->AddResourcePaths(base::make_span(
       kAshOsFeedbackUntrustedResources, kAshOsFeedbackUntrustedResourcesSize));
@@ -65,9 +66,6 @@
   untrusted_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src 'self' chrome-untrusted://resources;");
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, untrusted_source.release());
 }
 
 OsFeedbackUntrustedUI::~OsFeedbackUntrustedUI() = default;
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc
index 8017cf8..9372e84 100644
--- a/ash/webui/personalization_app/personalization_app_ui.cc
+++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -171,8 +171,9 @@
       wallpaper_provider_(std::move(wallpaper_provider)) {
   DCHECK(wallpaper_provider_);
 
-  std::unique_ptr<content::WebUIDataSource> source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIPersonalizationAppHost));
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      web_ui->GetWebContents()->GetBrowserContext(),
+      kChromeUIPersonalizationAppHost);
 
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
@@ -189,12 +190,9 @@
   // TODO(crbug.com/1098690): Trusted Type Polymer
   source->DisableTrustedTypesCSP();
 
-  AddResources(source.get());
-  AddStrings(source.get());
-  AddBooleans(source.get());
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source.release());
+  AddResources(source);
+  AddStrings(source);
+  AddBooleans(source);
 }
 
 PersonalizationAppUI::~PersonalizationAppUI() = default;
diff --git a/ash/webui/personalization_app/untrusted_personalization_app_ui_config.cc b/ash/webui/personalization_app/untrusted_personalization_app_ui_config.cc
index 8485a5c..a57da58 100644
--- a/ash/webui/personalization_app/untrusted_personalization_app_ui_config.cc
+++ b/ash/webui/personalization_app/untrusted_personalization_app_ui_config.cc
@@ -48,12 +48,12 @@
  public:
   explicit UntrustedPersonalizationAppUI(content::WebUI* web_ui)
       : ui::UntrustedWebUIController(web_ui) {
-    std::unique_ptr<content::WebUIDataSource> source =
-        base::WrapUnique(content::WebUIDataSource::Create(
-            kChromeUIUntrustedPersonalizationAppURL));
+    content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+        web_ui->GetWebContents()->GetBrowserContext(),
+        kChromeUIUntrustedPersonalizationAppURL);
 
-    AddStrings(source.get());
-    AddBooleans(source.get());
+    AddStrings(source);
+    AddBooleans(source);
 
     const auto resources = base::make_span(kAshPersonalizationAppResources,
                                            kAshPersonalizationAppResourcesSize);
@@ -90,9 +90,6 @@
     // TODO(crbug/1169829) set up trusted types properly to allow Polymer to
     // write html.
     source->DisableTrustedTypesCSP();
-
-    auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-    content::WebUIDataSource::Add(browser_context, source.release());
   }
 
   UntrustedPersonalizationAppUI(const UntrustedPersonalizationAppUI&) = delete;
diff --git a/ash/webui/print_management/print_management_ui.cc b/ash/webui/print_management/print_management_ui.cc
index 597d7d4e..055a613 100644
--- a/ash/webui/print_management/print_management_ui.cc
+++ b/ash/webui/print_management/print_management_ui.cc
@@ -8,7 +8,6 @@
 #include "ash/webui/grit/ash_print_management_resources_map.h"
 #include "ash/webui/print_management/mojom/printing_manager.mojom.h"
 #include "ash/webui/print_management/url_constants.h"
-#include "base/memory/ptr_util.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
@@ -112,8 +111,10 @@
     BindPrintingMetadataProviderCallback callback)
     : ui::MojoWebUIController(web_ui),
       bind_pending_receiver_callback_(std::move(callback)) {
-  auto html_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIPrintManagementHost));
+  content::WebUIDataSource* html_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIPrintManagementHost);
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -121,16 +122,12 @@
 
   const auto resources = base::make_span(kAshPrintManagementResources,
                                          kAshPrintManagementResourcesSize);
-  SetUpWebUIDataSource(html_source.get(), resources,
-                       IDR_PRINT_MANAGEMENT_INDEX_HTML);
+  SetUpWebUIDataSource(html_source, resources, IDR_PRINT_MANAGEMENT_INDEX_HTML);
 
   html_source->AddResourcePath("printing_manager.mojom-lite.js",
                                IDR_PRINTING_MANAGER_MOJO_LITE_JS);
 
-  AddPrintManagementStrings(html_source.get());
-
-  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                html_source.release());
+  AddPrintManagementStrings(html_source);
 }
 
 PrintManagementUI::~PrintManagementUI() = default;
diff --git a/ash/webui/projector_app/annotator_message_handler.cc b/ash/webui/projector_app/annotator_message_handler.cc
index c083eb3..e2a520a 100644
--- a/ash/webui/projector_app/annotator_message_handler.cc
+++ b/ash/webui/projector_app/annotator_message_handler.cc
@@ -54,13 +54,13 @@
   FireWebUIListener("clear");
 }
 
-void AnnotatorMessageHandler::OnToolSet(base::Value::ConstListView args) {
+void AnnotatorMessageHandler::OnToolSet(const base::Value::List& args) {
   DCHECK_EQ(args.size(), 1u);
   ProjectorController::Get()->OnToolSet(AnnotatorTool::FromValue(args[0]));
 }
 
 void AnnotatorMessageHandler::OnUndoRedoAvailabilityChanged(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   DCHECK_EQ(args.size(), 2u);
   DCHECK(args[0].is_bool());
   DCHECK(args[1].is_bool());
@@ -68,7 +68,7 @@
                                                             args[1].GetBool());
 }
 
-void AnnotatorMessageHandler::OnError(base::Value::ConstListView args) {
+void AnnotatorMessageHandler::OnError(const base::Value::List& args) {
   // TODO(b/200846160): The annotator is in an error state. Show creation flow
   // error notification and trigger a reload of the WebContent hosting the
   // annotator to clear the error state.
diff --git a/ash/webui/projector_app/annotator_message_handler.h b/ash/webui/projector_app/annotator_message_handler.h
index 057cade..8cec25ea 100644
--- a/ash/webui/projector_app/annotator_message_handler.h
+++ b/ash/webui/projector_app/annotator_message_handler.h
@@ -37,9 +37,9 @@
   void set_web_ui_for_test(content::WebUI* web_ui) { set_web_ui(web_ui); }
 
  private:
-  void OnToolSet(base::Value::ConstListView args);
-  void OnUndoRedoAvailabilityChanged(base::Value::ConstListView args);
-  void OnError(base::Value::ConstListView args);
+  void OnToolSet(const base::Value::List& args);
+  void OnUndoRedoAvailabilityChanged(const base::Value::List& args);
+  void OnError(const base::Value::List& args);
 };
 
 }  // namespace ash
diff --git a/ash/webui/projector_app/projector_app_client.cc b/ash/webui/projector_app/projector_app_client.cc
index 11f53af..89e7701 100644
--- a/ash/webui/projector_app/projector_app_client.cc
+++ b/ash/webui/projector_app/projector_app_client.cc
@@ -14,6 +14,7 @@
 constexpr char kPendingScreencastName[] = "name";
 constexpr char kPendingScreencastUploadProgress[] = "uploadProgress";
 constexpr char kPendingScreencastCreatedTime[] = "createdTime";
+constexpr char kPendingScreencastUploadFailed[] = "uploadFailed";
 constexpr int64_t kPendingScreencastDiffThresholdInBytes = 600 * 1024;
 
 ProjectorAppClient* g_instance = nullptr;
@@ -31,6 +32,9 @@
              base::Value(created_time.is_null()
                              ? 0
                              : created_time.ToJsTimeIgnoringNull()));
+
+  // TODO(b/200179137): Calculate upload status.
+  val.SetKey(kPendingScreencastUploadFailed, base::Value(false));
   return val;
 }
 
diff --git a/ash/webui/projector_app/projector_message_handler.cc b/ash/webui/projector_app/projector_message_handler.cc
index fcf5f748..39d609a 100644
--- a/ash/webui/projector_app/projector_message_handler.cc
+++ b/ash/webui/projector_app/projector_message_handler.cc
@@ -247,7 +247,7 @@
                     precondition.ToValue());
 }
 
-void ProjectorMessageHandler::GetAccounts(base::Value::ConstListView args) {
+void ProjectorMessageHandler::GetAccounts(const base::Value::List& args) {
   AllowJavascript();
 
   // Check that there is only one argument which is the callback id.
@@ -275,7 +275,7 @@
 }
 
 void ProjectorMessageHandler::GetNewScreencastPrecondition(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   AllowJavascript();
 
   // Check that there is only one argument which is the callback id.
@@ -288,7 +288,7 @@
 }
 
 void ProjectorMessageHandler::StartProjectorSession(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   AllowJavascript();
 
   // There are two arguments. The first is the callback and the second is a list
@@ -323,7 +323,7 @@
 }
 
 void ProjectorMessageHandler::GetOAuthTokenForAccount(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   // Two arguments. The first is callback id, and the second is the list
   // containing the account for which to fetch the oauth token.
   DCHECK_EQ(args.size(), 2u);
@@ -342,7 +342,7 @@
                      GetWeakPtr(), oauth_token_fetch_callback));
 }
 
-void ProjectorMessageHandler::SendXhr(const base::Value::ConstListView args) {
+void ProjectorMessageHandler::SendXhr(const base::Value::List& args) {
   // Two arguments. The first is callback id, and the second is the list
   // containing function arguments for making the request.
   DCHECK_EQ(args.size(), 2u);
@@ -371,7 +371,7 @@
 }
 
 void ProjectorMessageHandler::ShouldDownloadSoda(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   AllowJavascript();
 
   // The device should be eligible to download SODA and SODA should not have
@@ -380,20 +380,18 @@
       args[0], base::Value(ProjectorAppClient::Get()->ShouldDownloadSoda()));
 }
 
-void ProjectorMessageHandler::InstallSoda(
-    const base::Value::ConstListView args) {
+void ProjectorMessageHandler::InstallSoda(const base::Value::List& args) {
   AllowJavascript();
   ProjectorAppClient::Get()->InstallSoda();
   ResolveJavascriptCallback(args[0], base::Value(true));
 }
 
-void ProjectorMessageHandler::OnError(const base::Value::ConstListView args) {
+void ProjectorMessageHandler::OnError(const base::Value::List& args) {
   // TODO(b/195113693): Get the SWA dialog associated with this WebUI and close
   // it.
 }
 
-void ProjectorMessageHandler::GetUserPref(
-    const base::Value::ConstListView args) {
+void ProjectorMessageHandler::GetUserPref(const base::Value::List& args) {
   AllowJavascript();
 
   std::string user_pref;
@@ -405,8 +403,7 @@
   ResolveJavascriptCallback(args[0], *(pref_service_->Get(user_pref)));
 }
 
-void ProjectorMessageHandler::SetUserPref(
-    const base::Value::ConstListView args) {
+void ProjectorMessageHandler::SetUserPref(const base::Value::List& args) {
   AllowJavascript();
   SetUserPrefArgs parsed_args;
   if (!GetSetUserPrefArgs(args[1], &parsed_args)) {
@@ -419,7 +416,7 @@
 }
 
 void ProjectorMessageHandler::OpenFeedbackDialog(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   AllowJavascript();
   ProjectorAppClient::Get()->OpenFeedbackDialog();
   ResolveJavascriptCallback(args[0], base::Value());
@@ -463,7 +460,7 @@
 }
 
 void ProjectorMessageHandler::GetPendingScreencasts(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   AllowJavascript();
   // Check that there is only one argument which is the callback id.
   DCHECK_EQ(args.size(), 1u);
diff --git a/ash/webui/projector_app/projector_message_handler.h b/ash/webui/projector_app/projector_message_handler.h
index fc784f34a..5266f9b 100644
--- a/ash/webui/projector_app/projector_message_handler.h
+++ b/ash/webui/projector_app/projector_message_handler.h
@@ -64,41 +64,41 @@
   // Requested by the Projector SWA to list the available accounts (primary and
   // secondary accounts) in the current session. The list of accounts will be
   // used in the account picker in the SWA.
-  void GetAccounts(const base::Value::ConstListView args);
+  void GetAccounts(const base::Value::List& args);
 
   // Requested by the Projector SWA to check the new screencast precondition
   // state.
-  void GetNewScreencastPrecondition(const base::Value::ConstListView args);
+  void GetNewScreencastPrecondition(const base::Value::List& args);
 
   // Requested by the Projector SWA to start a new Projector session if it is
   // possible.
-  void StartProjectorSession(const base::Value::ConstListView args);
+  void StartProjectorSession(const base::Value::List& args);
 
   // Requested by the Projector SWA to get access to the OAuth token for the
   // account email provided in the `args`.
-  void GetOAuthTokenForAccount(const base::Value::ConstListView args);
+  void GetOAuthTokenForAccount(const base::Value::List& args);
 
   // Requested by the Projector SWA to send XHR request.
-  void SendXhr(const base::Value::ConstListView args);
+  void SendXhr(const base::Value::List& args);
 
   // Requested by the Projector SWA to check if SODA is not available and should
   // be downloaded. Returns false if the device doesn't support SODA.
-  void ShouldDownloadSoda(const base::Value::ConstListView args);
+  void ShouldDownloadSoda(const base::Value::List& args);
 
   // Requested by the Projector SWA to trigger SODA installation.
-  void InstallSoda(const base::Value::ConstListView args);
+  void InstallSoda(const base::Value::List& args);
 
   // Called by the Projector SWA when an error occurred.
-  void OnError(const base::Value::ConstListView args);
+  void OnError(const base::Value::List& args);
 
   // Requested by the Projector SWA to get access to a particular user pref.
-  void GetUserPref(const base::Value::ConstListView args);
+  void GetUserPref(const base::Value::List& args);
 
   // Requested by the Projector SWA to set the value of a user pref.
-  void SetUserPref(const base::Value::ConstListView args);
+  void SetUserPref(const base::Value::List& args);
 
   // Requested by the Projector SWA to open the Chrome feedback dialog.
-  void OpenFeedbackDialog(const base::Value::ConstListView args);
+  void OpenFeedbackDialog(const base::Value::List& args);
 
   // Called when OAuth token fetch request is completed by
   // ProjectorOAuthTokenFetcher. Resolves the javascript promise created by
@@ -118,7 +118,7 @@
 
   // Requested by the Projector SWA to fetch a list of screencasts pending to
   // upload or failed to upload.
-  void GetPendingScreencasts(const base::Value::ConstListView args);
+  void GetPendingScreencasts(const base::Value::List& args);
 
   ProjectorOAuthTokenFetcher oauth_token_fetcher_;
   std::unique_ptr<ProjectorXhrSender> xhr_sender_;
diff --git a/ash/webui/projector_app/resources/communication/message_types.js b/ash/webui/projector_app/resources/communication/message_types.js
index 1ff91ec..441ed6cb 100644
--- a/ash/webui/projector_app/resources/communication/message_types.js
+++ b/ash/webui/projector_app/resources/communication/message_types.js
@@ -60,5 +60,7 @@
   SODA_DOWNLOAD_IN_PROGRESS: 5,
   OUT_OF_DISK_SPACE: 6,
   NO_MIC: 7,
-  OTHERS: 8,
+  DRIVE_FS_UNMOUNTED: 8,
+  DRIVE_FS_MOUNT_FAILED: 9,
+  OTHERS: 10,
 };
diff --git a/ash/webui/projector_app/resources/communication/projector_app.externs.js b/ash/webui/projector_app/resources/communication/projector_app.externs.js
index 9067a73c..5dd0bac 100644
--- a/ash/webui/projector_app/resources/communication/projector_app.externs.js
+++ b/ash/webui/projector_app/resources/communication/projector_app.externs.js
@@ -173,6 +173,12 @@
  */
 projectorApp.PendingScreencast.prototype.createdTime;
 
+/**
+ * Whether this screencast is failed to upload.
+ * @type {boolean}
+ */
+projectorApp.PendingScreencast.prototype.uploadFailed;
+
 // TODO(b/205334821): We may want to provide duration field to
 // PendingScreencast.
 
diff --git a/ash/webui/projector_app/test/projector_message_handler_unittest.cc b/ash/webui/projector_app/test/projector_message_handler_unittest.cc
index a852d05..38b50c26 100644
--- a/ash/webui/projector_app/test/projector_message_handler_unittest.cc
+++ b/ash/webui/projector_app/test/projector_message_handler_unittest.cc
@@ -378,6 +378,7 @@
   const auto& screencast = list_view[0];
   EXPECT_EQ(*(screencast.FindStringPath("name")), name);
   EXPECT_EQ(*(screencast.FindDoublePath("createdTime")), 0);
+  EXPECT_EQ(*(screencast.FindBoolPath("uploadFailed")), false);
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, OnScreencastsStateChange) {
diff --git a/ash/webui/sample_system_web_app_ui/sample_system_web_app_ui.cc b/ash/webui/sample_system_web_app_ui/sample_system_web_app_ui.cc
index 64724f25..9185eb6 100644
--- a/ash/webui/sample_system_web_app_ui/sample_system_web_app_ui.cc
+++ b/ash/webui/sample_system_web_app_ui/sample_system_web_app_ui.cc
@@ -22,8 +22,10 @@
 
 SampleSystemWebAppUI::SampleSystemWebAppUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
-  auto trusted_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUISampleSystemWebAppHost));
+  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
+  content::WebUIDataSource* trusted_source =
+      content::WebUIDataSource::CreateAndAdd(browser_context,
+                                             kChromeUISampleSystemWebAppHost);
   trusted_source->AddResourcePath("", IDR_ASH_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
   trusted_source->AddResourcePaths(base::make_span(
       kAshSampleSystemWebAppResources, kAshSampleSystemWebAppResourcesSize));
@@ -49,9 +51,6 @@
       network::mojom::CSPDirectiveName::TrustedTypes,
       "trusted-types lit-html worker-js-static;");
 
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, trusted_source.release());
-
   // Add ability to request chrome-untrusted: URLs
   web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
 
diff --git a/ash/webui/sample_system_web_app_ui/untrusted_sample_system_web_app_ui.cc b/ash/webui/sample_system_web_app_ui/untrusted_sample_system_web_app_ui.cc
index 54c913e..78c03bc 100644
--- a/ash/webui/sample_system_web_app_ui/untrusted_sample_system_web_app_ui.cc
+++ b/ash/webui/sample_system_web_app_ui/untrusted_sample_system_web_app_ui.cc
@@ -32,14 +32,13 @@
     content::WebUI* web_ui)
     : ui::UntrustedWebUIController(web_ui) {
   content::WebUIDataSource* untrusted_source =
-      content::WebUIDataSource::Create(kChromeUIUntrustedSampleSystemWebAppURL);
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIUntrustedSampleSystemWebAppURL);
   untrusted_source->AddResourcePaths(
       base::make_span(kAshSampleSystemWebAppUntrustedResources,
                       kAshSampleSystemWebAppUntrustedResourcesSize));
   untrusted_source->AddFrameAncestor(GURL(kChromeUISampleSystemWebAppURL));
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, untrusted_source);
 }
 
 UntrustedSampleSystemWebAppUI::~UntrustedSampleSystemWebAppUI() = default;
diff --git a/ash/webui/scanning/scanning_ui.cc b/ash/webui/scanning/scanning_ui.cc
index 486cc33..52ad55d 100644
--- a/ash/webui/scanning/scanning_ui.cc
+++ b/ash/webui/scanning/scanning_ui.cc
@@ -19,7 +19,6 @@
 #include "ash/webui/scanning/url_constants.h"
 #include "base/containers/span.h"
 #include "base/feature_list.h"
-#include "base/memory/ptr_util.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
@@ -169,8 +168,10 @@
     std::unique_ptr<ScanningAppDelegate> scanning_app_delegate)
     : ui::MojoWebUIController(web_ui, true /* enable_chrome_send */),
       bind_pending_receiver_callback_(std::move(callback)) {
-  auto html_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIScanningAppHost));
+  content::WebUIDataSource* html_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIScanningAppHost);
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -180,8 +181,7 @@
 
   const auto resources =
       base::make_span(kAshScanningAppResources, kAshScanningAppResourcesSize);
-  SetUpWebUIDataSource(html_source.get(), resources,
-                       IDR_SCANNING_APP_INDEX_HTML);
+  SetUpWebUIDataSource(html_source, resources, IDR_SCANNING_APP_INDEX_HTML);
 
   html_source->AddResourcePath("scanning.mojom-lite.js",
                                IDR_SCANNING_MOJO_LITE_JS);
@@ -190,9 +190,9 @@
   html_source->AddResourcePath("accessibility_features.mojom-lite.js",
                                IDR_ACCESSIBILITY_FEATURES_MOJO_LITE_JS);
 
-  AddFeatureFlags(html_source.get());
+  AddFeatureFlags(html_source);
 
-  AddScanningAppStrings(html_source.get());
+  AddScanningAppStrings(html_source);
 
   auto handler =
       std::make_unique<ScanningHandler>(std::move(scanning_app_delegate));
@@ -200,8 +200,6 @@
 
   web_ui->AddMessageHandler(std::move(handler));
   web_ui->AddMessageHandler(std::make_unique<ScanningMetricsHandler>());
-  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                html_source.release());
 }
 
 ScanningUI::~ScanningUI() = default;
diff --git a/ash/webui/shimless_rma/resources/onboarding_network_page.html b/ash/webui/shimless_rma/resources/onboarding_network_page.html
index 5fad7e2..609d9fc 100644
--- a/ash/webui/shimless_rma/resources/onboarding_network_page.html
+++ b/ash/webui/shimless_rma/resources/onboarding_network_page.html
@@ -68,9 +68,9 @@
       <cr-button id="cancelButton" on-click="closeConfig_">
           [[i18n('connectNetworkDialogCancelButtonText')]]
       </cr-button>
-      <cr-button id="connectButton" on-click="connectNetwork_"
-        disabled="[[!enableConnect_]]">
-          [[i18n('connectNetworkDialogConnectButtonText')]]
+      <cr-button id="connectButton" class="action-button" 
+          on-click="connectNetwork_" disabled="[[!enableConnect_]]">
+        [[i18n('connectNetworkDialogConnectButtonText')]]
       </cr-button>
     </div>
   </div>
diff --git a/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html b/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html
index bafecc6f..2ad10b7 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html
+++ b/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html
@@ -74,6 +74,10 @@
       line-height: var(--shimless-dialog-body-line-height);
     }
 
+    cr-dialog cr-button {
+      border-radius: 4px;
+    }
+
     cr-radio-button {
       --cr-radio-button-size: 20px;
       padding-bottom: 8px;
diff --git a/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html b/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html
index 5cdc97a..3a4f7bdc 100644
--- a/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html
+++ b/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html
@@ -156,7 +156,7 @@
     <cr-button id="closeLogDialogButton" on-click="onCancelClick_">
       [[i18n('rmaLogsCancelButtonText')]]
     </cr-button>
-    <cr-button id="rmaLogButton" class="text-button pill" 
+    <cr-button id="rmaLogButton" class="text-button action-button"
         on-click="onRmaLogButtonClick_">
       [[i18n('rmaLogsSaveToUsbButtonText')]]
     </cr-button>
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc
index 1e96e018..a724b4c 100644
--- a/ash/webui/shimless_rma/shimless_rma.cc
+++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -17,7 +17,6 @@
 #include "ash/webui/shimless_rma/url_constants.h"
 #include "base/command_line.h"
 #include "base/containers/span.h"
-#include "base/memory/ptr_util.h"
 #include "chromeos/strings/grit/chromeos_strings.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
@@ -357,8 +356,10 @@
     : ui::MojoWebDialogUI(web_ui),
       shimless_rma_manager_(std::make_unique<shimless_rma::ShimlessRmaService>(
           std::move(shimless_rma_delegate))) {
-  auto html_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIShimlessRMAHost));
+  content::WebUIDataSource* html_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUIShimlessRMAHost);
   html_source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -366,20 +367,16 @@
 
   const auto resources =
       base::make_span(kAshShimlessRmaResources, kAshShimlessRmaResourcesSize);
-  SetUpWebUIDataSource(html_source.get(), resources,
-                       IDR_ASH_SHIMLESS_RMA_INDEX_HTML);
+  SetUpWebUIDataSource(html_source, resources, IDR_ASH_SHIMLESS_RMA_INDEX_HTML);
 
-  AddShimlessRmaStrings(html_source.get());
+  AddShimlessRmaStrings(html_source);
 
-  ui::network_element::AddLocalizedStrings(html_source.get());
-  ui::network_element::AddOncLocalizedStrings(html_source.get());
-  ui::network_element::AddDetailsLocalizedStrings(html_source.get());
-  ui::network_element::AddConfigLocalizedStrings(html_source.get());
-  ui::network_element::AddErrorLocalizedStrings(html_source.get());
-  html_source.get()->UseStringsJs();
-
-  content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
-                                html_source.release());
+  ui::network_element::AddLocalizedStrings(html_source);
+  ui::network_element::AddOncLocalizedStrings(html_source);
+  ui::network_element::AddDetailsLocalizedStrings(html_source);
+  ui::network_element::AddConfigLocalizedStrings(html_source);
+  ui::network_element::AddErrorLocalizedStrings(html_source);
+  html_source->UseStringsJs();
 }
 
 ShimlessRMADialogUI::~ShimlessRMADialogUI() = default;
@@ -398,4 +395,4 @@
 
 WEB_UI_CONTROLLER_TYPE_IMPL(ShimlessRMADialogUI)
 
-}  // namespace ash
+}  // namespace ash
\ No newline at end of file
diff --git a/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc b/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
index 66c04a2..f47336f5 100644
--- a/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
+++ b/ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.cc
@@ -40,8 +40,9 @@
 
 ShortcutCustomizationAppUI::ShortcutCustomizationAppUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
-  auto source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUIShortcutCustomizationAppHost));
+  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
+      web_ui->GetWebContents()->GetBrowserContext(),
+      kChromeUIShortcutCustomizationAppHost);
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::ScriptSrc,
       "script-src chrome://resources chrome://test 'self';");
@@ -50,12 +51,9 @@
   const auto resources =
       base::make_span(kAshShortcutCustomizationAppResources,
                       kAshShortcutCustomizationAppResourcesSize);
-  SetUpWebUIDataSource(source.get(), resources,
+  SetUpWebUIDataSource(source, resources,
                        IDR_ASH_SHORTCUT_CUSTOMIZATION_APP_INDEX_HTML);
 
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, source.release());
-
   provider_ = std::make_unique<shortcut_ui::AcceleratorConfigurationProvider>();
 }
 
diff --git a/ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.cc b/ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.cc
index 0b6a2a1..9af4f85 100644
--- a/ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.cc
+++ b/ash/webui/system_extensions_internals_ui/system_extensions_internals_ui.cc
@@ -7,7 +7,6 @@
 #include "ash/webui/grit/ash_system_extensions_internals_resources.h"
 #include "ash/webui/grit/ash_system_extensions_internals_resources_map.h"
 #include "ash/webui/system_extensions_internals_ui/url_constants.h"
-#include "base/memory/ptr_util.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -18,17 +17,16 @@
 
 SystemExtensionsInternalsUI::SystemExtensionsInternalsUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
-  auto data_source = base::WrapUnique(
-      content::WebUIDataSource::Create(kChromeUISystemExtensionsInternalsHost));
+  content::WebUIDataSource* data_source =
+      content::WebUIDataSource::CreateAndAdd(
+          web_ui->GetWebContents()->GetBrowserContext(),
+          kChromeUISystemExtensionsInternalsHost);
 
   data_source->AddResourcePath("",
                                IDR_ASH_SYSTEM_EXTENSIONS_INTERNALS_INDEX_HTML);
   data_source->AddResourcePaths(
       base::make_span(kAshSystemExtensionsInternalsResources,
                       kAshSystemExtensionsInternalsResourcesSize));
-
-  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
-  content::WebUIDataSource::Add(browser_context, data_source.release());
 }
 
 SystemExtensionsInternalsUI::~SystemExtensionsInternalsUI() = default;
diff --git a/ash/wm/desks/desks_bar_view.cc b/ash/wm/desks/desks_bar_view.cc
index b778141..487498cb 100644
--- a/ash/wm/desks/desks_bar_view.cc
+++ b/ash/wm/desks/desks_bar_view.cc
@@ -1204,7 +1204,8 @@
 
 void DesksBarView::OnDesksTemplatesButtonPressed() {
   RecordLoadTemplateHistogram();
-  overview_grid_->overview_session()->ShowDesksTemplatesGrids(IsZeroState());
+  overview_grid_->overview_session()->ShowDesksTemplatesGrids(IsZeroState(),
+                                                              base::GUID());
 }
 
 void DesksBarView::OnContentsScrolled() {
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.cc b/ash/wm/desks/templates/desks_templates_grid_view.cc
index 54ba23b2..4cd1951 100644
--- a/ash/wm/desks/templates/desks_templates_grid_view.cc
+++ b/ash/wm/desks/templates/desks_templates_grid_view.cc
@@ -161,6 +161,10 @@
 void DesksTemplatesGridView::PopulateGridUI(
     const std::vector<DeskTemplate*>& desk_templates,
     const gfx::Rect& grid_bounds) {
+  DCHECK(grid_items_.empty());
+
+  // TODO(richui|sammiequon): See if this can be removed as this function should
+  // only be called once per overview session.
   if (desk_templates.empty()) {
     RemoveAllChildViews();
     grid_items_.clear();
@@ -349,6 +353,21 @@
   return false;
 }
 
+DesksTemplatesItemView* DesksTemplatesGridView::RequestFocusForUUID(
+    const base::GUID& uuid) {
+  if (!uuid.is_valid())
+    return nullptr;
+
+  for (auto* item_view : grid_items_) {
+    if (uuid == item_view->desk_template()->uuid()) {
+      DCHECK(!item_view->name_view()->GetReadOnly());
+      item_view->name_view()->RequestFocus();
+      return item_view;
+    }
+  }
+  return nullptr;
+}
+
 void DesksTemplatesGridView::OnLocatedEvent(ui::LocatedEvent* event,
                                             bool is_touch) {
   if (widget_window_ && widget_window_->event_targeting_policy() ==
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.h b/ash/wm/desks/templates/desks_templates_grid_view.h
index 085e98a..b6dc124 100644
--- a/ash/wm/desks/templates/desks_templates_grid_view.h
+++ b/ash/wm/desks/templates/desks_templates_grid_view.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "base/guid.h"
 #include "ui/aura/window_observer.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/animation/bounds_animator.h"
@@ -66,6 +67,10 @@
   // Returns whether the given `point_in_screen` intersect with any grid item.
   bool IntersectsWithGridItem(const gfx::Point& point_in_screen);
 
+  // Requests focus on the textfield of the item associated with `uuid`. Returns
+  // the item if it exists.
+  DesksTemplatesItemView* RequestFocusForUUID(const base::GUID& uuid);
+
   // views::View:
   void Layout() override;
   void AddedToWidget() override;
diff --git a/ash/wm/desks/templates/desks_templates_presenter.cc b/ash/wm/desks/templates/desks_templates_presenter.cc
index 3cd2471..570e09b 100644
--- a/ash/wm/desks/templates/desks_templates_presenter.cc
+++ b/ash/wm/desks/templates/desks_templates_presenter.cc
@@ -49,6 +49,7 @@
 // Callback ran after creating and activating a new desk for launching a
 // template. Launches apps into the active desk.
 void OnNewDeskCreatedForTemplate(std::unique_ptr<DeskTemplate> desk_template,
+                                 base::Time time_launch_started,
                                  base::TimeDelta delay,
                                  aura::Window* root_window,
                                  bool on_create_activate_success) {
@@ -56,7 +57,7 @@
     return;
 
   Shell::Get()->desks_templates_delegate()->LaunchAppsFromTemplate(
-      std::move(desk_template), delay);
+      std::move(desk_template), time_launch_started, delay);
 
   OverviewSession* overview_session =
       Shell::Get()->overview_controller()->overview_session();
@@ -80,7 +81,7 @@
 
   auto* desk_model = GetDeskModel();
   desk_model_observation_.Observe(desk_model);
-  GetAllEntries();
+  GetAllEntries(base::GUID());
 }
 
 DesksTemplatesPresenter::~DesksTemplatesPresenter() {
@@ -130,11 +131,11 @@
   }
 }
 
-void DesksTemplatesPresenter::GetAllEntries() {
+void DesksTemplatesPresenter::GetAllEntries(const base::GUID& item_to_focus) {
   weak_ptr_factory_.InvalidateWeakPtrs();
   GetDeskModel()->GetAllEntries(
       base::BindOnce(&DesksTemplatesPresenter::OnGetAllEntries,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr(), item_to_focus));
 }
 
 void DesksTemplatesPresenter::DeleteEntry(const std::string& template_uuid) {
@@ -143,7 +144,6 @@
       template_uuid,
       base::BindOnce(&DesksTemplatesPresenter::OnDeleteEntry,
                      weak_ptr_factory_.GetWeakPtr(), template_uuid));
-  cached_saved_template_uuid_.reset();
 }
 
 void DesksTemplatesPresenter::LaunchDeskTemplate(
@@ -169,7 +169,8 @@
   GetDeskModel()->GetEntryByUUID(
       template_uuid,
       base::BindOnce(&DesksTemplatesPresenter::OnGetTemplateForDeskLaunch,
-                     weak_ptr_factory_.GetWeakPtr(), delay, root_window));
+                     weak_ptr_factory_.GetWeakPtr(), base::Time::Now(), delay,
+                     root_window));
 }
 
 void DesksTemplatesPresenter::MaybeSaveActiveDeskAsTemplate(
@@ -189,25 +190,22 @@
 
   if (is_update)
     desk_template->set_updated_time(base::Time::Now());
-
-  weak_ptr_factory_.InvalidateWeakPtrs();
-
-  if (!is_update) {
+  else
     RecordWindowAndTabCountHistogram(desk_template.get());
-    cached_saved_template_uuid_ = desk_template->uuid();
-  } else {
-    cached_saved_template_uuid_.reset();
-  }
 
-  // TODO(richui): Look into passing the entire template and not just the
-  // UUID.
-  const std::string template_uuid = desk_template->uuid().AsLowercaseString();
+  // Clone the desk template so one can be sent to the model, and the other as
+  // part of the callback.
+  // TODO: Investigate if we can modify the model to send the template as one of
+  // the callback args.
+  auto desk_template_clone = desk_template->Clone();
 
   // Save or update `desk_template` as an entry in DeskModel.
+  weak_ptr_factory_.InvalidateWeakPtrs();
   GetDeskModel()->AddOrUpdateEntry(
       std::move(desk_template),
       base::BindOnce(&DesksTemplatesPresenter::OnAddOrUpdateEntry,
-                     weak_ptr_factory_.GetWeakPtr(), is_update, template_uuid));
+                     weak_ptr_factory_.GetWeakPtr(), is_update,
+                     std::move(desk_template_clone)));
 }
 
 void DesksTemplatesPresenter::OnDeskModelDestroying() {
@@ -225,6 +223,7 @@
 }
 
 void DesksTemplatesPresenter::OnGetAllEntries(
+    const base::GUID& item_to_focus,
     desks_storage::DeskModel::GetAllEntriesStatus status,
     const std::vector<DeskTemplate*>& entries) {
   if (status != desks_storage::DeskModel::GetAllEntriesStatus::kOk)
@@ -243,21 +242,10 @@
           static_cast<DesksTemplatesGridView*>(grid_widget->GetContentsView());
       grid_view->PopulateGridUI(entries,
                                 overview_grid->GetGridEffectiveBounds());
-      if (cached_saved_template_uuid_) {
-        for (auto* item_view : grid_view->grid_items()) {
-          if (cached_saved_template_uuid_ ==
-              item_view->desk_template()->uuid()) {
-            // If a template was newly added, set focus on that template item's
-            // name view.
-            DCHECK(!item_view->name_view()->GetReadOnly());
-            item_view->name_view()->RequestFocus();
-            // Check if name nudge needs to be removed.
-            item_view->MaybeRemoveNameNumber();
-            cached_saved_template_uuid_.reset();
-            break;
-          }
-        }
-      }
+      auto* focused_item_view = grid_view->RequestFocusForUUID(item_to_focus);
+      // Check if name number needs to be removed.
+      if (focused_item_view)
+        focused_item_view->MaybeRemoveNameNumber();
     }
   }
 
@@ -265,25 +253,6 @@
     std::move(on_update_ui_closure_for_testing_).Run();
 }
 
-void DesksTemplatesPresenter::GetEntryByUUID(const std::string& template_uuid) {
-  weak_ptr_factory_.InvalidateWeakPtrs();
-  GetDeskModel()->GetEntryByUUID(
-      template_uuid, base::BindOnce(&DesksTemplatesPresenter::OnGetEntryByUUID,
-                                    weak_ptr_factory_.GetWeakPtr()));
-}
-
-void DesksTemplatesPresenter::OnGetEntryByUUID(
-    desks_storage::DeskModel::GetEntryByUuidStatus status,
-    std::unique_ptr<ash::DeskTemplate> entry) {
-  if (status != desks_storage::DeskModel::GetEntryByUuidStatus::kOk)
-    return;
-
-  if (!entry)
-    return;
-
-  AddOrUpdateUIEntries({entry.get()});
-}
-
 void DesksTemplatesPresenter::OnDeleteEntry(
     const std::string& template_uuid,
     desks_storage::DeskModel::DeleteEntryStatus status) {
@@ -296,6 +265,7 @@
 }
 
 void DesksTemplatesPresenter::OnGetTemplateForDeskLaunch(
+    base::Time time_launch_started,
     base::TimeDelta delay,
     aura::Window* root_window,
     desks_storage::DeskModel::GetEntryByUuidStatus status,
@@ -315,8 +285,9 @@
   // function in the anonymous namespace.
   const auto template_name = entry->template_name();
   DesksController::Get()->CreateAndActivateNewDeskForTemplate(
-      template_name, base::BindOnce(&OnNewDeskCreatedForTemplate,
-                                    std::move(entry), delay, root_window));
+      template_name,
+      base::BindOnce(&OnNewDeskCreatedForTemplate, std::move(entry),
+                     time_launch_started, delay, root_window));
 
   if (on_update_ui_closure_for_testing)
     std::move(on_update_ui_closure_for_testing).Run();
@@ -326,7 +297,7 @@
 
 void DesksTemplatesPresenter::OnAddOrUpdateEntry(
     bool was_update,
-    const std::string& template_uuid,
+    std::unique_ptr<DeskTemplate> desk_template,
     desks_storage::DeskModel::AddOrUpdateEntryStatus status) {
   RecordAddOrUpdateTemplateStatusHistogram(status);
 
@@ -345,22 +316,41 @@
   if (status != desks_storage::DeskModel::AddOrUpdateEntryStatus::kOk)
     return;
 
-  // If the templates grid is already shown, just update the entry.
-  if (overview_session_->IsShowingDesksTemplatesGrid()) {
-    GetEntryByUUID(template_uuid);
+  // If the templates grid has already been shown before, update the entry.
+  const auto& grid_list = overview_session_->grid_list();
+  DCHECK(!grid_list.empty());
+  const bool is_zero_state = grid_list.front()->desks_bar_view()->IsZeroState();
+
+  views::Widget* grid_widget = grid_list.front()->desks_templates_grid_widget();
+  if (grid_widget) {
+    AddOrUpdateUIEntries({desk_template.get()});
+
+    if (!was_update) {
+      // Shows the grid if it was hidden. This will not call `GetAllEntries`.
+      overview_session_->ShowDesksTemplatesGrids(is_zero_state, base::GUID());
+      auto* grid_view =
+          static_cast<DesksTemplatesGridView*>(grid_widget->GetContentsView());
+      grid_view->RequestFocusForUUID(desk_template->uuid());
+    }
+
+    if (on_update_ui_closure_for_testing_)
+      std::move(on_update_ui_closure_for_testing_).Run();
     return;
   }
 
-  // Update the button here in case it has been disabled.
-  const auto& grid_list = overview_session_->grid_list();
-  DCHECK(!grid_list.empty());
+  // This will update the templates button and save as desks button too. This
+  // will call `GetAllEntries`.
   overview_session_->ShowDesksTemplatesGrids(
-      grid_list.front()->desks_bar_view()->IsZeroState());
+      grid_list.front()->desks_bar_view()->IsZeroState(),
+      desk_template->uuid());
 
   if (!was_update) {
     RecordNewTemplateHistogram();
     RecordUserTemplateCountHistogram(GetEntryCount(), GetMaxEntryCount());
   }
+
+  // Note we do not run `on_update_ui_closure_for_testing` here as we want to
+  // wait for the `GetAllEntries` fired in `ShowDesksTemplatesGrids`.
 }
 
 void DesksTemplatesPresenter::AddOrUpdateUIEntries(
diff --git a/ash/wm/desks/templates/desks_templates_presenter.h b/ash/wm/desks/templates/desks_templates_presenter.h
index fdb76a94..a3e3873 100644
--- a/ash/wm/desks/templates/desks_templates_presenter.h
+++ b/ash/wm/desks/templates/desks_templates_presenter.h
@@ -13,7 +13,6 @@
 #include "base/scoped_observation.h"
 #include "components/desks_storage/core/desk_model.h"
 #include "components/desks_storage/core/desk_model_observer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/window.h"
 
 namespace ash {
@@ -50,7 +49,7 @@
 
   // Calls the DeskModel to get all the template entries, with a callback to
   // `OnGetAllEntries`.
-  void GetAllEntries();
+  void GetAllEntries(const base::GUID& item_to_focus);
 
   // Calls the DeskModel to delete the template with the provided uuid.
   void DeleteEntry(const std::string& template_uuid);
@@ -86,18 +85,10 @@
 
   // Callback ran after querying the model for a list of entries. This function
   // also contains logic for updating the UI.
-  void OnGetAllEntries(desks_storage::DeskModel::GetAllEntriesStatus status,
+  void OnGetAllEntries(const base::GUID& item_to_focus,
+                       desks_storage::DeskModel::GetAllEntriesStatus status,
                        const std::vector<DeskTemplate*>& entries);
 
-  // Calls the DeskModel to get a specific template entry, with a callback to
-  // `OnGetEntryByUUID`.
-  void GetEntryByUUID(const std::string& template_uuid);
-
-  // Callback ran after querying the model for a specific entry. Will then call
-  // `AddOrUpdateUIEntries` to update specified template in the UI.
-  void OnGetEntryByUUID(desks_storage::DeskModel::GetEntryByUuidStatus status,
-                        std::unique_ptr<ash::DeskTemplate> entry);
-
   // Callback after deleting an entry. Will then call `RemoveUIEntries` to
   // update the UI by removing the deleted template.
   void OnDeleteEntry(const std::string& template_uuid,
@@ -105,6 +96,7 @@
 
   // Launches DeskTemplate after retrieval from storage.
   void OnGetTemplateForDeskLaunch(
+      base::Time time_launch_started,
       base::TimeDelta delay,
       aura::Window* root_window,
       desks_storage::DeskModel::GetEntryByUuidStatus status,
@@ -114,7 +106,7 @@
   // `AddOrUpdateUIEntries` to update the UI by adding or updating the template.
   void OnAddOrUpdateEntry(
       bool was_update,
-      const std::string& template_uuid,
+      std::unique_ptr<DeskTemplate> desk_template,
       desks_storage::DeskModel::AddOrUpdateEntryStatus status);
 
   // Helper functions for updating the UI.
@@ -137,12 +129,6 @@
   // the model.
   base::OnceClosure on_update_ui_closure_for_testing_;
 
-  // A cache of the last saved `DeskTemplate` UUID, used to name nudge the last
-  // saved template on `GetAllEntries`.
-  // TODO(crbug.com/1266552): Investigate if this is needed once we aren't
-  // recreating the grid every time.
-  absl::optional<base::GUID> cached_saved_template_uuid_;
-
   base::WeakPtrFactory<DesksTemplatesPresenter> weak_ptr_factory_{this};
 };
 
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc
index abb0e35..93f36623d 100644
--- a/ash/wm/desks/templates/desks_templates_unittest.cc
+++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -73,7 +73,7 @@
 
 class DesksTemplatesTest : public OverviewTestBase {
  public:
-  DesksTemplatesTest() = default;
+  DesksTemplatesTest() {}
   DesksTemplatesTest(const DesksTemplatesTest&) = delete;
   DesksTemplatesTest& operator=(const DesksTemplatesTest&) = delete;
   ~DesksTemplatesTest() override = default;
@@ -1618,7 +1618,6 @@
   // created. There should still be only one template item and one feedback
   // button.
   ShowDesksTemplatesGrids();
-  WaitForDesksTemplatesUI();
   ASSERT_EQ(2ul, templates_grid_view->children().size());
 }
 
diff --git a/ash/wm/overview/overview_highlight_controller_unittest.cc b/ash/wm/overview/overview_highlight_controller_unittest.cc
index 816c68c..02fc5e9 100644
--- a/ash/wm/overview/overview_highlight_controller_unittest.cc
+++ b/ash/wm/overview/overview_highlight_controller_unittest.cc
@@ -149,7 +149,7 @@
       {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}   // Up (same as Left)
   };
 
-  for (size_t key_index = 0; key_index < base::size(arrow_keys); ++key_index) {
+  for (size_t key_index = 0; key_index < std::size(arrow_keys); ++key_index) {
     ToggleOverview();
     const std::vector<std::unique_ptr<OverviewItem>>& overview_windows =
         GetOverviewItemsForRoot(0);
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc
index 5730dc1..de82f84 100644
--- a/ash/wm/overview/overview_session.cc
+++ b/ash/wm/overview/overview_session.cc
@@ -1015,17 +1015,24 @@
   return window == active_window_before_overview_;
 }
 
-void OverviewSession::ShowDesksTemplatesGrids(bool was_zero_state) {
+void OverviewSession::ShowDesksTemplatesGrids(bool was_zero_state,
+                                              const base::GUID& item_to_focus) {
   if (IsShowingDesksTemplatesGrid())
     return;
 
+  const bool created_grid_widgets =
+      !grid_list_.front()->desks_templates_grid_widget();
+
   // Send an a11y alert.
   Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert(
       AccessibilityAlert::DESK_TEMPLATES_MODE_ENTERED);
 
   for (auto& grid : grid_list_)
     grid->ShowDesksTemplatesGrid(was_zero_state);
-  desks_templates_presenter_->GetAllEntries();
+  // Only ask for all entries if it is the first time creating the grid widgets.
+  // Otherwise, add or update the entries one at a time.
+  if (created_grid_widgets)
+    desks_templates_presenter_->GetAllEntries(item_to_focus);
   UpdateNoWindowsWidgetOnEachGrid();
 }
 
@@ -1274,7 +1281,8 @@
         return;
 
       DCHECK(!grid_list_.empty());
-      ShowDesksTemplatesGrids(grid_list_[0]->desks_bar_view()->IsZeroState());
+      ShowDesksTemplatesGrids(grid_list_[0]->desks_bar_view()->IsZeroState(),
+                              base::GUID());
       break;
 #else
       return;
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h
index 7763bc6..5c3925a6 100644
--- a/ash/wm/overview/overview_session.h
+++ b/ash/wm/overview/overview_session.h
@@ -22,6 +22,7 @@
 #include "ash/wm/splitview/split_view_drag_indicators.h"
 #include "ash/wm/splitview/split_view_observer.h"
 #include "base/containers/flat_set.h"
+#include "base/guid.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
 #include "ui/aura/window_observer.h"
@@ -290,7 +291,9 @@
 
   // Shows the desks templates grids on all displays. If `was_zero_state` is
   // true then we will expand the desks bars.
-  void ShowDesksTemplatesGrids(bool was_zero_state);
+  void ShowDesksTemplatesGrids(bool was_zero_state,
+                               const base::GUID& item_to_focus);
+
   void HideDesksTemplatesGrids();
   bool IsShowingDesksTemplatesGrid() const;
 
diff --git a/ash/wm/pip/pip_window_resizer.cc b/ash/wm/pip/pip_window_resizer.cc
index 8c9dd39..3624bc4 100644
--- a/ash/wm/pip/pip_window_resizer.cc
+++ b/ash/wm/pip/pip_window_resizer.cc
@@ -129,7 +129,7 @@
                                bounds),
        AshPipPosition::BOTTOM_RIGHT}};
 
-  std::sort(area_ninths, area_ninths + base::size(area_ninths));
+  std::sort(area_ninths, area_ninths + std::size(area_ninths));
   UMA_HISTOGRAM_ENUMERATION(kAshPipPositionHistogramName,
                             area_ninths[8].second);
 }
diff --git a/ash/wm/tablet_mode/accelerometer_test_data_literals.cc b/ash/wm/tablet_mode/accelerometer_test_data_literals.cc
index 62a933e..90b8c03 100644
--- a/ash/wm/tablet_mode/accelerometer_test_data_literals.cc
+++ b/ash/wm/tablet_mode/accelerometer_test_data_literals.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace ash {
 
@@ -556,7 +556,7 @@
     0.0703125f,   -0.0986328f,   0.948242f,     -0.928711f,    -0.162109f,
     -0.333008f};
 extern const size_t kAccelerometerLaptopModeTestDataLength =
-    base::size(kAccelerometerLaptopModeTestData);
+    std::size(kAccelerometerLaptopModeTestData);
 
 extern const float kAccelerometerFullyOpenTestData[] = {
     0.892578f,    -0.0810547f,  0.0146484f,    0.929688f,     -0.0644531f,
@@ -994,7 +994,7 @@
     0.887695f,    0.0146484f,   0.360352f,     0.927734f,     -0.03125f,
     0.272461f};
 extern const size_t kAccelerometerFullyOpenTestDataLength =
-    base::size(kAccelerometerFullyOpenTestData);
+    std::size(kAccelerometerFullyOpenTestData);
 
 extern const float kAccelerometerVerticalHingeTestData[] = {
     -0.0766145f,  6.02381f,     7.85298f,     -0.268151f,   -8.84897f,
@@ -1996,7 +1996,7 @@
 };
 
 extern const size_t kAccelerometerVerticalHingeTestDataLength =
-    base::size(kAccelerometerVerticalHingeTestData);
+    std::size(kAccelerometerVerticalHingeTestData);
 
 extern const float kAccelerometerVerticalHingeUnstableAnglesTestData[] = {
     8.5904f,   -1.36948f,  -3.74453f,   8.72447f,  1.1971f,    4.00311f,
@@ -2023,6 +2023,6 @@
 };
 
 extern const size_t kAccelerometerVerticalHingeUnstableAnglesTestDataLength =
-    base::size(kAccelerometerVerticalHingeUnstableAnglesTestData);
+    std::size(kAccelerometerVerticalHingeUnstableAnglesTestData);
 
 }  // namespace ash
diff --git a/ash/wm/test_session_state_animator.cc b/ash/wm/test_session_state_animator.cc
index a4c9e76b..722d9c9 100644
--- a/ash/wm/test_session_state_animator.cc
+++ b/ash/wm/test_session_state_animator.cc
@@ -10,7 +10,6 @@
 #include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 
 namespace ash {
 
@@ -176,7 +175,7 @@
 bool TestSessionStateAnimator::AreContainersAnimated(
     int container_mask,
     SessionStateAnimator::AnimationType type) const {
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i] &&
         !IsContainerAnimated(kAllContainers[i], type)) {
       return false;
@@ -199,7 +198,7 @@
                                               AnimationType type,
                                               AnimationSpeed speed) {
   ++last_animation_epoch_;
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i]) {
       AddAnimation(kAllContainers[i], type, speed, base::DoNothing(),
                    base::DoNothing());
@@ -215,14 +214,14 @@
   ++last_animation_epoch_;
 
   int container_count = 0;
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i])
       ++container_count;
   }
 
   base::RepeatingClosure completion_callback =
       base::BarrierClosure(container_count, std::move(callback));
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i]) {
       // ash::SessionStateAnimatorImpl invokes the callback whether or not the
       // animation was completed successfully or not.
@@ -250,7 +249,7 @@
 }
 
 void TestSessionStateAnimator::AbortAnimations(int container_mask) {
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i])
       AbortAnimation(kAllContainers[i]);
   }
@@ -262,7 +261,7 @@
     AnimationSpeed speed,
     AnimationSequence* animation_sequence) {
   ++last_animation_epoch_;
-  for (size_t i = 0; i < base::size(kAllContainers); ++i) {
+  for (size_t i = 0; i < std::size(kAllContainers); ++i) {
     if (container_mask & kAllContainers[i]) {
       base::OnceClosure success_callback =
           base::BindOnce(&AnimationSequence::SequenceFinished,
diff --git a/ash/wm/window_modality_controller_unittest.cc b/ash/wm/window_modality_controller_unittest.cc
index f53cd89..7bde4e7 100644
--- a/ash/wm/window_modality_controller_unittest.cc
+++ b/ash/wm/window_modality_controller_unittest.cc
@@ -3,12 +3,10 @@
 // found in the LICENSE file.
 
 #include "ui/wm/core/window_modality_controller.h"
-
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/test_child_modal_parent.h"
 #include "ash/wm/window_util.h"
-#include "base/cxx17_backports.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/capture_client.h"
 #include "ui/aura/test/test_window_delegate.h"
@@ -67,14 +65,14 @@
   EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
 
   int check1[] = {-1, -12, -11};
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, base::size(check1)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
 
   wm::ActivateWindow(w1.get());
   EXPECT_TRUE(wm::IsActiveWindow(w12.get()));
   // Transient children are always stacked above their transient parent, which
   // is why this order is not -11, -1, -12.
   int check2[] = {-1, -11, -12};
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check2, base::size(check2)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check2, std::size(check2)));
 
   w12.reset();
   EXPECT_TRUE(wm::IsActiveWindow(w11.get()));
@@ -114,20 +112,20 @@
   wm::ActivateWindow(w1.get());
   EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
   int check1[] = {-2, -1, -11, -111};
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, base::size(check1)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
 
   wm::ActivateWindow(w11.get());
   EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, base::size(check1)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
 
   wm::ActivateWindow(w111.get());
   EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, base::size(check1)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check1, std::size(check1)));
 
   wm::ActivateWindow(w2.get());
   EXPECT_TRUE(wm::IsActiveWindow(w2.get()));
   int check2[] = {-1, -11, -111, -2};
-  EXPECT_TRUE(ValidateStacking(w1->parent(), check2, base::size(check2)));
+  EXPECT_TRUE(ValidateStacking(w1->parent(), check2, std::size(check2)));
 
   w2.reset();
   EXPECT_TRUE(wm::IsActiveWindow(w111.get()));
diff --git a/base/profiler/metadata_recorder.cc b/base/profiler/metadata_recorder.cc
index d4c857f..c51728f 100644
--- a/base/profiler/metadata_recorder.cc
+++ b/base/profiler/metadata_recorder.cc
@@ -13,8 +13,9 @@
 
 MetadataRecorder::Item::Item(uint64_t name_hash,
                              absl::optional<int64_t> key,
+                             absl::optional<PlatformThreadId> thread_id,
                              int64_t value)
-    : name_hash(name_hash), key(key), value(value) {}
+    : name_hash(name_hash), key(key), thread_id(thread_id), value(value) {}
 
 MetadataRecorder::Item::Item() : name_hash(0), value(0) {}
 
@@ -37,6 +38,7 @@
 
 void MetadataRecorder::Set(uint64_t name_hash,
                            absl::optional<int64_t> key,
+                           absl::optional<PlatformThreadId> thread_id,
                            int64_t value) {
   AutoLock lock(write_lock_);
 
@@ -49,7 +51,8 @@
   size_t item_slots_used = item_slots_used_.load(std::memory_order_relaxed);
   for (size_t i = 0; i < item_slots_used; ++i) {
     auto& item = items_[i];
-    if (item.name_hash == name_hash && item.key == key) {
+    if (item.name_hash == name_hash && item.key == key &&
+        item.thread_id == thread_id) {
       item.value.store(value, std::memory_order_relaxed);
 
       const bool was_active =
@@ -82,18 +85,22 @@
   auto& item = items_[item_slots_used];
   item.name_hash = name_hash;
   item.key = key;
+  item.thread_id = thread_id;
   item.value.store(value, std::memory_order_relaxed);
   item.is_active.store(true, std::memory_order_release);
   item_slots_used_.fetch_add(1, std::memory_order_release);
 }
 
-void MetadataRecorder::Remove(uint64_t name_hash, absl::optional<int64_t> key) {
+void MetadataRecorder::Remove(uint64_t name_hash,
+                              absl::optional<int64_t> key,
+                              absl::optional<PlatformThreadId> thread_id) {
   AutoLock lock(write_lock_);
 
   size_t item_slots_used = item_slots_used_.load(std::memory_order_relaxed);
   for (size_t i = 0; i < item_slots_used; ++i) {
     auto& item = items_[i];
-    if (item.name_hash == name_hash && item.key == key) {
+    if (item.name_hash == name_hash && item.key == key &&
+        item.thread_id == thread_id) {
       // A removed item will occupy its slot until that slot is reclaimed.
       const bool was_active =
           item.is_active.exchange(false, std::memory_order_relaxed);
@@ -106,18 +113,21 @@
 }
 
 MetadataRecorder::MetadataProvider::MetadataProvider(
-    MetadataRecorder* metadata_recorder)
+    MetadataRecorder* metadata_recorder,
+    PlatformThreadId thread_id)
     : metadata_recorder_(metadata_recorder),
+      thread_id_(thread_id),
       auto_lock_(metadata_recorder->read_lock_) {}
 
 MetadataRecorder::MetadataProvider::~MetadataProvider() = default;
 
 size_t MetadataRecorder::MetadataProvider::GetItems(
     ItemArray* const items) const {
-  return metadata_recorder_->GetItems(items);
+  return metadata_recorder_->GetItems(items, thread_id_);
 }
 
-size_t MetadataRecorder::GetItems(ItemArray* const items) const {
+size_t MetadataRecorder::GetItems(ItemArray* const items,
+                                  PlatformThreadId thread_id) const {
   // If a writer adds a new item after this load, it will be ignored.  We do
   // this instead of calling item_slots_used_.load() explicitly in the for loop
   // bounds checking, which would be expensive.
@@ -135,9 +145,11 @@
     const auto& item = items_[read_index];
     // Because we wait until |is_active| is set to consider an item active and
     // that field is always set last, we ignore half-created items.
-    if (item.is_active.load(std::memory_order_acquire)) {
-      (*items)[write_index++] = Item{
-          item.name_hash, item.key, item.value.load(std::memory_order_relaxed)};
+    if (item.is_active.load(std::memory_order_acquire) &&
+        (!item.thread_id.has_value() || item.thread_id == thread_id)) {
+      (*items)[write_index++] =
+          Item{item.name_hash, item.key, item.thread_id,
+               item.value.load(std::memory_order_relaxed)};
     }
   }
 
diff --git a/base/profiler/metadata_recorder.h b/base/profiler/metadata_recorder.h
index b1b7c5a..50093b21ee 100644
--- a/base/profiler/metadata_recorder.h
+++ b/base/profiler/metadata_recorder.h
@@ -12,6 +12,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
+#include "base/threading/platform_thread.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
@@ -129,7 +130,10 @@
   MetadataRecorder& operator=(const MetadataRecorder&) = delete;
 
   struct BASE_EXPORT Item {
-    Item(uint64_t name_hash, absl::optional<int64_t> key, int64_t value);
+    Item(uint64_t name_hash,
+         absl::optional<int64_t> key,
+         absl::optional<PlatformThreadId> thread_id,
+         int64_t value);
     Item();
 
     Item(const Item& other);
@@ -139,20 +143,28 @@
     uint64_t name_hash;
     // The key if specified when setting the item.
     absl::optional<int64_t> key;
+    // The thread_id is captured from the current thread for a thread-scoped
+    // item.
+    absl::optional<PlatformThreadId> thread_id;
     // The value of the metadata item.
     int64_t value;
   };
   static constexpr size_t MAX_METADATA_COUNT = 50;
   typedef std::array<Item, MAX_METADATA_COUNT> ItemArray;
 
-  // Sets a value for a (|name_hash|, |key|) pair, overwriting any value
-  // previously set for the pair. Nullopt keys are treated as just another key
-  // state for the purpose of associating values.
-  void Set(uint64_t name_hash, absl::optional<int64_t> key, int64_t value);
+  // Sets a value for a (|name_hash|, |key|, |thread_id|) tuple, overwriting any
+  // value previously set for the tuple. Nullopt keys are treated as just
+  // another key state for the purpose of associating values.
+  void Set(uint64_t name_hash,
+           absl::optional<int64_t> key,
+           absl::optional<PlatformThreadId> thread_id,
+           int64_t value);
 
   // Removes the item with the specified name hash and optional key. Has no
   // effect if such an item does not exist.
-  void Remove(uint64_t name_hash, absl::optional<int64_t> key);
+  void Remove(uint64_t name_hash,
+              absl::optional<int64_t> key,
+              absl::optional<PlatformThreadId> thread_id);
 
   // An object that provides access to a MetadataRecorder's items and holds the
   // necessary exclusive read lock until the object is destroyed. Reclaiming of
@@ -179,22 +191,25 @@
    public:
     // Acquires an exclusive read lock on the metadata recorder which is held
     // until the object is destroyed.
-    explicit MetadataProvider(MetadataRecorder* metadata_recorder)
+    explicit MetadataProvider(MetadataRecorder* metadata_recorder,
+                              PlatformThreadId thread_id)
         EXCLUSIVE_LOCK_FUNCTION(metadata_recorder_->read_lock_);
     ~MetadataProvider() UNLOCK_FUNCTION();
     MetadataProvider(const MetadataProvider&) = delete;
     MetadataProvider& operator=(const MetadataProvider&) = delete;
 
-    // Retrieves the first |available_slots| items in the metadata recorder and
-    // copies them into |items|, returning the number of metadata items that
-    // were copied. To ensure that all items can be copied, |available slots|
-    // should be greater than or equal to |MAX_METADATA_COUNT|. Requires
-    // NO_THREAD_SAFETY_ANALYSIS because clang's analyzer doesn't understand the
-    // cross-class locking used in this class' implementation.
+    // Retrieves the first |available_slots| items in the metadata recorder for
+    // |thread_id| and copies them into |items|, returning the number of
+    // metadata items that were copied. To ensure that all items can be copied,
+    // |available slots| should be greater than or equal to
+    // |MAX_METADATA_COUNT|. Requires NO_THREAD_SAFETY_ANALYSIS because clang's
+    // analyzer doesn't understand the cross-class locking used in this class'
+    // implementation.
     size_t GetItems(ItemArray* const items) const NO_THREAD_SAFETY_ANALYSIS;
 
    private:
     const raw_ptr<const MetadataRecorder> metadata_recorder_;
+    PlatformThreadId thread_id_;
     base::AutoLock auto_lock_;
   };
 
@@ -212,14 +227,15 @@
     // is marked as active.
     std::atomic<bool> is_active{false};
 
-    // Neither name_hash or key require atomicity or memory order constraints
-    // because no reader will attempt to read them mid-write. Specifically,
-    // readers wait until |is_active| is true to read them. Because |is_active|
-    // is always stored with a memory_order_release fence, we're guaranteed that
-    // |name_hash| and |key| will be finished writing before |is_active| is set
-    // to true.
+    // Neither name_hash, key or thread_id require atomicity or memory order
+    // constraints because no reader will attempt to read them mid-write.
+    // Specifically, readers wait until |is_active| is true to read them.
+    // Because |is_active| is always stored with a memory_order_release fence,
+    // we're guaranteed that |name_hash|, |key| and |thread_id| will be finished
+    // writing before |is_active| is set to true.
     uint64_t name_hash;
     absl::optional<int64_t> key;
+    absl::optional<PlatformThreadId> thread_id;
 
     // Requires atomic reads and writes to avoid word tearing when updating an
     // existing item unsynchronized. Does not require acquire/release semantics
@@ -240,7 +256,10 @@
       EXCLUSIVE_LOCKS_REQUIRED(write_lock_)
           EXCLUSIVE_LOCKS_REQUIRED(read_lock_);
 
-  size_t GetItems(ItemArray* const items) const
+  // Retrieves items in the metadata recorder that are active for |thread_id|
+  // and copies them into |items|, returning the number of metadata items that
+  // were copied.
+  size_t GetItems(ItemArray* const items, PlatformThreadId thread_id) const
       EXCLUSIVE_LOCKS_REQUIRED(read_lock_);
 
   // Metadata items that the recorder has seen. Rather than implementing the
diff --git a/base/profiler/metadata_recorder_unittest.cc b/base/profiler/metadata_recorder_unittest.cc
index 078736dd..82a4e90f 100644
--- a/base/profiler/metadata_recorder_unittest.cc
+++ b/base/profiler/metadata_recorder_unittest.cc
@@ -27,49 +27,59 @@
   MetadataRecorder recorder;
   MetadataRecorder::ItemArray items;
 
-  size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
-
-  EXPECT_EQ(0u, item_count);
+  EXPECT_EQ(0u, MetadataRecorder::MetadataProvider(&recorder,
+                                                   PlatformThread::CurrentId())
+                    .GetItems(&items));
+  EXPECT_EQ(0u, MetadataRecorder::MetadataProvider(&recorder,
+                                                   PlatformThread::CurrentId())
+                    .GetItems(&items));
 }
 
 TEST(MetadataRecorderTest, Set_NewNameHash) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, absl::nullopt, 20);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
 
   MetadataRecorder::ItemArray items;
   size_t item_count;
   {
-    item_count = MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+    item_count = MetadataRecorder::MetadataProvider(&recorder,
+                                                    PlatformThread::CurrentId())
+                     .GetItems(&items);
     ASSERT_EQ(1u, item_count);
     EXPECT_EQ(10u, items[0].name_hash);
     EXPECT_FALSE(items[0].key.has_value());
+    EXPECT_FALSE(items[0].thread_id.has_value());
     EXPECT_EQ(20, items[0].value);
   }
 
-  recorder.Set(20, absl::nullopt, 30);
+  recorder.Set(20, absl::nullopt, absl::nullopt, 30);
 
   {
-    item_count = MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+    item_count = MetadataRecorder::MetadataProvider(&recorder,
+                                                    PlatformThread::CurrentId())
+                     .GetItems(&items);
     ASSERT_EQ(2u, item_count);
     EXPECT_EQ(20u, items[1].name_hash);
     EXPECT_FALSE(items[1].key.has_value());
+    EXPECT_FALSE(items[1].thread_id.has_value());
     EXPECT_EQ(30, items[1].value);
   }
 }
 
 TEST(MetadataRecorderTest, Set_ExistingNameNash) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, 20);
-  recorder.Set(10, absl::nullopt, 30);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
   ASSERT_EQ(1u, item_count);
   EXPECT_EQ(10u, items[0].name_hash);
   EXPECT_FALSE(items[0].key.has_value());
+  EXPECT_FALSE(items[0].thread_id.has_value());
   EXPECT_EQ(30, items[0].value);
 }
 
@@ -78,19 +88,20 @@
   MetadataRecorder::ItemArray items;
   std::vector<MetadataRecorder::Item> expected;
   for (size_t i = 0; i < items.size(); ++i) {
-    expected.push_back(MetadataRecorder::Item{i, absl::nullopt, 0});
-    recorder.Set(i, absl::nullopt, 0);
+    expected.emplace_back(i, absl::nullopt, absl::nullopt, 0);
+    recorder.Set(i, absl::nullopt, absl::nullopt, 0);
   }
 
   // By removing an item from a full recorder, re-setting the same item, and
   // verifying that the item is returned, we can verify that the recorder is
   // reusing the inactive slot for the same name hash instead of trying (and
   // failing) to allocate a new slot.
-  recorder.Remove(3, absl::nullopt);
-  recorder.Set(3, absl::nullopt, 0);
+  recorder.Remove(3, absl::nullopt, absl::nullopt);
+  recorder.Set(3, absl::nullopt, absl::nullopt, 0);
 
   size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
   EXPECT_EQ(items.size(), item_count);
   EXPECT_THAT(expected, ::testing::UnorderedElementsAreArray(items));
 }
@@ -99,22 +110,24 @@
   MetadataRecorder recorder;
   MetadataRecorder::ItemArray items;
   for (size_t i = 0; i < items.size(); ++i) {
-    recorder.Set(i, absl::nullopt, 0);
+    recorder.Set(i, absl::nullopt, absl::nullopt, 0);
   }
 
   // This should fail silently.
-  recorder.Set(items.size(), absl::nullopt, 0);
+  recorder.Set(items.size(), absl::nullopt, absl::nullopt, 0);
 }
 
 TEST(MetadataRecorderTest, Set_NulloptKeyIsIndependentOfNonNulloptKey) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, 100, 20);
+  recorder.Set(10, 100, absl::nullopt, 20);
 
   MetadataRecorder::ItemArray items;
   size_t item_count;
   {
-    item_count = MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+    item_count = MetadataRecorder::MetadataProvider(&recorder,
+                                                    PlatformThread::CurrentId())
+                     .GetItems(&items);
     ASSERT_EQ(1u, item_count);
     EXPECT_EQ(10u, items[0].name_hash);
     ASSERT_TRUE(items[0].key.has_value());
@@ -122,10 +135,12 @@
     EXPECT_EQ(20, items[0].value);
   }
 
-  recorder.Set(10, absl::nullopt, 30);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
 
   {
-    item_count = MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+    item_count = MetadataRecorder::MetadataProvider(&recorder,
+                                                    PlatformThread::CurrentId())
+                     .GetItems(&items);
     ASSERT_EQ(2u, item_count);
 
     EXPECT_EQ(10u, items[0].name_hash);
@@ -139,16 +154,65 @@
   }
 }
 
-TEST(MetadataRecorderTest, Remove) {
+TEST(MetadataRecorderTest, Set_ThreadIdIsScoped) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, 20);
-  recorder.Set(30, absl::nullopt, 40);
-  recorder.Set(50, absl::nullopt, 60);
-  recorder.Remove(30, absl::nullopt);
+
+  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
+
+  MetadataRecorder::ItemArray items;
+  size_t item_count;
+  {
+    item_count = MetadataRecorder::MetadataProvider(&recorder,
+                                                    PlatformThread::CurrentId())
+                     .GetItems(&items);
+    ASSERT_EQ(1u, item_count);
+    EXPECT_EQ(10u, items[0].name_hash);
+    EXPECT_FALSE(items[0].key.has_value());
+    ASSERT_TRUE(items[0].thread_id.has_value());
+    EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
+    EXPECT_EQ(20, items[0].value);
+  }
+  {
+    item_count = MetadataRecorder::MetadataProvider(&recorder, kInvalidThreadId)
+                     .GetItems(&items);
+    EXPECT_EQ(0U, item_count);
+  }
+}
+
+TEST(MetadataRecorderTest, Set_NulloptThreadAndNonNulloptThread) {
+  MetadataRecorder recorder;
+
+  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
+  ASSERT_EQ(2u, item_count);
+  EXPECT_EQ(10u, items[0].name_hash);
+  EXPECT_FALSE(items[0].key.has_value());
+  ASSERT_TRUE(items[0].thread_id.has_value());
+  EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
+  EXPECT_EQ(20, items[0].value);
+
+  EXPECT_EQ(10u, items[1].name_hash);
+  EXPECT_FALSE(items[1].key.has_value());
+  EXPECT_FALSE(items[1].thread_id.has_value());
+  EXPECT_EQ(30, items[1].value);
+}
+
+TEST(MetadataRecorderTest, Remove) {
+  MetadataRecorder recorder;
+  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
+  recorder.Set(30, absl::nullopt, absl::nullopt, 40);
+  recorder.Set(50, absl::nullopt, absl::nullopt, 60);
+  recorder.Remove(30, absl::nullopt, absl::nullopt);
+
+  MetadataRecorder::ItemArray items;
+  size_t item_count =
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
   ASSERT_EQ(2u, item_count);
   EXPECT_EQ(10u, items[0].name_hash);
   EXPECT_FALSE(items[0].key.has_value());
@@ -160,12 +224,13 @@
 
 TEST(MetadataRecorderTest, Remove_DoesntExist) {
   MetadataRecorder recorder;
-  recorder.Set(10, absl::nullopt, 20);
-  recorder.Remove(20, absl::nullopt);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 20);
+  recorder.Remove(20, absl::nullopt, absl::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
   ASSERT_EQ(1u, item_count);
   EXPECT_EQ(10u, items[0].name_hash);
   EXPECT_FALSE(items[0].key.has_value());
@@ -175,14 +240,15 @@
 TEST(MetadataRecorderTest, Remove_NulloptKeyIsIndependentOfNonNulloptKey) {
   MetadataRecorder recorder;
 
-  recorder.Set(10, 100, 20);
-  recorder.Set(10, absl::nullopt, 30);
+  recorder.Set(10, 100, absl::nullopt, 20);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
 
-  recorder.Remove(10, absl::nullopt);
+  recorder.Remove(10, absl::nullopt, absl::nullopt);
 
   MetadataRecorder::ItemArray items;
   size_t item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
   ASSERT_EQ(1u, item_count);
   EXPECT_EQ(10u, items[0].name_hash);
   ASSERT_TRUE(items[0].key.has_value());
@@ -190,31 +256,52 @@
   EXPECT_EQ(20, items[0].value);
 }
 
+TEST(MetadataRecorderTest,
+     Remove_NulloptThreadIsIndependentOfNonNulloptThread) {
+  MetadataRecorder recorder;
+
+  recorder.Set(10, absl::nullopt, PlatformThread::CurrentId(), 20);
+  recorder.Set(10, absl::nullopt, absl::nullopt, 30);
+
+  recorder.Remove(10, absl::nullopt, absl::nullopt);
+
+  MetadataRecorder::ItemArray items;
+  size_t item_count =
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&items);
+  ASSERT_EQ(1u, item_count);
+  EXPECT_EQ(10u, items[0].name_hash);
+  EXPECT_FALSE(items[0].key.has_value());
+  ASSERT_TRUE(items[0].thread_id.has_value());
+  EXPECT_EQ(PlatformThread::CurrentId(), *items[0].thread_id);
+  EXPECT_EQ(20, items[0].value);
+}
+
 TEST(MetadataRecorderTest, ReclaimInactiveSlots) {
   MetadataRecorder recorder;
 
   std::set<MetadataRecorder::Item> items_set;
   // Fill up the metadata map.
   for (size_t i = 0; i < MetadataRecorder::MAX_METADATA_COUNT; ++i) {
-    recorder.Set(i, absl::nullopt, i);
-    items_set.insert(
-        MetadataRecorder::Item{i, absl::nullopt, static_cast<int64_t>(i)});
+    recorder.Set(i, absl::nullopt, absl::nullopt, i);
+    items_set.insert(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
+                                            static_cast<int64_t>(i)});
   }
 
   // Remove every fourth entry to fragment the data.
   size_t entries_removed = 0;
   for (size_t i = 3; i < MetadataRecorder::MAX_METADATA_COUNT; i += 4) {
-    recorder.Remove(i, absl::nullopt);
+    recorder.Remove(i, absl::nullopt, absl::nullopt);
     ++entries_removed;
-    items_set.erase(
-        MetadataRecorder::Item{i, absl::nullopt, static_cast<int64_t>(i)});
+    items_set.erase(MetadataRecorder::Item{i, absl::nullopt, absl::nullopt,
+                                           static_cast<int64_t>(i)});
   }
 
   // Ensure that the inactive slots are reclaimed to make room for more entries.
   for (size_t i = 1; i <= entries_removed; ++i) {
-    recorder.Set(i * 100, absl::nullopt, i * 100);
-    items_set.insert(MetadataRecorder::Item{i * 100, absl::nullopt,
-                                            static_cast<int64_t>(i * 100)});
+    recorder.Set(i * 100, absl::nullopt, absl::nullopt, i * 100);
+    items_set.insert(MetadataRecorder::Item{
+        i * 100, absl::nullopt, absl::nullopt, static_cast<int64_t>(i * 100)});
   }
 
   MetadataRecorder::ItemArray items_arr;
@@ -222,7 +309,8 @@
 
   MetadataRecorder::ItemArray recorder_items;
   size_t recorder_item_count =
-      MetadataRecorder::MetadataProvider(&recorder).GetItems(&recorder_items);
+      MetadataRecorder::MetadataProvider(&recorder, PlatformThread::CurrentId())
+          .GetItems(&recorder_items);
   EXPECT_EQ(recorder_item_count, MetadataRecorder::MAX_METADATA_COUNT);
   EXPECT_THAT(recorder_items, ::testing::UnorderedElementsAreArray(items_arr));
 }
@@ -232,7 +320,7 @@
   HistogramTester histogram_tester;
 
   for (size_t i = 0; i < MetadataRecorder::MAX_METADATA_COUNT; ++i) {
-    recorder.Set(i * 10, absl::nullopt, i * 100);
+    recorder.Set(i * 10, absl::nullopt, absl::nullopt, i * 100);
   }
 
   EXPECT_THAT(
diff --git a/base/profiler/sample_metadata.cc b/base/profiler/sample_metadata.cc
index 070ee6c..6685a103 100644
--- a/base/profiler/sample_metadata.cc
+++ b/base/profiler/sample_metadata.cc
@@ -7,71 +7,100 @@
 #include "base/metrics/metrics_hashes.h"
 #include "base/no_destructor.h"
 #include "base/profiler/stack_sampling_profiler.h"
+#include "base/threading/thread_local.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 
-SampleMetadata::SampleMetadata(StringPiece name)
-    : name_hash_(HashMetricName(name)) {}
+namespace {
+
+absl::optional<PlatformThreadId> GetPlatformThreadIdForScope(
+    SampleMetadataScope scope) {
+  if (scope == SampleMetadataScope::kProcess)
+    return absl::nullopt;
+  return PlatformThread::CurrentId();
+}
+
+}  // namespace
+
+SampleMetadata::SampleMetadata(StringPiece name, SampleMetadataScope scope)
+    : name_hash_(HashMetricName(name)), scope_(scope) {}
 
 void SampleMetadata::Set(int64_t value) {
-  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt, value);
+  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt,
+                                   GetPlatformThreadIdForScope(scope_), value);
 }
 
 void SampleMetadata::Set(int64_t key, int64_t value) {
-  GetSampleMetadataRecorder()->Set(name_hash_, key, value);
+  GetSampleMetadataRecorder()->Set(name_hash_, key,
+                                   GetPlatformThreadIdForScope(scope_), value);
 }
 
 void SampleMetadata::Remove() {
-  GetSampleMetadataRecorder()->Remove(name_hash_, absl::nullopt);
+  GetSampleMetadataRecorder()->Remove(name_hash_, absl::nullopt,
+                                      GetPlatformThreadIdForScope(scope_));
 }
 
 void SampleMetadata::Remove(int64_t key) {
-  GetSampleMetadataRecorder()->Remove(name_hash_, key);
+  GetSampleMetadataRecorder()->Remove(name_hash_, key,
+                                      GetPlatformThreadIdForScope(scope_));
 }
 
-ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name, int64_t value)
-    : name_hash_(HashMetricName(name)) {
-  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt, value);
+ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name,
+                                           int64_t value,
+                                           SampleMetadataScope scope)
+    : name_hash_(HashMetricName(name)),
+      thread_id_(GetPlatformThreadIdForScope(scope)) {
+  GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt, thread_id_,
+                                   value);
 }
 
 ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name,
                                            int64_t key,
-                                           int64_t value)
-    : name_hash_(HashMetricName(name)), key_(key) {
-  GetSampleMetadataRecorder()->Set(name_hash_, key, value);
+                                           int64_t value,
+                                           SampleMetadataScope scope)
+    : name_hash_(HashMetricName(name)),
+      key_(key),
+      thread_id_(GetPlatformThreadIdForScope(scope)) {
+  GetSampleMetadataRecorder()->Set(name_hash_, key, thread_id_, value);
 }
 
 ScopedSampleMetadata::~ScopedSampleMetadata() {
-  GetSampleMetadataRecorder()->Remove(name_hash_, key_);
+  GetSampleMetadataRecorder()->Remove(name_hash_, key_, thread_id_);
 }
 
 // This function is friended by StackSamplingProfiler so must live directly in
 // the base namespace.
-void ApplyMetadataToPastSamplesImpl(TimeTicks period_start,
-                                    TimeTicks period_end,
-                                    int64_t name_hash,
-                                    absl::optional<int64_t> key,
-                                    int64_t value) {
-  StackSamplingProfiler::ApplyMetadataToPastSamples(period_start, period_end,
-                                                    name_hash, key, value);
+void ApplyMetadataToPastSamplesImpl(
+    TimeTicks period_start,
+    TimeTicks period_end,
+    int64_t name_hash,
+    absl::optional<int64_t> key,
+    int64_t value,
+    absl::optional<PlatformThreadId> thread_id) {
+  StackSamplingProfiler::ApplyMetadataToPastSamples(
+      period_start, period_end, name_hash, key, value, thread_id);
 }
 
 void ApplyMetadataToPastSamples(TimeTicks period_start,
                                 TimeTicks period_end,
                                 StringPiece name,
-                                int64_t value) {
+                                int64_t value,
+                                SampleMetadataScope scope) {
   return ApplyMetadataToPastSamplesImpl(
-      period_start, period_end, HashMetricName(name), absl::nullopt, value);
+      period_start, period_end, HashMetricName(name), absl::nullopt, value,
+      GetPlatformThreadIdForScope(scope));
 }
 
 void ApplyMetadataToPastSamples(TimeTicks period_start,
                                 TimeTicks period_end,
                                 StringPiece name,
                                 int64_t key,
-                                int64_t value) {
+                                int64_t value,
+                                SampleMetadataScope scope) {
   return ApplyMetadataToPastSamplesImpl(period_start, period_end,
-                                        HashMetricName(name), key, value);
+                                        HashMetricName(name), key, value,
+                                        GetPlatformThreadIdForScope(scope));
 }
 
 MetadataRecorder* GetSampleMetadataRecorder() {
diff --git a/base/profiler/sample_metadata.h b/base/profiler/sample_metadata.h
index 57a6db4..38788e6 100644
--- a/base/profiler/sample_metadata.h
+++ b/base/profiler/sample_metadata.h
@@ -7,6 +7,7 @@
 
 #include "base/profiler/metadata_recorder.h"
 #include "base/strings/string_piece.h"
+#include "base/threading/platform_thread.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 // -----------------------------------------------------------------------------
@@ -15,8 +16,8 @@
 //
 // Overview:
 // These functions provide a means to control the metadata attached to samples
-// collected by the stack sampling profiler. Metadata state is shared between
-// all threads within a process.
+// collected by the stack sampling profiler. SampleMetadataScope controls the
+// scope covered by the metadata (thread, process).
 //
 // Any samples collected by the sampling profiler will include the active
 // metadata. This enables us to later analyze targeted subsets of samples
@@ -55,10 +56,20 @@
 
 class TimeTicks;
 
+enum class SampleMetadataScope {
+  // All threads in the current process will have the associated metadata
+  // attached to their samples.
+  kProcess,
+  // The metadata will only be attached to samples for the current thread.
+  kThread
+};
+
 class BASE_EXPORT SampleMetadata {
  public:
-  // Set the metadata value associated with |name|.
-  explicit SampleMetadata(StringPiece name);
+  // Set the metadata value associated with |name| to be recorded for |scope|.
+  explicit SampleMetadata(
+      StringPiece name,
+      SampleMetadataScope scope = SampleMetadataScope::kProcess);
 
   SampleMetadata(const SampleMetadata&) = default;
   ~SampleMetadata() = default;
@@ -96,21 +107,32 @@
 
  private:
   const uint64_t name_hash_;
+  // Scope is kept as-is instead of retrieving a PlatformThreadId in case
+  // Set()/Remove() is called on a thread different from where the object was
+  // constructed.
+  const SampleMetadataScope scope_;
 };
 
 class BASE_EXPORT ScopedSampleMetadata {
  public:
-  // Set the metadata value associated with |name|.
-  ScopedSampleMetadata(StringPiece name, int64_t value);
+  // Set the metadata value associated with |name| for |scope|.
+  ScopedSampleMetadata(
+      StringPiece name,
+      int64_t value,
+      SampleMetadataScope scope = SampleMetadataScope::kProcess);
 
-  // Set the metadata value associated with the pair (|name|, |key|). This
-  // constructor allows the metadata to be associated with an additional
-  // user-defined key. One might supply a key based on the frame id, for
-  // example, to distinguish execution in service of scrolling between different
-  // frames. Prefer the previous constructor if no user-defined metadata is
-  // required. Note: values specified for a name and key are stored separately
-  // from values specified with only a name.
-  ScopedSampleMetadata(StringPiece name, int64_t key, int64_t value);
+  // Set the metadata value associated with the pair (|name|, |key|) for
+  // |scope|. This constructor allows the metadata to be associated with an
+  // additional user-defined key. One might supply a key based on the frame id,
+  // for example, to distinguish execution in service of scrolling between
+  // different frames. Prefer the previous constructor if no user-defined
+  // metadata is required. Note: values specified for a name and key are stored
+  // separately from values specified with only a name.
+  ScopedSampleMetadata(
+      StringPiece name,
+      int64_t key,
+      int64_t value,
+      SampleMetadataScope scope = SampleMetadataScope::kProcess);
 
   ScopedSampleMetadata(const ScopedSampleMetadata&) = delete;
   ~ScopedSampleMetadata();
@@ -120,6 +142,7 @@
  private:
   const uint64_t name_hash_;
   absl::optional<int64_t> key_;
+  absl::optional<PlatformThreadId> thread_id_;
 };
 
 // Applies the specified metadata to samples already recorded between
@@ -131,15 +154,19 @@
 // metadata scope (i.e. because the start or end of execution was missed), at
 // the cost of missing execution that are longer than the profiling period, or
 // extend before or after it. |period_end| must be <= TimeTicks::Now().
-BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
-                                            TimeTicks period_end,
-                                            StringPiece name,
-                                            int64_t value);
-BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
-                                            TimeTicks period_end,
-                                            StringPiece name,
-                                            int64_t key,
-                                            int64_t value);
+BASE_EXPORT void ApplyMetadataToPastSamples(
+    TimeTicks period_start,
+    TimeTicks period_end,
+    StringPiece name,
+    int64_t value,
+    SampleMetadataScope scope = SampleMetadataScope::kProcess);
+BASE_EXPORT void ApplyMetadataToPastSamples(
+    TimeTicks period_start,
+    TimeTicks period_end,
+    StringPiece name,
+    int64_t key,
+    int64_t value,
+    SampleMetadataScope scope = SampleMetadataScope::kProcess);
 
 // Returns the process-global metadata recorder instance used for tracking
 // sampling profiler metadata.
diff --git a/base/profiler/sample_metadata_unittest.cc b/base/profiler/sample_metadata_unittest.cc
index 7c76ce4e..36efb79 100644
--- a/base/profiler/sample_metadata_unittest.cc
+++ b/base/profiler/sample_metadata_unittest.cc
@@ -5,77 +5,87 @@
 #include "base/profiler/sample_metadata.h"
 
 #include "base/metrics/metrics_hashes.h"
+#include "base/threading/platform_thread.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
 
 TEST(SampleMetadataTest, ScopedSampleMetadata) {
   MetadataRecorder::ItemArray items;
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 
   {
     ScopedSampleMetadata m("myname", 100);
 
-    ASSERT_EQ(1u,
-              MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
-                  .GetItems(&items));
+    ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(
+                      GetSampleMetadataRecorder(), PlatformThread::CurrentId())
+                      .GetItems(&items));
     EXPECT_EQ(HashMetricName("myname"), items[0].name_hash);
     EXPECT_FALSE(items[0].key.has_value());
     EXPECT_EQ(100, items[0].value);
   }
 
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 }
 
 TEST(SampleMetadataTest, ScopedSampleMetadataWithKey) {
   MetadataRecorder::ItemArray items;
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 
   {
     ScopedSampleMetadata m("myname", 10, 100);
 
-    ASSERT_EQ(1u,
-              MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
-                  .GetItems(&items));
+    ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(
+                      GetSampleMetadataRecorder(), PlatformThread::CurrentId())
+                      .GetItems(&items));
     EXPECT_EQ(HashMetricName("myname"), items[0].name_hash);
     ASSERT_TRUE(items[0].key.has_value());
     EXPECT_EQ(10, *items[0].key);
     EXPECT_EQ(100, items[0].value);
   }
 
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 }
 
 TEST(SampleMetadataTest, SampleMetadata) {
   MetadataRecorder::ItemArray items;
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 
   SampleMetadata metadata("myname");
   metadata.Set(100);
-  ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
   EXPECT_EQ(HashMetricName("myname"), items[0].name_hash);
   EXPECT_FALSE(items[0].key.has_value());
   EXPECT_EQ(100, items[0].value);
 
   metadata.Remove();
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 }
 
 TEST(SampleMetadataTest, SampleMetadataWithKey) {
   MetadataRecorder::ItemArray items;
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 
   SampleMetadata metadata("myname");
   metadata.Set(10, 100);
-  ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
   EXPECT_EQ(HashMetricName("myname"), items[0].name_hash);
   ASSERT_TRUE(items[0].key.has_value());
@@ -83,7 +93,32 @@
   EXPECT_EQ(100, items[0].value);
 
   metadata.Remove(10);
-  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder())
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
+                    .GetItems(&items));
+}
+
+TEST(SampleMetadataTest, SampleMetadataWithThreadId) {
+  MetadataRecorder::ItemArray items;
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
+                    .GetItems(&items));
+
+  SampleMetadata metadata("myname", SampleMetadataScope::kThread);
+  metadata.Set(100);
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   kInvalidThreadId)
+                    .GetItems(&items));
+  ASSERT_EQ(1u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
+                    .GetItems(&items));
+  EXPECT_EQ(HashMetricName("myname"), items[0].name_hash);
+  EXPECT_FALSE(items[0].key.has_value());
+  EXPECT_EQ(100, items[0].value);
+
+  metadata.Remove();
+  ASSERT_EQ(0u, MetadataRecorder::MetadataProvider(GetSampleMetadataRecorder(),
+                                                   PlatformThread::CurrentId())
                     .GetItems(&items));
 }
 
diff --git a/base/profiler/stack_sampler.h b/base/profiler/stack_sampler.h
index 54d8ab2..4dca2e8 100644
--- a/base/profiler/stack_sampler.h
+++ b/base/profiler/stack_sampler.h
@@ -67,7 +67,8 @@
 
   // Records a set of frames and returns them.
   virtual void RecordStackFrames(StackBuffer* stackbuffer,
-                                 ProfileBuilder* profile_builder) = 0;
+                                 ProfileBuilder* profile_builder,
+                                 PlatformThreadId thread_id) = 0;
 
  protected:
   StackSampler();
diff --git a/base/profiler/stack_sampler_impl.cc b/base/profiler/stack_sampler_impl.cc
index 4dcdf75..72bb2d1 100644
--- a/base/profiler/stack_sampler_impl.cc
+++ b/base/profiler/stack_sampler_impl.cc
@@ -108,7 +108,8 @@
 }
 
 void StackSamplerImpl::RecordStackFrames(StackBuffer* stack_buffer,
-                                         ProfileBuilder* profile_builder) {
+                                         ProfileBuilder* profile_builder,
+                                         PlatformThreadId thread_id) {
   DCHECK(stack_buffer);
 
   if (record_sample_callback_)
@@ -123,7 +124,7 @@
     // Make this scope as small as possible because |metadata_provider| is
     // holding a lock.
     MetadataRecorder::MetadataProvider metadata_provider(
-        GetSampleMetadataRecorder());
+        GetSampleMetadataRecorder(), thread_id);
     StackCopierDelegate delegate(&unwinders_, profile_builder,
                                  &metadata_provider);
     copy_stack_succeeded = stack_copier_->CopyStack(
diff --git a/base/profiler/stack_sampler_impl.h b/base/profiler/stack_sampler_impl.h
index 7894d98..6bdf89f 100644
--- a/base/profiler/stack_sampler_impl.h
+++ b/base/profiler/stack_sampler_impl.h
@@ -39,7 +39,8 @@
   void Initialize() override;
   void AddAuxUnwinder(std::unique_ptr<Unwinder> unwinder) override;
   void RecordStackFrames(StackBuffer* stack_buffer,
-                         ProfileBuilder* profile_builder) override;
+                         ProfileBuilder* profile_builder,
+                         PlatformThreadId thread_id) override;
 
   // Exposes the internal function for unit testing.
   static std::vector<Frame> WalkStackForTesting(
diff --git a/base/profiler/stack_sampler_impl_unittest.cc b/base/profiler/stack_sampler_impl_unittest.cc
index 19c83965..ad8bae3 100644
--- a/base/profiler/stack_sampler_impl_unittest.cc
+++ b/base/profiler/stack_sampler_impl_unittest.cc
@@ -294,7 +294,8 @@
   std::unique_ptr<StackBuffer> stack_buffer =
       std::make_unique<StackBuffer>(stack.size() * sizeof(uintptr_t));
   TestProfileBuilder profile_builder(&module_cache);
-  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder);
+  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder,
+                                       PlatformThread::CurrentId());
 
   EXPECT_EQ(stack, stack_copy);
 }
@@ -316,7 +317,8 @@
   std::unique_ptr<StackBuffer> stack_buffer =
       std::make_unique<StackBuffer>(stack.size() * sizeof(uintptr_t));
   TestProfileBuilder profile_builder(&module_cache);
-  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder);
+  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder,
+                                       PlatformThread::CurrentId());
 
   EXPECT_EQ(timestamp, profile_builder.last_timestamp());
 }
@@ -333,7 +335,8 @@
 
   stack_sampler_impl.Initialize();
 
-  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder);
+  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder,
+                                       PlatformThread::CurrentId());
 
   EXPECT_TRUE(unwinder->on_stack_capture_was_invoked());
   EXPECT_TRUE(unwinder->update_modules_was_invoked());
@@ -354,7 +357,8 @@
   CallRecordingUnwinder* aux_unwinder = owned_aux_unwinder.get();
   stack_sampler_impl.AddAuxUnwinder(std::move(owned_aux_unwinder));
 
-  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder);
+  stack_sampler_impl.RecordStackFrames(stack_buffer.get(), &profile_builder,
+                                       PlatformThread::CurrentId());
 
   EXPECT_TRUE(aux_unwinder->on_stack_capture_was_invoked());
   EXPECT_TRUE(aux_unwinder->update_modules_was_invoked());
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index dc3a13d..2eec075 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -120,11 +120,13 @@
   };
 
   struct CollectionContext {
-    CollectionContext(const SamplingParams& params,
+    CollectionContext(PlatformThreadId thread_id,
+                      const SamplingParams& params,
                       WaitableEvent* finished,
                       std::unique_ptr<StackSampler> sampler,
                       std::unique_ptr<ProfileBuilder> profile_builder)
         : collection_id(next_collection_id.GetNext()),
+          thread_id(thread_id),
           params(params),
           finished(finished),
           profile_builder(std::move(profile_builder)),
@@ -134,6 +136,7 @@
     // An identifier for this collection, used to uniquely identify the
     // collection to outside interests.
     const int collection_id;
+    const PlatformThreadId thread_id;  // Thread id of the sampled thread.
 
     const SamplingParams params;    // Information about how to sample.
     const raw_ptr<WaitableEvent>
@@ -178,7 +181,8 @@
                                   base::TimeTicks period_end,
                                   int64_t name_hash,
                                   absl::optional<int64_t> key,
-                                  int64_t value);
+                                  int64_t value,
+                                  absl::optional<PlatformThreadId> thread_id);
 
   // Removes an active collection based on its collection id, forcing it to run
   // its callback if any data has been collected. This can be called externally
@@ -231,11 +235,13 @@
   void AddCollectionTask(std::unique_ptr<CollectionContext> collection);
   void AddAuxUnwinderTask(int collection_id,
                           std::unique_ptr<Unwinder> unwinder);
-  void ApplyMetadataToPastSamplesTask(base::TimeTicks period_start,
-                                      base::TimeTicks period_end,
-                                      int64_t name_hash,
-                                      absl::optional<int64_t> key,
-                                      int64_t value);
+  void ApplyMetadataToPastSamplesTask(
+      base::TimeTicks period_start,
+      base::TimeTicks period_end,
+      int64_t name_hash,
+      absl::optional<int64_t> key,
+      int64_t value,
+      absl::optional<PlatformThreadId> thread_id);
   void RemoveCollectionTask(int collection_id);
   void RecordSampleTask(int collection_id);
   void ShutdownTask(int add_events);
@@ -402,7 +408,8 @@
     base::TimeTicks period_end,
     int64_t name_hash,
     absl::optional<int64_t> key,
-    int64_t value) {
+    int64_t value,
+    absl::optional<PlatformThreadId> thread_id) {
   ThreadExecutionState state;
   scoped_refptr<SingleThreadTaskRunner> task_runner = GetTaskRunner(&state);
   if (state != RUNNING)
@@ -411,7 +418,7 @@
   task_runner->PostTask(
       FROM_HERE, BindOnce(&SamplingThread::ApplyMetadataToPastSamplesTask,
                           Unretained(this), period_start, period_end, name_hash,
-                          key, value));
+                          key, value, thread_id));
 }
 
 void StackSamplingProfiler::SamplingThread::Remove(int collection_id) {
@@ -570,10 +577,13 @@
     base::TimeTicks period_end,
     int64_t name_hash,
     absl::optional<int64_t> key,
-    int64_t value) {
+    int64_t value,
+    absl::optional<PlatformThreadId> thread_id) {
   DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
-  MetadataRecorder::Item item(name_hash, key, value);
+  MetadataRecorder::Item item(name_hash, key, thread_id, value);
   for (auto& id_collection_pair : active_collections_) {
+    if (thread_id && id_collection_pair.second->thread_id != thread_id)
+      continue;
     id_collection_pair.second->profile_builder->ApplyMetadataRetrospectively(
         period_start, period_end, item);
   }
@@ -642,7 +652,8 @@
 
   // Record a single sample.
   collection->sampler->RecordStackFrames(stack_buffer_.get(),
-                                         collection->profile_builder.get());
+                                         collection->profile_builder.get(),
+                                         collection->thread_id);
 
   // Schedule the next sample recording if there is one.
   if (++collection->sample_count < collection->params.samples_per_profile) {
@@ -778,7 +789,10 @@
     UnwindersFactory core_unwinders_factory,
     RepeatingClosure record_sample_callback,
     StackSamplerTestDelegate* test_delegate)
-    : StackSamplingProfiler(params, std::move(profile_builder), nullptr) {
+    : StackSamplingProfiler(thread_token,
+                            params,
+                            std::move(profile_builder),
+                            std::unique_ptr<StackSampler>()) {
   sampler_ =
       StackSampler::Create(thread_token, profile_builder_->GetModuleCache(),
                            std::move(core_unwinders_factory),
@@ -786,10 +800,12 @@
 }
 
 StackSamplingProfiler::StackSamplingProfiler(
+    SamplingProfilerThreadToken thread_token,
     const SamplingParams& params,
     std::unique_ptr<ProfileBuilder> profile_builder,
     std::unique_ptr<StackSampler> sampler)
-    : params_(params),
+    : thread_token_(thread_token),
+      params_(params),
       profile_builder_(std::move(profile_builder)),
       sampler_(std::move(sampler)),
       // The event starts "signaled" so code knows it's safe to start thread
@@ -852,7 +868,7 @@
   DCHECK_EQ(kNullProfilerId, profiler_id_);
   profiler_id_ = SamplingThread::GetInstance()->Add(
       std::make_unique<SamplingThread::CollectionContext>(
-          params_, &profiling_inactive_, std::move(sampler_),
+          thread_token_.id, params_, &profiling_inactive_, std::move(sampler_),
           std::move(profile_builder_)));
   DCHECK_NE(kNullProfilerId, profiler_id_);
 
@@ -887,9 +903,10 @@
     base::TimeTicks period_end,
     int64_t name_hash,
     absl::optional<int64_t> key,
-    int64_t value) {
+    int64_t value,
+    absl::optional<PlatformThreadId> thread_id) {
   SamplingThread::GetInstance()->ApplyMetadataToPastSamples(
-      period_start, period_end, name_hash, key, value);
+      period_start, period_end, name_hash, key, value, thread_id);
 }
 
 }  // namespace base
diff --git a/base/profiler/stack_sampling_profiler.h b/base/profiler/stack_sampling_profiler.h
index c36deb5..2435b40 100644
--- a/base/profiler/stack_sampling_profiler.h
+++ b/base/profiler/stack_sampling_profiler.h
@@ -111,7 +111,8 @@
 
   // Same as above function, with custom |sampler| implementation. The sampler
   // on Android is not implemented in base.
-  StackSamplingProfiler(const SamplingParams& params,
+  StackSamplingProfiler(SamplingProfilerThreadToken thread_token,
+                        const SamplingParams& params,
                         std::unique_ptr<ProfileBuilder> profile_builder,
                         std::unique_ptr<StackSampler> sampler);
 
@@ -182,19 +183,23 @@
 
   // Friend the global function from sample_metadata.cc so that it can call into
   // the function below.
-  friend void ApplyMetadataToPastSamplesImpl(TimeTicks period_start,
-                                             TimeTicks period_end,
-                                             int64_t name_hash,
-                                             absl::optional<int64_t> key,
-                                             int64_t value);
+  friend void ApplyMetadataToPastSamplesImpl(
+      TimeTicks period_start,
+      TimeTicks period_end,
+      int64_t name_hash,
+      absl::optional<int64_t> key,
+      int64_t value,
+      absl::optional<PlatformThreadId> thread_id);
 
   // Apply metadata to already recorded samples. See the
   // ApplyMetadataToPastSamples() docs in sample_metadata.h.
-  static void ApplyMetadataToPastSamples(TimeTicks period_start,
-                                         TimeTicks period_end,
-                                         int64_t name_hash,
-                                         absl::optional<int64_t> key,
-                                         int64_t value);
+  static void ApplyMetadataToPastSamples(
+      TimeTicks period_start,
+      TimeTicks period_end,
+      int64_t name_hash,
+      absl::optional<int64_t> key,
+      int64_t value,
+      absl::optional<PlatformThreadId> thread_id);
 
   // The thread whose stack will be sampled.
   SamplingProfilerThreadToken thread_token_;
diff --git a/base/profiler/stack_sampling_profiler_test_util.cc b/base/profiler/stack_sampling_profiler_test_util.cc
index 975ee98..b00a2ab 100644
--- a/base/profiler/stack_sampling_profiler_test_util.cc
+++ b/base/profiler/stack_sampling_profiler_test_util.cc
@@ -161,6 +161,14 @@
 
 TargetThread::~TargetThread() = default;
 
+void TargetThread::Start() {
+  EXPECT_TRUE(PlatformThread::Create(0, this, &target_thread_handle_));
+}
+
+void TargetThread::Join() {
+  PlatformThread::Join(target_thread_handle_);
+}
+
 void TargetThread::ThreadMain() {
   thread_token_ = GetSamplingProfilerCurrentThreadToken();
   std::move(to_run_).Run();
@@ -281,16 +289,13 @@
   TargetThread target_thread(
       BindLambdaForTesting([&]() { scenario->Execute(&events); }));
 
-  PlatformThreadHandle target_thread_handle;
-  EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle));
-
+  target_thread.Start();
   events.ready_for_sample.Wait();
 
   std::move(profile_callback).Run(target_thread.thread_token());
 
   events.sample_finished.Signal();
-
-  PlatformThread::Join(target_thread_handle);
+  target_thread.Join();
 }
 
 std::vector<Frame> SampleScenario(UnwindScenario* scenario,
diff --git a/base/profiler/stack_sampling_profiler_test_util.h b/base/profiler/stack_sampling_profiler_test_util.h
index c23200ec..057921ce 100644
--- a/base/profiler/stack_sampling_profiler_test_util.h
+++ b/base/profiler/stack_sampling_profiler_test_util.h
@@ -26,13 +26,16 @@
 // A thread to target for profiling that will run the supplied closure.
 class TargetThread : public PlatformThread::Delegate {
  public:
-  TargetThread(OnceClosure to_run);
+  explicit TargetThread(OnceClosure to_run);
 
   TargetThread(const TargetThread&) = delete;
   TargetThread& operator=(const TargetThread&) = delete;
 
   ~TargetThread() override;
 
+  void Start();
+  void Join();
+
   // PlatformThread::Delegate:
   void ThreadMain() override;
 
@@ -41,6 +44,7 @@
  private:
   SamplingProfilerThreadToken thread_token_ = {0};
   OnceClosure to_run_;
+  PlatformThreadHandle target_thread_handle_;
 };
 
 // Addresses near the start and end of a function.
diff --git a/base/profiler/stack_sampling_profiler_unittest.cc b/base/profiler/stack_sampling_profiler_unittest.cc
index 7e5a145..f2a2cc1 100644
--- a/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/base/profiler/stack_sampling_profiler_unittest.cc
@@ -310,10 +310,7 @@
   UnwindScenario::SampleEvents events;
   TargetThread target_thread(
       BindLambdaForTesting([&]() { scenario.Execute(&events); }));
-
-  PlatformThreadHandle target_thread_handle;
-  EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle));
-
+  target_thread.Start();
   events.ready_for_sample.Wait();
 
   WaitableEvent sampling_thread_completed(
@@ -347,7 +344,7 @@
   // Cause the target thread to finish, so that it's no longer executing code in
   // the library we're about to unload.
   events.sample_finished.Signal();
-  PlatformThread::Join(target_thread_handle);
+  target_thread.Join();
 
   // Unload the library now that it's not being used.
   if (wait_until_unloaded)
@@ -1133,19 +1130,14 @@
   UnwindScenario::SampleEvents events1;
   TargetThread target_thread1(
       BindLambdaForTesting([&]() { scenario1.Execute(&events1); }));
-  PlatformThreadHandle target_thread_handle1;
-  EXPECT_TRUE(
-      PlatformThread::Create(0, &target_thread1, &target_thread_handle1));
+  target_thread1.Start();
   events1.ready_for_sample.Wait();
 
   UnwindScenario scenario2(BindRepeating(&CallWithPlainFunction));
   UnwindScenario::SampleEvents events2;
   TargetThread target_thread2(
       BindLambdaForTesting([&]() { scenario2.Execute(&events2); }));
-
-  PlatformThreadHandle target_thread_handle2;
-  EXPECT_TRUE(
-      PlatformThread::Create(0, &target_thread2, &target_thread_handle2));
+  target_thread2.Start();
   events2.ready_for_sample.Wait();
 
   // Providing an initial delay makes it more likely that both will be
@@ -1201,8 +1193,8 @@
 
   events1.sample_finished.Signal();
   events2.sample_finished.Signal();
-  PlatformThread::Join(target_thread_handle1);
-  PlatformThread::Join(target_thread_handle2);
+  target_thread1.Join();
+  target_thread2.Join();
 }
 
 // A simple thread that runs a profiler on another thread.
@@ -1523,4 +1515,96 @@
   EXPECT_EQ(11, metadata2.item.value);
 }
 
+PROFILER_TEST_F(
+    StackSamplingProfilerTest,
+    ApplyMetadataToPastSamples_PassedToProfileBuilder_MultipleCollections) {
+  SamplingParams params;
+  params.sampling_interval = Milliseconds(10);
+  // 10,000 samples ensures the profiler continues running until manually
+  // stopped, after applying metadata.
+  params.samples_per_profile = 10000;
+  ModuleCache module_cache1, module_cache2;
+
+  WaitableEvent profiler1_started;
+  WaitableEvent profiler2_started;
+  WaitableEvent profiler1_metadata_applied;
+  WaitableEvent profiler2_metadata_applied;
+
+  Profile profile1;
+  WaitableEvent sampling_completed1;
+  TargetThread target_thread1(BindLambdaForTesting([&]() {
+    StackSamplingProfiler profiler1(
+        target_thread1.thread_token(), params,
+        std::make_unique<TestProfileBuilder>(
+            &module_cache1, BindLambdaForTesting([&](Profile result_profile) {
+              profile1 = std::move(result_profile);
+              sampling_completed1.Signal();
+            })),
+        CreateCoreUnwindersFactoryForTesting(&module_cache1),
+        RepeatingClosure());
+    profiler1.Start();
+    profiler1_started.Signal();
+    profiler2_started.Wait();
+
+    // Record metadata on past samples only for this thread. The time range
+    // shouldn't affect the outcome, it should always be passed to the
+    // ProfileBuilder.
+    ApplyMetadataToPastSamples(TimeTicks(), TimeTicks::Now(), "TestMetadata1",
+                               10, 10, SampleMetadataScope::kThread);
+
+    profiler1_metadata_applied.Signal();
+    profiler2_metadata_applied.Wait();
+    profiler1.Stop();
+  }));
+  target_thread1.Start();
+
+  Profile profile2;
+  WaitableEvent sampling_completed2;
+  TargetThread target_thread2(BindLambdaForTesting([&]() {
+    StackSamplingProfiler profiler2(
+        target_thread2.thread_token(), params,
+        std::make_unique<TestProfileBuilder>(
+            &module_cache2, BindLambdaForTesting([&](Profile result_profile) {
+              profile2 = std::move(result_profile);
+              sampling_completed2.Signal();
+            })),
+        CreateCoreUnwindersFactoryForTesting(&module_cache2),
+        RepeatingClosure());
+    profiler2.Start();
+    profiler2_started.Signal();
+    profiler1_started.Wait();
+
+    // Record metadata on past samples only for this thread.
+    ApplyMetadataToPastSamples(TimeTicks(), TimeTicks::Now(), "TestMetadata2",
+                               20, 20, SampleMetadataScope::kThread);
+
+    profiler2_metadata_applied.Signal();
+    profiler1_metadata_applied.Wait();
+    profiler2.Stop();
+  }));
+  target_thread2.Start();
+
+  // Wait for the profile to be captured before checking expectations.
+  sampling_completed1.Wait();
+  sampling_completed2.Wait();
+
+  ASSERT_EQ(1u, profile1.retrospective_metadata.size());
+  ASSERT_EQ(1u, profile2.retrospective_metadata.size());
+
+  {
+    const RetrospectiveMetadata& metadata1 = profile1.retrospective_metadata[0];
+    EXPECT_EQ(HashMetricName("TestMetadata1"), metadata1.item.name_hash);
+    ASSERT_TRUE(metadata1.item.key.has_value());
+    EXPECT_EQ(10, *metadata1.item.key);
+    EXPECT_EQ(10, metadata1.item.value);
+  }
+  {
+    const RetrospectiveMetadata& metadata2 = profile2.retrospective_metadata[0];
+    EXPECT_EQ(HashMetricName("TestMetadata2"), metadata2.item.name_hash);
+    ASSERT_TRUE(metadata2.item.key.has_value());
+    EXPECT_EQ(20, *metadata2.item.key);
+    EXPECT_EQ(20, metadata2.item.value);
+  }
+}
+
 }  // namespace base
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 0cc5620..5f9766d5 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -49,7 +49,11 @@
   // `base::Value::Dict` ends up taking 4 machine words instead of 3. An
   // additional word is used by absl::variant for the type index.
   constexpr size_t kExpectedSize = 5 * sizeof(void*);
-#else   // !BUILDFLAG(IS_WIN)
+#elif defined(__GLIBCXX__)
+  // libstdc++ std::string takes already 4 machine words, so the absl::variant
+  // takes 5
+  constexpr size_t kExpectedSize = 5 * sizeof(void*);
+#else   // !BUILDFLAG(IS_WIN) && !defined(__GLIBCXX__)
   // libc++'s std::string and std::vector both take 3 machine words. An
   // additional word is used by absl::variant for the type index.
   constexpr size_t kExpectedSize = 4 * sizeof(void*);
diff --git a/build/android/java/templates/BuildConfig.template b/build/android/java/templates/BuildConfig.template
index 8953ad5..c24f76b 100644
--- a/build/android/java/templates/BuildConfig.template
+++ b/build/android/java/templates/BuildConfig.template
@@ -81,12 +81,6 @@
     public static MAYBE_FINAL boolean IS_INCREMENTAL_INSTALL MAYBE_FALSE;
 #endif
 
-#if defined(_IS_CHROMECAST_BRANDING_INTERNAL)
-    public static MAYBE_FINAL boolean IS_CHROMECAST_BRANDING_INTERNAL = true;
-#else
-    public static MAYBE_FINAL boolean IS_CHROMECAST_BRANDING_INTERNAL MAYBE_FALSE;
-#endif
-
 #if defined(_ISOLATED_SPLITS_ENABLED)
     public static MAYBE_FINAL boolean ISOLATED_SPLITS_ENABLED = true;
 #else
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 81a5218..ce40de4 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1948,10 +1948,6 @@
         defines += [ "_IS_CHROME_BRANDED" ]
       }
 
-      if (is_chromecast && chromecast_branding == "internal") {
-        defines += [ "_IS_CHROMECAST_BRANDING_INTERNAL" ]
-      }
-
       if (defined(invoker.bundles_supported) && invoker.bundles_supported) {
         defines += [ "_BUNDLES_SUPPORTED" ]
       }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index bae94a39..fa17834 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1547,7 +1547,7 @@
         cflags += [ "-Wmax-tokens" ]
       }
 
-      if (llvm_force_head_revision) {
+      if (llvm_force_head_revision && !is_nacl) {
         cflags += [
           # TODO(https://crbug.com/1300731) Clean up and enable.
           "-Wno-unqualified-std-cast-call",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 955a364..1c46c07 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-7.20220223.2.1
+7.20220226.0.1
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 955a364..f51c9c3 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-7.20220223.2.1
+7.20220226.1.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 955a364..1c46c07 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-7.20220223.2.1
+7.20220226.0.1
diff --git a/build/linux/sysroot_scripts/sysroots.json b/build/linux/sysroot_scripts/sysroots.json
index bd6c510..02469a2 100644
--- a/build/linux/sysroot_scripts/sysroots.json
+++ b/build/linux/sysroot_scripts/sysroots.json
@@ -1,36 +1,36 @@
 {
     "sid_amd64": {
-        "Sha1Sum": "fb061d85160a65abc57e4459896aa225cfd8c86f",
+        "Sha1Sum": "bf028d6f446cd511713b3103d9de754c8df64ba8",
         "SysrootDir": "debian_sid_amd64-sysroot",
         "Tarball": "debian_sid_amd64_sysroot.tar.xz"
     },
     "sid_arm": {
-        "Sha1Sum": "d94ab800f295912a891b359fa5f71a643c3fba62",
+        "Sha1Sum": "68199c49f72522184f53838de84ca8089ff4104c",
         "SysrootDir": "debian_sid_arm-sysroot",
         "Tarball": "debian_sid_arm_sysroot.tar.xz"
     },
     "sid_arm64": {
-        "Sha1Sum": "5d3cca0a256424f2d0a2ecdfe95203d555b5e135",
+        "Sha1Sum": "fd7d3ccf92450b96e27ca9d91615a8d6500bf5a3",
         "SysrootDir": "debian_sid_arm64-sysroot",
         "Tarball": "debian_sid_arm64_sysroot.tar.xz"
     },
     "sid_armel": {
-        "Sha1Sum": "68262902eac968b9c99919ef5793d63089585965",
+        "Sha1Sum": "558928c9a60d70e69baa5848bf4a4a838970ef6e",
         "SysrootDir": "debian_sid_armel-sysroot",
         "Tarball": "debian_sid_armel_sysroot.tar.xz"
     },
     "sid_i386": {
-        "Sha1Sum": "23d12100f83139fc55349a841214d5d0bbd85a8d",
+        "Sha1Sum": "d6b5c8c868a925933367547d7e86720c77dc87fb",
         "SysrootDir": "debian_sid_i386-sysroot",
         "Tarball": "debian_sid_i386_sysroot.tar.xz"
     },
     "sid_mips": {
-        "Sha1Sum": "bf65fd76500dd0b282aa52e8b53202eff7583de1",
+        "Sha1Sum": "cf992ead7c06faf4742639c9075e2dea780a2d6f",
         "SysrootDir": "debian_sid_mips-sysroot",
         "Tarball": "debian_sid_mips_sysroot.tar.xz"
     },
     "sid_mips64el": {
-        "Sha1Sum": "9ddbcdb4be1b8e28a4e553928e2aeb479acdbe94",
+        "Sha1Sum": "5b9613eb92d426428206a3a2a15838bcf4d04192",
         "SysrootDir": "debian_sid_mips64el-sysroot",
         "Tarball": "debian_sid_mips64el_sysroot.tar.xz"
     }
diff --git a/build/toolchain/apple/linker_driver.py b/build/toolchain/apple/linker_driver.py
index 33809eb..2afe63b 100755
--- a/build/toolchain/apple/linker_driver.py
+++ b/build/toolchain/apple/linker_driver.py
@@ -51,17 +51,9 @@
 # -Wcrl,strippath,<strip_path>
 #    Sets the path to the strip to run with -Wcrl,strip, in which case
 #    `xcrun` is not used to invoke it.
-#
-# -Wcrl,pad_linkedit,<size>
-#    Pads the total size of the linker's output to the specified size in bytes,
-#    after running the linker and `strip`. Padding is added to the __LINKEDIT
-#    segment by the pad_linkedit.py script located in the same directory as this
-#    script. It is an error to attempt to reduce the size of the linked image
-#    using this option.
 
 
 class LinkerDriver(object):
-
     def __init__(self, args):
         """Creates a new linker driver.
 
@@ -82,7 +74,6 @@
             ('unstripped,', self.run_save_unstripped),
             ('strippath,', self.set_strip_path),
             ('strip,', self.run_strip),
-            ('pad_linkedit,', self.run_pad_linkedit),
         ]
 
         # Linker driver actions can modify the these values.
@@ -287,21 +278,6 @@
         self._strip_cmd = [strip_path]
         return []
 
-    def run_pad_linkedit(self, size_string):
-        """Linker driver action for -Wcrl,pad_linkedit,<size>.
-
-        Args:
-            size_string: string, the size to pass to pad_linkedit.py.
-
-        Returns:
-            list of string, Build step outputs.
-        """
-        pad_linkedit_command = (os.path.join(os.path.dirname(__file__),
-                                             'pad_linkedit.py'),
-                                self._get_linker_output(), size_string)
-        subprocess.check_call(pad_linkedit_command)
-        return []
-
 
 # Regular expressions matching log spam messages from dsymutil.
 DSYM_SPURIOUS_PATTERNS = [
diff --git a/build/toolchain/apple/pad_linkedit.py b/build/toolchain/apple/pad_linkedit.py
deleted file mode 100755
index b41f186..0000000
--- a/build/toolchain/apple/pad_linkedit.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python3
-# coding: utf-8
-
-# Copyright 2022 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Increases the size of a Mach-O image by adding padding to its __LINKEDIT
-# segment.
-
-import argparse
-import os
-import struct
-import sys
-
-# Constants from <mach-o/loader.h>.
-_MH_MAGIC = 0xfeedface
-_MH_MAGIC_64 = 0xfeedfacf
-_LC_SEGMENT = 0x1
-_LC_SEGMENT_64 = 0x19
-_LC_CODE_SIGNATURE = 0x1d
-_SEG_LINKEDIT = b'__LINKEDIT'.ljust(16, b'\x00')
-
-
-class PadLinkeditError(Exception):
-    pass
-
-
-def _struct_read_unpack(file, format_or_struct):
-    """Reads bytes from |file|, unpacking them via the struct module. This
-    function is provided for convenience: the number of bytes to read from
-    |file| is determined based on the size of data that the struct unpack
-    operation will consume.
-
-    Args:
-        file: The file object to read from.
-
-        format_or_struct: A string suitable for struct.unpack’s |format|
-            argument, or a struct.Struct object. This will be used to determine
-            the number of bytes to read and to perform the unpack.
-
-    Returns:
-        A tuple of unpacked items.
-    """
-
-    if isinstance(format_or_struct, struct.Struct):
-        struc = format_or_struct
-        return struc.unpack(file.read(struc.size))
-
-    format = format_or_struct
-    return struct.unpack(format, file.read(struct.calcsize(format)))
-
-
-def PadLinkedit(file, size):
-    """Takes |file|, a single-architecture (thin) Mach-O image, and increases
-    its size to |size| by adding padding (NUL bytes) to its __LINKEDIT segment.
-    If |file| is not a thin Mach-O image, if its structure is unexpected, if it
-    is already larger than |size|, or if it is already code-signed, raises
-    PadLinkeditError.
-
-    The image must already have a __LINKEDIT segment, the load command for the
-    __LINKEDIT segment must be the last segment load command in the image, and
-    the __LINKEDIT segment contents must be at the end of the file.
-
-    Args:
-        file: The file object to read from and modify.
-
-        size: The desired size of the file.
-
-    Returns:
-        None
-
-    Raises:
-        PadLinkeditError if |file| is not suitable for the operation.
-    """
-
-    file.seek(0, os.SEEK_END)
-    current_size = file.tell()
-    file.seek(0, os.SEEK_SET)
-
-    magic, = _struct_read_unpack(file, '<I')
-    if magic == _MH_MAGIC_64:
-        bits, endian = 64, '<'
-    elif magic == _MH_MAGIC:
-        bits, endian = 32, '<'
-    elif magic == struct.unpack('>I', struct.pack('<I', _MH_MAGIC_64)):
-        bits, endian = 64, '>'
-    elif magic == struct.unpack('>I', struct.pack('<I', _MH_MAGIC)):
-        bits, endian = 32, '>'
-    else:
-        raise PadLinkeditError('unrecognized magic', magic)
-
-    if bits == 64:
-        lc_segment = _LC_SEGMENT_64
-        segment_command_struct = struct.Struct(endian + '16s4Q4I')
-    else:
-        lc_segment = _LC_SEGMENT
-        segment_command_struct = struct.Struct(endian + '16s8I')
-
-    grow = size - current_size
-    if grow < 0:
-        raise PadLinkeditError('file would need to shrink', grow)
-
-    (cputype, cpusubtype, filetype, ncmds, sizeofcmds,
-     flags) = _struct_read_unpack(file,
-                                  endian + '6I' + ('4x' if bits == 64 else ''))
-
-    load_command_struct = struct.Struct(endian + '2I')
-    found_linkedit = False
-    segment_max_offset = 0
-
-    # Iterate through the load commands. It’s possible to consider |sizeofcmds|,
-    # but since the file is being edited in-place, that would just be a sanity
-    # check.
-    for load_command_index in range(ncmds):
-        cmd, cmdsize = _struct_read_unpack(file, load_command_struct)
-        consumed = load_command_struct.size
-        if cmd == lc_segment:
-            if found_linkedit:
-                raise PadLinkeditError('__LINKEDIT segment not last')
-
-            (segname, vmaddr, vmsize, fileoff, filesize, maxprot, initprot,
-             nsects, flags) = _struct_read_unpack(file, segment_command_struct)
-            consumed += segment_command_struct.size
-
-            if segname == _SEG_LINKEDIT:
-                found_linkedit = True
-
-                if fileoff < segment_max_offset:
-                    raise PadLinkeditError('__LINKEDIT data not last')
-                if fileoff + filesize != current_size:
-                    raise PadLinkeditError('__LINKEDIT data not at EOF')
-
-                vmsize += grow
-                filesize += grow
-                file.seek(-segment_command_struct.size, os.SEEK_CUR)
-                file.write(
-                    segment_command_struct.pack(segname, vmaddr, vmsize,
-                                                fileoff, filesize, maxprot,
-                                                initprot, nsects, flags))
-
-            segment_max_offset = max(segment_max_offset, fileoff + filesize)
-        elif cmd == _LC_CODE_SIGNATURE:
-            raise PadLinkeditError(
-                'modifying an already-signed image would render it unusable')
-
-        # Aside from the above, load commands aren’t being interpreted, or even
-        # read, so skip ahead to the next one.
-        file.seek(cmdsize - consumed, os.SEEK_CUR)
-
-    if not found_linkedit:
-        raise PadLinkeditError('no __LINKEDIT')
-
-    # Add the padding to the __LINKEDIT segment data.
-    file.seek(grow, os.SEEK_END)
-    file.truncate()
-
-
-def _main(args):
-    parser = argparse.ArgumentParser(
-        description=
-        'Increase the size of a Mach-O image by adding padding to its ' +
-        '__LINKEDIT segment.')
-    parser.add_argument('file', help='The Mach-O file to modify')
-    parser.add_argument('size',
-                        type=int,
-                        help='The desired final size of the file, in bytes')
-    parsed = parser.parse_args()
-
-    with open(parsed.file, 'r+b') as file:
-        PadLinkedit(file, parsed.size)
-
-
-if __name__ == '__main__':
-    sys.exit(_main(sys.argv[1:]))
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 86e24b4..091ec28 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -465,6 +465,7 @@
     "//services/metrics/public/cpp:ukm_builders",
     "//services/metrics/public/mojom",
     "//services/tracing/public/cpp:cpp",
+    "//skia:skcms",
     "//ui/base:features",
     "//ui/events:events_base",
     "//ui/gfx",
diff --git a/cc/input/main_thread_scrolling_reason.h b/cc/input/main_thread_scrolling_reason.h
index 55522c655..cc411a5 100644
--- a/cc/input/main_thread_scrolling_reason.h
+++ b/cc/input/main_thread_scrolling_reason.h
@@ -17,10 +17,10 @@
 
 namespace cc {
 
-// Ensure this stays in sync with MainThreadScrollingReason in
-// tools/metrics/enums.xml. When adding a new MainThreadScrollingReason, make
-// sure the corresponding [MainThread/Compositor]CanSetScrollReasons function
-// is also updated.
+// Ensure this stays in sync with the "MainThreadScrollingReason" enum in:
+//   tools/metrics/histograms/enums.xml
+// When adding a new MainThreadScrollingReason, make sure the corresponding
+// [MainThread/Compositor]CanSetScrollReasons function is also updated.
 struct CC_EXPORT MainThreadScrollingReason {
   enum : uint32_t {
     kNotScrollingOnMain = 0,
@@ -70,7 +70,8 @@
   // thread.
   static bool MainThreadCanSetScrollReasons(uint32_t reasons) {
     constexpr uint32_t reasons_set_by_main_thread =
-        kHasBackgroundAttachmentFixedObjects | kThreadedScrollingDisabled;
+        kHasBackgroundAttachmentFixedObjects | kThreadedScrollingDisabled |
+        kPopupNoThreadedInput;
     return (reasons & reasons_set_by_main_thread) == reasons;
   }
 
diff --git a/cc/input/scroll_elasticity_helper.cc b/cc/input/scroll_elasticity_helper.cc
index 298ae48..8dbc386 100644
--- a/cc/input/scroll_elasticity_helper.cc
+++ b/cc/input/scroll_elasticity_helper.cc
@@ -17,7 +17,8 @@
   explicit ScrollElasticityHelperImpl(LayerTreeHostImpl* host_impl);
   ~ScrollElasticityHelperImpl() override;
 
-  bool IsUserScrollable() const override;
+  bool IsUserScrollableHorizontal() const override;
+  bool IsUserScrollableVertical() const override;
   gfx::Vector2dF StretchAmount() const override;
   gfx::Size ScrollBounds() const override;
   void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override;
@@ -36,12 +37,18 @@
 
 ScrollElasticityHelperImpl::~ScrollElasticityHelperImpl() = default;
 
-bool ScrollElasticityHelperImpl::IsUserScrollable() const {
+bool ScrollElasticityHelperImpl::IsUserScrollableHorizontal() const {
   const auto* scroll_node = host_impl_->OuterViewportScrollNode();
   if (!scroll_node)
     return false;
-  return scroll_node->user_scrollable_horizontal ||
-         scroll_node->user_scrollable_vertical;
+  return scroll_node->user_scrollable_horizontal;
+}
+
+bool ScrollElasticityHelperImpl::IsUserScrollableVertical() const {
+  const auto* scroll_node = host_impl_->OuterViewportScrollNode();
+  if (!scroll_node)
+    return false;
+  return scroll_node->user_scrollable_vertical;
 }
 
 gfx::Vector2dF ScrollElasticityHelperImpl::StretchAmount() const {
diff --git a/cc/input/scroll_elasticity_helper.h b/cc/input/scroll_elasticity_helper.h
index 16aa4a83..328c5d6f 100644
--- a/cc/input/scroll_elasticity_helper.h
+++ b/cc/input/scroll_elasticity_helper.h
@@ -52,7 +52,8 @@
 
   virtual ~ScrollElasticityHelper() {}
 
-  virtual bool IsUserScrollable() const = 0;
+  virtual bool IsUserScrollableHorizontal() const = 0;
+  virtual bool IsUserScrollableVertical() const = 0;
 
   // The bounds of the root scroller.
   virtual gfx::Size ScrollBounds() const = 0;
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc
index 6f1ef12..35ee71e 100644
--- a/cc/paint/image_transfer_cache_entry.cc
+++ b/cc/paint/image_transfer_cache_entry.cc
@@ -528,7 +528,6 @@
         return false;
       }
 
-      DCHECK(!target_color_params);
       sk_sp<SkImage> plane = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
       if (!plane) {
         DLOG(ERROR) << "Failed to create image from plane pixmap";
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index e9090ca0..73fa44a 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -2115,7 +2115,7 @@
   DCHECK_GT(image_data->decode.ref_count, 0u);
   DCHECK_GT(image_data->upload.ref_count, 0u);
 
-  sk_sp<SkColorSpace> color_space =
+  sk_sp<SkColorSpace> target_color_space =
       SupportsColorSpaceConversion() &&
               draw_image.target_color_space().IsValid()
           ? draw_image.target_color_space().ToSkColorSpace()
@@ -2126,12 +2126,17 @@
   // have happened at decode time.
   sk_sp<SkColorSpace> decoded_target_colorspace =
       ColorSpaceForImageDecode(draw_image, image_data->mode);
-  if (color_space && SkColorSpace::Equals(color_space.get(),
-                                          decoded_target_colorspace.get())) {
-    color_space = nullptr;
+  if (target_color_space &&
+      SkColorSpace::Equals(target_color_space.get(),
+                           decoded_target_colorspace.get())) {
+    target_color_space = nullptr;
   }
 
   absl::optional<TargetColorParams> target_color_params;
+  if (target_color_space) {
+    target_color_params = draw_image.target_color_params();
+    target_color_params->color_space = gfx::ColorSpace(*target_color_space);
+  }
 
   // Will be nullptr for non-HDR images or when we're using the default level.
   const bool needs_adjusted_color_space =
@@ -2143,16 +2148,15 @@
     DCHECK(use_transfer_cache_);
     if (image_data->decode.do_hardware_accelerated_decode()) {
       UploadImageIfNecessary_TransferCache_HardwareDecode(
-          draw_image, image_data, color_space);
+          draw_image, image_data, target_color_space);
     } else if (image_data->yuva_pixmap_info.has_value()) {
+      const bool needs_tone_mapping =
+          decoded_target_colorspace &&
+          gfx::ColorSpace(*decoded_target_colorspace).IsPQOrHLG();
       UploadImageIfNecessary_TransferCache_SoftwareDecode_YUVA(
           draw_image, image_data, decoded_target_colorspace,
-          target_color_params);
+          needs_tone_mapping ? target_color_params : absl::nullopt);
     } else {
-      if (color_space) {
-        target_color_params = draw_image.target_color_params();
-        target_color_params->color_space = gfx::ColorSpace(*color_space);
-      }
       UploadImageIfNecessary_TransferCache_SoftwareDecode_RGBA(
           draw_image, image_data, needs_adjusted_color_space,
           decoded_target_colorspace, target_color_params);
@@ -2167,11 +2171,12 @@
     if (image_data->yuva_pixmap_info.has_value()) {
       UploadImageIfNecessary_GpuCpu_YUVA(
           draw_image, image_data, uploaded_image, image_needs_mips,
-          decoded_target_colorspace, color_space);
+          decoded_target_colorspace, target_color_space);
     } else {
       UploadImageIfNecessary_GpuCpu_RGBA(
           draw_image, image_data, uploaded_image, image_needs_mips,
-          needs_adjusted_color_space, decoded_target_colorspace, color_space);
+          needs_adjusted_color_space, decoded_target_colorspace,
+          target_color_space);
     }
   }
 }
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc
index b96d4f1..3ab5d222 100644
--- a/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -3128,7 +3128,13 @@
     EXPECT_TRUE(decoded_draw_image.image());
     EXPECT_TRUE(decoded_draw_image.image()->isTextureBacked());
 
-    if (decodes_to_yuv) {
+    // If `draw_image` is tone mapped, then it will be converted to RGBA
+    // during tone mapping.
+    bool color_converted_to_rgba = use_transfer_cache_ &&
+                                   target_cs.IsPQOrHLG() &&
+                                   cache->SupportsColorSpaceConversion();
+
+    if (decodes_to_yuv && !color_converted_to_rgba) {
       // Skia will flatten a YUV SkImage upon calling makeTextureImage. Thus, we
       // must separately request mips for each plane and compare to the original
       // uploaded planes.
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 615b9b8f..4120585a2 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -781,10 +781,6 @@
 void UpdateRenderTarget(EffectTree* effect_tree) {
   int last_backdrop_filter = kInvalidNodeId;
 
-  // A list of EffectNodes which induce a render surface to generate and cache
-  // content for a SharedElement.
-  std::vector<EffectNode*> shared_element_render_pass_nodes;
-
   for (int i = kContentsRootPropertyNodeId;
        i < static_cast<int>(effect_tree->size()); ++i) {
     EffectNode* node = effect_tree->Node(i);
@@ -800,44 +796,6 @@
         node->has_potential_backdrop_filter_animation)
       last_backdrop_filter = node->id;
     node->affected_by_backdrop_filter = false;
-
-    if (node->shared_element_resource_id.IsValid())
-      shared_element_render_pass_nodes.push_back(node);
-  }
-
-  // A SharedElement's render surface draws into the
-  // DocumentTransitionContentLayer, not into its parent layer in the regular
-  // effect tree. This is because during a shared element transition animation,
-  // the SharedElement doesn't paint, but instead delegates its paint to the
-  // DocumentTransitionContentLayer that paints on top of everything else.
-  //
-  // Update the target_id for each SharedElement to the render target where its
-  // corresponding DocumentTransitionContentLayer generates quads. This is the
-  // DocumentTransitionContentLayer's effect if it generates a render surface,
-  // or its target_id if it doesn't. This must be done after a traversal of the
-  // complete EffectTree to ensure render targets for nodes corresponding to the
-  // DocumentTransitionContentLayer have been set up.
-  //
-  // TODO(vmpstr): there is bespoke viz code to draw the surface for the
-  // SharedElement into the DocumentTransitionContentLayer target. Now that
-  // we're also setting the target id here, some of that viz code can be
-  // removed.
-  for (auto* effect_node : shared_element_render_pass_nodes) {
-    const EffectNode* shared_element_layer_node =
-        effect_tree->FindNodeFromSharedElementResourceId(
-            effect_node->shared_element_resource_id);
-
-    // It's possible for a shared element to not have a corresponding document
-    // transition layer. For example if the element which displays this layer is
-    // marked display:none.
-    if (!shared_element_layer_node)
-      continue;
-
-    if (effect_tree->GetRenderSurface(shared_element_layer_node->id)) {
-      effect_node->target_id = shared_element_layer_node->id;
-    } else {
-      effect_node->target_id = shared_element_layer_node->target_id;
-    }
   }
 
   if (last_backdrop_filter == kInvalidNodeId)
@@ -998,6 +956,24 @@
   // The root surface always gets added to the render surface  list.
   AddSurfaceToRenderSurfaceList(root_surface, render_surface_list,
                                 property_trees);
+
+  // Add all of the render surfaces for the transition pseudo elements early,
+  // since they will need to be added before the shared elements in the layer
+  // lists below, which isn't reflected in the dependency. This can't be done
+  // with dependency ordering because other things require correct dependency
+  // ordering (the AppendQuads pass). By adding the render surfaces right after
+  // the root, we guarantee that the pseudo element tree's render surfaces will
+  // come _after_ any render passes that they reference in the render pass
+  // order.
+  auto transition_pseudo_render_surfaces =
+      effect_tree.GetTransitionPseudoElementRenderSurfaces();
+  for (auto* surface : transition_pseudo_render_surfaces) {
+    if (!surface->is_render_surface_list_member()) {
+      AddSurfaceToRenderSurfaceList(surface, render_surface_list,
+                                    property_trees);
+    }
+  }
+
   // For all non-skipped layers, add their target to the render surface list if
   // it's not already been added, and add their content rect to the target
   // surface's accumulated content rect.
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 77961fb6..f158b83 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -707,7 +707,7 @@
   PropertyTree<EffectNode>::clear();
   render_surfaces_.clear();
   render_surfaces_.push_back(nullptr);
-  document_transition_layer_to_node_index_.clear();
+  transition_pseudo_element_effect_nodes_.clear();
 
 #if DCHECK_IS_ON()
   EffectTree tree;
@@ -1042,26 +1042,26 @@
   return id_1;
 }
 
-void EffectTree::SetSharedElementResourceIdForNodeId(
-    int node_id,
-    viz::SharedElementResourceId resource_id) {
-  document_transition_layer_to_node_index_[resource_id] = node_id;
+void EffectTree::ClearTransitionPseudoElementEffectNodes() {
+  transition_pseudo_element_effect_nodes_.clear();
 }
 
-EffectNode* EffectTree::FindNodeFromSharedElementResourceId(
-    viz::SharedElementResourceId resource_id) {
-  auto iterator = document_transition_layer_to_node_index_.find(resource_id);
-  if (iterator == document_transition_layer_to_node_index_.end())
-    return nullptr;
-  return Node(iterator->second);
+void EffectTree::AddTransitionPseudoElementEffectId(int id) {
+  transition_pseudo_element_effect_nodes_.insert(id);
 }
 
-const EffectNode* EffectTree::FindNodeFromSharedElementResourceId(
-    viz::SharedElementResourceId resource_id) const {
-  auto iterator = document_transition_layer_to_node_index_.find(resource_id);
-  if (iterator == document_transition_layer_to_node_index_.end())
-    return nullptr;
-  return Node(iterator->second);
+std::vector<RenderSurfaceImpl*>
+EffectTree::GetTransitionPseudoElementRenderSurfaces() {
+  std::vector<RenderSurfaceImpl*> result;
+  for (auto effect_id : transition_pseudo_element_effect_nodes_) {
+    // Add the render surface if there is one. Otherwise, add the target render
+    // surface.
+    if (auto* render_surface = GetRenderSurface(effect_id))
+      result.push_back(render_surface);
+    else if (auto* target = GetRenderSurface(Node(effect_id)->target_id))
+      result.push_back(target);
+  }
+  return result;
 }
 
 bool EffectTree::ContributesToDrawnSurface(int id) const {
@@ -1219,8 +1219,8 @@
 EffectTree& EffectTree::operator=(const EffectTree& from) {
   PropertyTree::operator=(from);
   render_surfaces_.resize(size());
-  document_transition_layer_to_node_index_ =
-      from.document_transition_layer_to_node_index_;
+  transition_pseudo_element_effect_nodes_ =
+      from.transition_pseudo_element_effect_nodes_;
   // copy_requests_ are omitted here, since these need to be moved rather
   // than copied or assigned.
 
@@ -1230,8 +1230,8 @@
 #if DCHECK_IS_ON()
 bool EffectTree::operator==(const EffectTree& other) const {
   return PropertyTree::operator==(other) &&
-         document_transition_layer_to_node_index_ ==
-             other.document_transition_layer_to_node_index_;
+         transition_pseudo_element_effect_nodes_ ==
+             other.transition_pseudo_element_effect_nodes_;
 }
 #endif
 
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index 62d4772..004ca9e 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <string>
 #include <unordered_map>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -378,16 +379,9 @@
     return render_surfaces_[id].get();
   }
 
-  void SetSharedElementResourceIdForNodeId(
-      int node_id,
-      viz::SharedElementResourceId resource_id);
-  EffectNode* FindNodeFromSharedElementResourceId(
-      viz::SharedElementResourceId resource_id);
-  const EffectNode* FindNodeFromSharedElementResourceId(
-      viz::SharedElementResourceId resource_id) const;
-  void ClearSharedElementResourceIdToNodeMap() {
-    document_transition_layer_to_node_index_.clear();
-  }
+  void ClearTransitionPseudoElementEffectNodes();
+  void AddTransitionPseudoElementEffectId(int id);
+  std::vector<RenderSurfaceImpl*> GetTransitionPseudoElementRenderSurfaces();
 
   bool ContributesToDrawnSurface(int id) const;
 
@@ -430,11 +424,7 @@
   // Indexed by node id.
   std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces_;
 
-  // If an element is being rendered as a "live snapshot" using a
-  // DocumentTransitionLayer, this maps the layer's SharedElementResourceId to
-  // the EffectNode id associated with that layer.
-  base::flat_map<viz::SharedElementResourceId, int>
-      document_transition_layer_to_node_index_;
+  std::unordered_set<int> transition_pseudo_element_effect_nodes_;
 };
 
 // These callbacks are called in the main thread to notify changes of scroll
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 996f0cd..36672a4 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -476,19 +476,18 @@
       ":chrome_resources",
       ":chrome_versioned_bundle_data",
       "//base/allocator:early_zone_registration_mac",
+      "//build:branding_buildflags",
       "//chrome/common:buildflags",
       "//chrome/common:version_header",
     ]
 
-    ldflags = []
-
     if (enable_stripping) {
       # At link time, preserve the global symbols specified in the .exports
       # file. All other global symbols will be marked as private. The default
       # //build/config/mac:strip_all config will then remove the remaining
       # local and debug symbols.
-      ldflags += [ "-Wl,-exported_symbols_list," +
-                   rebase_path("app/app.exports", root_build_dir) ]
+      ldflags = [ "-Wl,-exported_symbols_list," +
+                  rebase_path("app/app.exports", root_build_dir) ]
     }
 
     if (is_component_build) {
@@ -496,7 +495,7 @@
       # executable because dlopen() and loading all the dependent dylibs
       # is time-consuming, see https://crbug.com/1197495.
       deps += [ ":chrome_framework+link" ]
-      ldflags += [ "-Wl,-rpath,@executable_path/../Frameworks" ]
+      ldflags = [ "-Wl,-rpath,@executable_path/../Frameworks" ]
 
       # The Framework is packaged inside the .app bundle. But when using the
       # component build, all the dependent shared libraries of :chrome_dll are
@@ -510,70 +509,6 @@
     if (enable_chromium_updater) {
       deps += [ ":chromium_updater_privileged_helper" ]
     }
-
-    if (is_chrome_branded && is_official_build && current_cpu == "x64") {
-      # This is for https://crbug.com/1300598, and more generally,
-      # https://crbug.com/1297588 (and all of the associated bugs). It's
-      # horrible!
-      #
-      # When the main executable is updated on disk while the application is
-      # running, and the offset of the Mach-O image at the main executable's
-      # path changes from the offset that was determined when the executable was
-      # loaded, SecCode ceases to be able to work with the executable. This may
-      # be triggered when the product is updated on disk but the application has
-      # not yet relaunched. This affects SecCodeCopySelf and
-      # SecCodeCopyGuestWithAttributes. Bugs are evident even when validation
-      # (SecCodeCheckValidity) is not attempted.
-      #
-      # Practically, this is only a concern for fat (universal) files, because
-      # the offset of a Mach-O image in a thin (single-architecture) file is
-      # always 0. The branded product always ships a fat executable, and because
-      # some uses of SecCode are in OS code beyond Chrome's control, an effort
-      # is made to freeze the geometry of the branded (is_chrome_branded)
-      # for-public-release (is_official_build) main executable.
-      #
-      # The fat file is produced by installer/mac/universalizer.py. The x86_64
-      # slice always precedes the arm64 slice: lipo, as used by
-      # universalizer.py, always places the arm64 slice last. See Xcode 12.0
-      # https://github.com/apple-oss-distributions/cctools/blob/cctools-973.0.1/misc/lipo.c#L2672
-      # cmp_qsort, used by create_fat at #L962. universalizer.py ensures that
-      # the first slice in the file is located at a constant offset (16kB since
-      # 98.0.4758.80), but if the first slice's size changes, it can affect the
-      # offset of the second slice, the arm64 one, triggering SecCode-related
-      # bugs for arm64 users across updates.
-      #
-      # As quite a hack of a workaround, the offset of the arm64 slice within
-      # the fat main executable is fixed at a constant value by introducing
-      # padding to the x86_64 slice that precedes it. The arm64 slice needs to
-      # remain at offset 304kB (since 98.0.4758.80), so enough padding is added
-      # to the x86_64 slice to ensure that the arm64 slice lands where it needs
-      # to be when universalized. This padding needs to be added to the thin
-      # form of the x86_64 image before being fed to universalizer.py.
-      #
-      # To make things extra tricky, the final size of the x86_64 image is not
-      # known when it is linked, because code signing will contribute more data
-      # to the file. Typically, official code signing adds a non-constant
-      # 22-23kB. The non-constancy makes a precise computation of the required
-      # padding at this stage of the build impossible. Luckily, the size of the
-      # x86_64 image doesn't need to be so precise. The arm64 slice that follows
-      # it in the fat file will be 16kB-aligned, so it's enough to ensure that
-      # the x86_64 slice ends at an offset in the range (288kB, 304kB], or,
-      # since the x86_64 slice itself begins at offset 16kB, its total size once
-      # signed must be in the range (272kB, 288kB]. Targeting size 280kB, right
-      # in the middle of that range, and assuming an expected 23200-byte
-      # contribution from code signing, the unsigned x86_64 image should be
-      # padded to 263520 bytes. Code signing may then add any amount in the
-      # range (15008 bytes, 31392 bytes] and the result, when universalized,
-      # will have its arm64 slice at the required 304kB offset.
-      #
-      # -Wcrl,pad_linkedit runs //build/toolchain/apple/pad_linkedit.py, and can
-      # only increase the size of the image. It will raise an error on an
-      # attempt to decrease the size. Fortunately, the x86_64 main executable in
-      # this build configuration is currently (at the time of this writing)
-      # smaller than this size, and is expected to shrink even further in the
-      # future.
-      ldflags += [ "-Wcrl,pad_linkedit,263520" ]
-    }
   }
 
   if (verify_dynamic_libraries) {
@@ -782,6 +717,7 @@
 
       deps = [
         "//base/allocator:early_zone_registration_mac",
+        "//build:branding_buildflags",
         "//chrome/common:version_header",
         "//sandbox/mac:seatbelt",
       ]
diff --git a/chrome/VERSION b/chrome/VERSION
index 6f1d665..370560f8 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=101
 MINOR=0
-BUILD=4911
+BUILD=4912
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 0805dc6..c6224c4 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -173,6 +173,7 @@
     "java/res_base/font/chrome_google_sans_bold.xml",
     "java/res_base/font/chrome_google_sans_medium.xml",
     "java/res_base/values/ic_launcher_alias.xml",
+    "java/res_base/values/ic_launcher_round_alias.xml",
     "java/res_base/values/values.xml",
     "java/res_base/xml/network_security_config.xml",
     "java/res_chromium_base/mipmap-hdpi/app_icon.png",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 4a1dd5b1..0edf08c 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -28,8 +28,7 @@
   "java/res/drawable-hdpi/btn_normal_tabs.png",
   "java/res/drawable-hdpi/btn_right.png",
   "java/res/drawable-hdpi/btn_tab_close_normal.png",
-  "java/res/drawable-hdpi/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-hdpi/btn_tabstrip_new_tab_normal.png",
+  "java/res/drawable-hdpi/btn_tabstrip_new_tab.png",
   "java/res/drawable-hdpi/btn_tabstrip_switch_normal.png",
   "java/res/drawable-hdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-hdpi/cvc_icon.png",
@@ -89,13 +88,8 @@
   "java/res/drawable-hdpi/toolbar_shadow_focused.png",
   "java/res/drawable-hdpi/toolbar_shadow_normal.png",
   "java/res/drawable-hdpi/verify_checkmark.png",
-  "java/res/drawable-ldrtl-hdpi-v17/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-ldrtl-mdpi-v17/btn_tabstrip_new_incognito_tab_normal.png",
   "java/res/drawable-ldrtl-v17/btn_back.xml",
   "java/res/drawable-ldrtl-v17/btn_forward.xml",
-  "java/res/drawable-ldrtl-xhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-ldrtl-xxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-ldrtl-xxxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png",
   "java/res/drawable-ldrtl/google_pay_with_divider.xml",
   "java/res/drawable-mdpi/bg_tabstrip_background_tab_outline.9.png",
   "java/res/drawable-mdpi/bg_tabstrip_tab.9.png",
@@ -109,8 +103,7 @@
   "java/res/drawable-mdpi/btn_normal_tabs.png",
   "java/res/drawable-mdpi/btn_right.png",
   "java/res/drawable-mdpi/btn_tab_close_normal.png",
-  "java/res/drawable-mdpi/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-mdpi/btn_tabstrip_new_tab_normal.png",
+  "java/res/drawable-mdpi/btn_tabstrip_new_tab.png",
   "java/res/drawable-mdpi/btn_tabstrip_switch_normal.png",
   "java/res/drawable-mdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-mdpi/cvc_icon.png",
@@ -193,8 +186,7 @@
   "java/res/drawable-xhdpi/btn_normal_tabs.png",
   "java/res/drawable-xhdpi/btn_right.png",
   "java/res/drawable-xhdpi/btn_tab_close_normal.png",
-  "java/res/drawable-xhdpi/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-xhdpi/btn_tabstrip_new_tab_normal.png",
+  "java/res/drawable-xhdpi/btn_tabstrip_new_tab.png",
   "java/res/drawable-xhdpi/btn_tabstrip_switch_normal.png",
   "java/res/drawable-xhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xhdpi/cvc_icon.png",
@@ -263,8 +255,7 @@
   "java/res/drawable-xxhdpi/btn_normal_tabs.png",
   "java/res/drawable-xxhdpi/btn_right.png",
   "java/res/drawable-xxhdpi/btn_tab_close_normal.png",
-  "java/res/drawable-xxhdpi/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-xxhdpi/btn_tabstrip_new_tab_normal.png",
+  "java/res/drawable-xxhdpi/btn_tabstrip_new_tab.png",
   "java/res/drawable-xxhdpi/btn_tabstrip_switch_normal.png",
   "java/res/drawable-xxhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xxhdpi/cvc_icon.png",
@@ -333,8 +324,7 @@
   "java/res/drawable-xxxhdpi/btn_normal_tabs.png",
   "java/res/drawable-xxxhdpi/btn_right.png",
   "java/res/drawable-xxxhdpi/btn_tab_close_normal.png",
-  "java/res/drawable-xxxhdpi/btn_tabstrip_new_incognito_tab_normal.png",
-  "java/res/drawable-xxxhdpi/btn_tabstrip_new_tab_normal.png",
+  "java/res/drawable-xxxhdpi/btn_tabstrip_new_tab.png",
   "java/res/drawable-xxxhdpi/btn_tabstrip_switch_normal.png",
   "java/res/drawable-xxxhdpi/contextual_search_promo_ripple.9.png",
   "java/res/drawable-xxxhdpi/cvc_icon.png",
diff --git a/chrome/android/expectations/lint-suppressions.xml b/chrome/android/expectations/lint-suppressions.xml
index 9221316..5572d76f 100644
--- a/chrome/android/expectations/lint-suppressions.xml
+++ b/chrome/android/expectations/lint-suppressions.xml
@@ -209,16 +209,6 @@
     <ignore regexp="The resource `R.string.translate_dont_offer_site` appears to be unused"/>
     <ignore regexp="The resource `R.string.translate_dont_offer_lang` appears to be unused"/>
 
-    <!-- crbug.com/1231370 remove this line and the following 8 lines after the bug is resolved -->
-    <ignore regexp="The resource `R.string.download_message_download_in_progress_description` appears to be unused"/>
-    <ignore regexp="The resource `R.string.download_message_download_complete_description` appears to be unused"/>
-    <ignore regexp="The resource `R.plurals.download_message_multiple_download_in_progress` appears to be unused"/>
-    <ignore regexp="The resource `R.plurals.download_message_multiple_download_complete` appears to be unused"/>
-    <ignore regexp="The resource `R.plurals.download_message_multiple_download_failed` appears to be unused"/>
-    <ignore regexp="The resource `R.plurals.download_message_multiple_download_pending` appears to be unused"/>
-    <ignore regexp="The resource `R.plurals.download_message_multiple_download_scheduled` appears to be unused"/>
-    <ignore regexp="The resource `R.string.download_message_download_scheduled_description` appears to be unused"/>
-
     <!-- Old-style and new-style WebAPKs use same resources for simplicity. Old-style WebAPKs do
          not use R.style.SplashTheme but new-style WebAPKs do.
          TODO(crbug.com/971254): Remove suppression once old-style WebAPKs are deprecated. -->
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/onboarding/BaseOnboardingCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/onboarding/BaseOnboardingCoordinator.java
index bf184cd4..47618f49 100644
--- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/onboarding/BaseOnboardingCoordinator.java
+++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/onboarding/BaseOnboardingCoordinator.java
@@ -197,7 +197,7 @@
                     R.string.autofill_assistant_google_terms_description);
         }
 
-        NoUnderlineClickableSpan termsSpan = new NoUnderlineClickableSpan(mContext.getResources(),
+        NoUnderlineClickableSpan termsSpan = new NoUnderlineClickableSpan(mContext,
                 (widget)
                         -> mInfoPageUtil.showInfoPage(mContext.getApplicationContext(),
                                 TextUtils.isEmpty(termsAndConditionsUrl)
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java
index b067f83e7..c36b107 100644
--- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java
+++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceLayout.java
@@ -18,7 +18,6 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
-import org.chromium.base.MathUtils;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.jank_tracker.JankScenario;
 import org.chromium.base.jank_tracker.JankTracker;
@@ -38,6 +37,7 @@
 import org.chromium.chrome.browser.layouts.animation.CompositorAnimator;
 import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
 import org.chromium.chrome.browser.tasks.TasksSurface;
@@ -173,10 +173,7 @@
         };
 
         mController.addOverviewModeObserver(mStartSurfaceObserver);
-        if (TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()) {
-            mThumbnailAspectRatio = (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-            mThumbnailAspectRatio = MathUtils.clamp(mThumbnailAspectRatio, 0.5f, 2.0f);
-        }
+        mThumbnailAspectRatio = TabUtils.getTabThumbnailAspectRatio(getContext());
     }
 
     @Override
@@ -479,10 +476,8 @@
         // down, making the "create group" visible for a while.
         animationList.add(CompositorAnimator.ofWritableFloatPropertyKey(handler, sourceLayoutTab,
                 LayoutTab.MAX_CONTENT_HEIGHT, sourceLayoutTab.getUnclampedOriginalContentHeight(),
-                TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()
-                        ? Math.min(getWidth() / mThumbnailAspectRatio,
-                                sourceLayoutTab.getUnclampedOriginalContentHeight())
-                        : getWidth(),
+                Math.min(getWidth() / mThumbnailAspectRatio,
+                        sourceLayoutTab.getUnclampedOriginalContentHeight()),
                 ZOOMING_DURATION, Interpolators.FAST_OUT_SLOW_IN_INTERPOLATOR));
 
         CompositorAnimator backgroundAlpha =
@@ -535,10 +530,8 @@
         // down, making the "create group" visible for a while.
         animationList.add(CompositorAnimator.ofWritableFloatPropertyKey(handler, sourceLayoutTab,
                 LayoutTab.MAX_CONTENT_HEIGHT,
-                TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()
-                        ? Math.min(getWidth() / mThumbnailAspectRatio,
-                                sourceLayoutTab.getUnclampedOriginalContentHeight())
-                        : getWidth(),
+                Math.min(getWidth() / mThumbnailAspectRatio,
+                        sourceLayoutTab.getUnclampedOriginalContentHeight()),
                 sourceLayoutTab.getUnclampedOriginalContentHeight(), ZOOMING_DURATION,
                 Interpolators.FAST_OUT_SLOW_IN_INTERPOLATOR));
 
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
index cd37f8c..9ab590a 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTabSwitcherTest.java
@@ -45,7 +45,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.MathUtils;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.params.ParameterAnnotations;
 import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
@@ -73,7 +72,6 @@
 import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
 import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab;
 import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
-import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
@@ -432,10 +430,8 @@
         onViewWaiting(allOf(withId(org.chromium.chrome.test.R.id.tab_thumbnail), isDisplayed()));
 
         View tabThumbnail = cta.findViewById(org.chromium.chrome.test.R.id.tab_thumbnail);
-        float defaultRatio = (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-        defaultRatio = MathUtils.clamp(defaultRatio, 0.5f, 2.0f);
         assertEquals(tabThumbnail.getMeasuredHeight(),
-                (int) (tabThumbnail.getMeasuredWidth() * 1.0 / defaultRatio), 2);
+                (int) (tabThumbnail.getMeasuredWidth() * 1.0 / 0.85f), 2);
     }
 
     @Test
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
index 66ff007..5a04e15 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -142,7 +142,7 @@
     @Restriction({Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE,
         UiRestriction.RESTRICTION_TYPE_PHONE, UiRestriction.RESTRICTION_TYPE_TABLET})
     @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION,
-            "force-fieldtrial-params=Study.Group:allow_to_refetch/true/thumbnail_aspect_ratio/2.0"})
+            "force-fieldtrial-params=Study.Group:allow_to_refetch/true"})
     public void fetchThumbnailsPreNativeTest() {
         // clang-format on
         StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule);
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
index 5f27ba6..77fd6758 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -8,6 +8,7 @@
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
@@ -168,7 +169,7 @@
 @Restriction(
         {UiRestriction.RESTRICTION_TYPE_PHONE, Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 @DisableIf.Build(message = "Flaky on emulators; see https://crbug.com/1130830",
-        supported_abis_includes = "x86")
+    supported_abis_includes = "x86")
 public class StartSurfaceLayoutTest {
     // clang-format on
     private static final String BASE_PARAMS = "force-fieldtrial-params="
@@ -257,6 +258,7 @@
     // clang-format off
     @CommandLineFlags.Add({BASE_PARAMS})
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
+    @DisabledTest(message = "https://crbug.com/1300962")
     @DisableIf.Build(sdk_is_greater_than = O_MR1, message = "crbug.com/1077552")
     public void testRenderGrid_10WebTabs() throws IOException {
         // clang-format on
@@ -864,8 +866,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
-        + "thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testTabSuggestionMessageCard_dismiss() throws InterruptedException {
         // clang-format on
         prepareTabs(3, 0, null);
@@ -883,6 +884,7 @@
         // TabSwitcherCoordinator::hasAppendedMessagesForTesting. Instead, we can query the number
         // of items that the inner model of the TabSwitcher has.
         CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
+        onView(tabSwitcherViewMatcher()).perform(swipeUp());
         onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
         onView(allOf(withId(R.id.close_button), withParent(withId(R.id.tab_grid_message_item))))
                 .perform(click());
@@ -896,8 +898,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"
-        + "/thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testTabSuggestionMessageCard_review() throws InterruptedException {
         // clang-format on
         prepareTabs(3, 0, null);
@@ -909,6 +910,7 @@
         enterGTSWithThumbnailChecking();
 
         CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
+        onView(tabSwitcherViewMatcher()).perform(swipeUp());
         onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
         onView(allOf(withId(R.id.action_button), withParent(withId(R.id.tab_grid_message_item))))
                 .perform(click());
@@ -929,8 +931,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
-        + "thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testShowOnlyOneTabSuggestionMessageCard_withSoftCleanup()
             throws InterruptedException {
         // clang-format on
@@ -944,8 +945,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
-        + "thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     @FlakyTest(message = "https://crbug.com/1198484")
     public void testShowOnlyOneTabSuggestionMessageCard_withHardCleanup()
             throws InterruptedException {
@@ -960,8 +960,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
-        + "thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testTabSuggestionMessageCardDismissAfterTabClosing() throws InterruptedException {
         // clang-format on
         prepareTabs(3, 0, mUrl);
@@ -971,6 +970,7 @@
 
         enterGTSWithThumbnailChecking();
         CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
+        onView(tabSwitcherViewMatcher()).perform(swipeUp());
         onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
 
         closeFirstTabInTabSwitcher();
@@ -1050,8 +1050,7 @@
     @EnableFeatures({ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study",
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0/"
-        + "thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testTabSuggestionMessageCard_orientation() throws InterruptedException {
         // clang-format on
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
@@ -1147,39 +1146,26 @@
         prepareTabs(2, 0, mUrl);
         enterTabSwitcher(mActivityTestRule.getActivity());
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(1.0));
-    }
-
-    @Test
-    @MediumTest
-    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
-    @DisabledTest(message = "https://crbug.com/1122657")
-    public void testThumbnailAspectRatio_point75() {
-        prepareTabs(2, 0, mUrl);
-        enterTabSwitcher(mActivityTestRule.getActivity());
-        onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75));
-        leaveGTSAndVerifyThumbnailsAreReleased();
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
 
         Tab tab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab();
         mActivityTestRule.loadUrlInTab(
                 NTP_URL, PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR, tab);
         enterTabSwitcher(mActivityTestRule.getActivity());
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.75));
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
     }
 
     @Test
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
+    @CommandLineFlags.Add({BASE_PARAMS + "allow_to_refetch/true"})
     @DisabledTest(message = "Flaky - https://crbug.com/1124041")
-    public void testThumbnailAspectRatio_fromTwoToPoint75() throws Exception {
+    public void testThumbnailAspectRatio_fromPoint85ToPoint75() throws Exception {
         prepareTabs(2, 0, mUrl);
         enterTabSwitcher(mActivityTestRule.getActivity());
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
         TabModel currentTabModel =
                 mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
         for (int i = 0; i < currentTabModel.getCount(); i++) {
@@ -1192,7 +1178,7 @@
 
         enterTabSwitcher(mActivityTestRule.getActivity());
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
         TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
     }
 
@@ -1276,7 +1262,7 @@
     @Test
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/2.0/allow_to_refetch/true"})
+    @CommandLineFlags.Add({BASE_PARAMS + "allow_to_refetch/true"})
     @DisabledTest(message = "http://crbug/1119527 - Flaky on bots.")
     public void testThumbnailFetchingResult_changingAspectRatio() throws Exception {
         prepareTabs(2, 0, mUrl);
@@ -1319,7 +1305,7 @@
         oldDifferentAspectRatioJpegCount = currentDifferentAspectRatioJpegCount;
 
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
 
         TabModel currentTabModel =
                 mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel();
@@ -1353,14 +1339,14 @@
                         TabContentManager.ThumbnailFetchingResult.GOT_NOTHING)
                         - oldNothingCount);
         onView(tabSwitcherViewMatcher())
-                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(2.0));
+                .check(ThumbnailAspectRatioAssertion.havingAspectRatio(0.85));
     }
 
     @Test
     @MediumTest
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
     @CommandLineFlags.Add({BASE_PARAMS})
-    public void testRecycling_defaultAspectRatio() {
+    public void testRecycling() {
         prepareTabs(10, 0, mUrl);
         ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
         enterTabSwitcher(mActivityTestRule.getActivity());
@@ -1371,21 +1357,8 @@
     @MediumTest
     // clang-format off
     @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
-    public void testRecycling_aspectRatioPoint75() {
-        // clang-format on
-        prepareTabs(10, 0, mUrl);
-        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
-        enterTabSwitcher(mActivityTestRule.getActivity());
-        onView(tabSwitcherViewMatcher()).perform(RecyclerViewActions.scrollToPosition(9));
-    }
-
-    @Test
-    @MediumTest
-    // clang-format off
-    @EnableFeatures({ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/0.75"})
-    public void testExpandTab_withAspectRatioPoint75() {
+    @CommandLineFlags.Add({BASE_PARAMS})
+    public void testExpandTab() {
         // clang-format on
         prepareTabs(1, 0, mUrl);
         enterTabSwitcher(mActivityTestRule.getActivity());
@@ -1398,9 +1371,9 @@
     // clang-format off
     @EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
             ChromeFeatureList.TAB_TO_GTS_ANIMATION + "<Study"})
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/1.0"})
+    @CommandLineFlags.Add({BASE_PARAMS})
     @DisabledTest(message = "https://crbug.com/1205952")
-    public void testRenderGrid_withAspectRatioOfOne() throws IOException {
+    public void testRenderGrid() throws IOException {
         // clang-format on
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         prepareTabs(3, 0, "about:blank");
@@ -1895,8 +1868,7 @@
             ChromeFeatureList.CLOSE_TAB_SUGGESTIONS + "<Study"})
     @DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
     @CommandLineFlags.Add({BASE_PARAMS + "/baseline_tab_suggestions/true" +
-            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0" +
-            "/thumbnail_aspect_ratio/1.0"})
+            "/baseline_close_tab_suggestions/true/min_time_between_prefetches/0"})
     public void testTabGroupManualSelection_AfterReviewTabSuggestion() throws InterruptedException {
         // clang-format on
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
@@ -1914,6 +1886,7 @@
         // thumbnail checking here is to ensure the suggestion is valid when entering tab switcher.
         enterGTSWithThumbnailChecking();
         CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
+        onView(tabSwitcherViewMatcher()).perform(swipeUp());
         onView(withId(R.id.tab_grid_message_item)).check(matches(isDisplayed()));
         onView(allOf(withId(R.id.action_button), withParent(withId(R.id.tab_grid_message_item))))
                 .perform(click());
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 99b3136..f247ca42 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
@@ -18,10 +18,10 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
-import org.chromium.base.MathUtils;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
@@ -216,9 +216,7 @@
             TabModelSelector tabModelSelector) {
         mContext = context;
         Resources resource = context.getResources();
-        float expectedThumbnailAspectRatio =
-                (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-        expectedThumbnailAspectRatio = MathUtils.clamp(expectedThumbnailAspectRatio, 0.5f, 2.0f);
+        float expectedThumbnailAspectRatio = TabUtils.getTabThumbnailAspectRatio(context);
 
         mThumbnailWidth = (int) resource.getDimension(R.dimen.tab_grid_thumbnail_card_default_size);
         mThumbnailHeight = (int) (mThumbnailWidth / expectedThumbnailAspectRatio);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java
index 0faa39b..2ee27f9a 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/NewTabTileMediator.java
@@ -6,9 +6,8 @@
 
 import static org.chromium.chrome.browser.tasks.tab_management.NewTabTileViewProperties.IS_INCOGNITO;
 
-import org.chromium.base.MathUtils;
 import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
@@ -28,10 +27,7 @@
         mTabModelSelector = tabModelSelector;
 
         // Deliberately use un-cached value to match with native.
-        float aspectRatio = (float) ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(
-                ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
-                TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO_PARAM, 1.0);
-        aspectRatio = MathUtils.clamp(aspectRatio, 0.5f, 2.0f);
+        float aspectRatio = TabUtils.getTabThumbnailAspectRatio(null);
         model.set(NewTabTileViewProperties.THUMBNAIL_ASPECT_RATIO, aspectRatio);
         model.set(NewTabTileViewProperties.CARD_HEIGHT_INTERCEPT, 0);
         model.set(NewTabTileViewProperties.ON_CLICK_LISTENER, view -> {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java
index dfda4ef..8effabf5 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridThumbnailView.java
@@ -8,7 +8,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.util.AttributeSet;
 
-import org.chromium.base.MathUtils;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
 import org.chromium.components.browser_ui.widget.RoundedCornerImageView;
 
@@ -23,8 +23,7 @@
 
     public TabGridThumbnailView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mAspectRatio = MathUtils.clamp(
-                (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue(), 0.5f, 2.0f);
+        mAspectRatio = TabUtils.getTabThumbnailAspectRatio(context);
     }
 
     @Override
@@ -74,15 +73,8 @@
             return;
         }
 
-        if (TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()) {
-            float expectedThumbnailAspectRatio =
-                    (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-            expectedThumbnailAspectRatio =
-                    MathUtils.clamp(expectedThumbnailAspectRatio, 0.5f, 2.0f);
-            int height = (int) (getWidth() * 1.0 / expectedThumbnailAspectRatio);
-            setMinimumHeight(Math.min(getHeight(), height));
-        } else {
-            setMinimumHeight(getWidth());
-        }
+        float expectedThumbnailAspectRatio = TabUtils.getTabThumbnailAspectRatio(getContext());
+        int height = (int) (getWidth() * 1.0 / expectedThumbnailAspectRatio);
+        setMinimumHeight(Math.min(getHeight(), height));
     }
 }
\ No newline at end of file
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
index 99d59e9..b93c313 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -23,10 +23,10 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import org.chromium.base.MathUtils;
 import org.chromium.chrome.browser.lifecycle.DestroyObserver;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
 import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab;
@@ -165,18 +165,10 @@
                     return;
                 }
 
-                if (TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()) {
-                    float expectedThumbnailAspectRatio =
-                            (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-                    expectedThumbnailAspectRatio =
-                            MathUtils.clamp(expectedThumbnailAspectRatio, 0.5f, 2.0f);
-                    int height = (int) (thumbnail.getWidth() * 1.0 / expectedThumbnailAspectRatio);
-                    thumbnail.setMinimumHeight(Math.min(thumbnail.getHeight(), height));
-                    thumbnail.setImageDrawable(null);
-                } else {
-                    thumbnail.setImageDrawable(null);
-                    thumbnail.setMinimumHeight(thumbnail.getWidth());
-                }
+                float expectedThumbnailAspectRatio = TabUtils.getTabThumbnailAspectRatio(context);
+                int height = (int) (thumbnail.getWidth() * 1.0 / expectedThumbnailAspectRatio);
+                thumbnail.setMinimumHeight(Math.min(thumbnail.getHeight(), height));
+                thumbnail.setImageDrawable(null);
             };
         } else if (mMode == TabListMode.STRIP) {
             mAdapter.registerType(UiType.STRIP, parent -> {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
index c0ab9c1..45b742d7 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiFeatureUtilities.java
@@ -16,7 +16,6 @@
 import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
-import org.chromium.chrome.browser.flags.DoubleCachedFieldTrialParameter;
 import org.chromium.chrome.browser.flags.IntCachedFieldTrialParameter;
 import org.chromium.chrome.browser.flags.StringCachedFieldTrialParameter;
 import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils;
@@ -41,11 +40,6 @@
             new StringCachedFieldTrialParameter(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
                     TAB_GRID_LAYOUT_ANDROID_NEW_TAB_TILE_PARAM, "");
 
-    public static final String THUMBNAIL_ASPECT_RATIO_PARAM = "thumbnail_aspect_ratio";
-    public static final DoubleCachedFieldTrialParameter THUMBNAIL_ASPECT_RATIO =
-            new DoubleCachedFieldTrialParameter(
-                    ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, THUMBNAIL_ASPECT_RATIO_PARAM, 0.85);
-
     private static final String SEARCH_CHIP_PARAM = "enable_search_term_chip";
     public static final BooleanCachedFieldTrialParameter ENABLE_SEARCH_CHIP =
             new BooleanCachedFieldTrialParameter(
@@ -175,13 +169,6 @@
                 && !ConditionalTabStripUtils.getOptOutIndicator();
     }
 
-    /**
-     * @return Whether the thumbnail_aspect_ratio field trail is set.
-     */
-    public static boolean isTabThumbnailAspectRatioNotOne() {
-        return Double.compare(1.0, THUMBNAIL_ASPECT_RATIO.getValue()) != 0;
-    }
-
     public static boolean isTabGridLayoutAndroidNewTabTileEnabled() {
         return TextUtils.equals(TAB_GRID_LAYOUT_ANDROID_NEW_TAB_TILE.getValue(), "NewTabTile");
     }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialogTest.java
index 4949cac3..e671bca 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsDialogTest.java
@@ -6,6 +6,7 @@
 
 import static androidx.test.espresso.action.ViewActions.click;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 
@@ -80,7 +81,8 @@
         navigateToCloseAllTabsDialog(selector);
         onViewWaiting(withId(org.chromium.chrome.test.R.id.positive_button)).perform(click());
 
-        assertEquals(0, selector.getModel(mIsIncognito).getCount());
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { assertEquals(0, selector.getModel(mIsIncognito).getCount()); });
     }
 
     /**
@@ -96,7 +98,8 @@
         navigateToCloseAllTabsDialog(selector);
         onViewWaiting(withId(org.chromium.chrome.test.R.id.negative_button)).perform(click());
 
-        assertEquals(1, selector.getModel(mIsIncognito).getCount());
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> { assertEquals(1, selector.getModel(mIsIncognito).getCount()); });
     }
 
     private void navigateToCloseAllTabsDialog(TabModelSelector selector) {
@@ -106,11 +109,9 @@
         assertEquals(1, selector.getModel(mIsIncognito).getCount());
 
         // Open the AppMenu in the Tab Switcher and ensure it shows.
-        onViewWaiting(withId(org.chromium.chrome.test.R.id.tab_switcher_button))
-                .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
-                .perform(click());
+        TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
         onViewWaiting(withId(org.chromium.chrome.test.R.id.tab_switcher_toolbar))
-                .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
+                .check(matches(isDisplayed()));
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false);
         });
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardTest.java
index 1a3a136..9a7ccdc 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSuggestionMessageCardTest.java
@@ -6,6 +6,7 @@
 
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.swipeUp;
 import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static androidx.test.espresso.assertion.ViewAssertions.matches;
 import static androidx.test.espresso.matcher.ViewMatchers.assertThat;
@@ -72,7 +73,7 @@
     // clang-format on
     private static final String BASE_PARAMS = "force-fieldtrial-params="
             + "Study.Group:baseline_tab_suggestions/true/enable_launch_polish/true"
-            + "/min_time_between_prefetches/0/thumbnail_aspect_ratio/1.0";
+            + "/min_time_between_prefetches/0";
     private static final String ENABLE_CLOSE_SUGGESTION_PARAM =
             "/baseline_close_tab_suggestions/true";
     private static final String ENABLE_GROUP_SUGGESTION_PARAM =
@@ -137,6 +138,8 @@
     private void enteringTabSwitcherAndVerifySuggestionIsShown(String suggestionText) {
         TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
         CriteriaHelper.pollUiThread(TabSwitcherCoordinator::hasAppendedMessagesForTesting);
+        onView(allOf(withParent(withId(R.id.compositor_view_holder)), withId(R.id.tab_list_view)))
+                .perform(swipeUp());
         onView(allOf(withParent(withId(R.id.tab_grid_message_item)), withText(suggestionText)))
                 .check(matches(isDisplayed()));
     }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
index 0d3be5ff..0cb8cca3 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherThumbnailTest.java
@@ -79,22 +79,6 @@
 
     @Test
     @MediumTest
-    @CommandLineFlags.Add({BASE_PARAMS + "/thumbnail_aspect_ratio/1.0"})
-    @FlakyTest(message = "https://crbug.com/1208059")
-    public void testThumbnailAspectRatio_one() {
-        int tabCounts = 11;
-        TabUiTestHelper.prepareTabsWithThumbnail(mActivityTestRule, tabCounts, 0, "about:blank");
-        TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
-        verifyAllThumbnailHeightWithAspectRatio(tabCounts, 1.f);
-
-        // With hard cleanup.
-        TabUiTestHelper.leaveTabSwitcher(mActivityTestRule.getActivity());
-        TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
-        verifyAllThumbnailHeightWithAspectRatio(tabCounts, 1.f);
-    }
-
-    @Test
-    @MediumTest
     @CommandLineFlags.Add({BASE_PARAMS})
     @FlakyTest(message = "https://crbug.com/1208059")
     public void testThumbnailAspectRatio_point85() {
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java
new file mode 100644
index 0000000..831c686
--- /dev/null
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java
@@ -0,0 +1,46 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+package org.chromium.chrome.browser.tab;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+/**
+ * Tests for {@link TabUtils}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+public final class TabUtilsUnitTest {
+    @Test
+    public void testGetTabThumbnailAspectRatio_withNullContext() {
+        assertThat(TabUtils.getTabThumbnailAspectRatio(null))
+                .isEqualTo(TabUtils.TAB_THUMBNAIL_ASPECT_RATIO);
+    }
+
+    @Test
+    @Config(qualifiers = "sw320dp")
+    public void testGetTabThumbnailAspectRatio_withNonTabletContext() {
+        assertThat(TabUtils.getTabThumbnailAspectRatio(ContextUtils.getApplicationContext()))
+                .isEqualTo(TabUtils.TAB_THUMBNAIL_ASPECT_RATIO);
+    }
+
+    @Test
+    @Config(qualifiers = "sw800dp-port")
+    public void testGetTabThumbnailAspectRatio_withTabletPortraitContext() {
+        assertThat(TabUtils.getTabThumbnailAspectRatio(ContextUtils.getApplicationContext()))
+                .isEqualTo(TabUtils.TAB_THUMBNAIL_ASPECT_RATIO);
+    }
+
+    @Test
+    @Config(qualifiers = "sw800dp-land")
+    public void testGetTabThumbnailAspectRatio_withTabletLandscapeContext() {
+        assertThat(TabUtils.getTabThumbnailAspectRatio(ContextUtils.getApplicationContext()))
+                .isEqualTo(TabUtils.TABLET_LANDSCAPE_TAB_THUMBNAIL_ASPECT_RATIO);
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni
index b8742179..ddd44d8 100644
--- a/chrome/android/features/tab_ui/tab_management_java_sources.gni
+++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -62,6 +62,7 @@
 ]
 
 tab_management_junit_java_sources = [
+  "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tab/TabUtilsUnitTest.java",
   "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/SingleTabSwitcherMediatorUnitTest.java",
   "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/TasksSurfaceMediatorUnitTest.java",
   "//chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTabUnitTest.java",
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/network_fetch/FeedNewTabPageCardInstrumentationTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/network_fetch/FeedNewTabPageCardInstrumentationTest.java
index 8efda44..18d6213 100644
--- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/network_fetch/FeedNewTabPageCardInstrumentationTest.java
+++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/network_fetch/FeedNewTabPageCardInstrumentationTest.java
@@ -2,6 +2,8 @@
 // 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.feed.network_fetch;
+
 import static androidx.test.espresso.Espresso.onView;
 import static androidx.test.espresso.action.ViewActions.click;
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
diff --git a/chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index ed82b86..0000000
--- a/chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_tab_normal.png b/chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_tab.png
similarity index 100%
rename from chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_tab_normal.png
rename to chrome/android/java/res/drawable-hdpi/btn_tabstrip_new_tab.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-ldrtl-hdpi-v17/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-ldrtl-hdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 50ac6ad..0000000
--- a/chrome/android/java/res/drawable-ldrtl-hdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-ldrtl-mdpi-v17/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-ldrtl-mdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 927d1594..0000000
--- a/chrome/android/java/res/drawable-ldrtl-mdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-ldrtl-xhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-ldrtl-xhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 6b8b4c5..0000000
--- a/chrome/android/java/res/drawable-ldrtl-xhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-ldrtl-xxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-ldrtl-xxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index aa322b77..0000000
--- a/chrome/android/java/res/drawable-ldrtl-xxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-ldrtl-xxxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-ldrtl-xxxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 3501179..0000000
--- a/chrome/android/java/res/drawable-ldrtl-xxxhdpi-v17/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index ff75156f..0000000
--- a/chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_tab_normal.png b/chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_tab.png
similarity index 100%
rename from chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_tab_normal.png
rename to chrome/android/java/res/drawable-mdpi/btn_tabstrip_new_tab.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 0c7c38c..0000000
--- a/chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_tab_normal.png b/chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_tab.png
similarity index 100%
rename from chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_tab_normal.png
rename to chrome/android/java/res/drawable-xhdpi/btn_tabstrip_new_tab.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 518faf1..0000000
--- a/chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_tab_normal.png b/chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_tab.png
similarity index 100%
rename from chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_tab_normal.png
rename to chrome/android/java/res/drawable-xxhdpi/btn_tabstrip_new_tab.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_incognito_tab_normal.png b/chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_incognito_tab_normal.png
deleted file mode 100644
index 24dbc4e..0000000
--- a/chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_incognito_tab_normal.png
+++ /dev/null
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_tab_normal.png b/chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_tab.png
similarity index 100%
rename from chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_tab_normal.png
rename to chrome/android/java/res/drawable-xxxhdpi/btn_tabstrip_new_tab.png
Binary files differ
diff --git a/chrome/android/java/res_base/values/ic_launcher_round_alias.xml b/chrome/android/java/res_base/values/ic_launcher_round_alias.xml
new file mode 100644
index 0000000..0b216d5e
--- /dev/null
+++ b/chrome/android/java/res_base/values/ic_launcher_round_alias.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2022 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources>
+    <drawable name="ic_launcher_round">@mipmap/app_icon</drawable>
+</resources>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index 4d47c02b..bc4ad483 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -85,6 +85,7 @@
                 add(ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID);
                 add(ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE);
                 add(ChromeFeatureList.DYNAMIC_COLOR_ANDROID);
+                add(ChromeFeatureList.DYNAMIC_COLOR_BUTTONS_ANDROID);
                 add(ChromeFeatureList.EARLY_LIBRARY_LOAD);
                 add(ChromeFeatureList.ELASTIC_OVERSCROLL);
                 add(ChromeFeatureList.ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS);
@@ -174,7 +175,6 @@
                         add(TabUiFeatureUtilities.ZOOMING_MIN_SDK);
                         add(TabUiFeatureUtilities.SKIP_SLOW_ZOOMING);
                         add(TabUiFeatureUtilities.TAB_GRID_LAYOUT_ANDROID_NEW_TAB_TILE);
-                        add(TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO);
                         add(TabUiFeatureUtilities.GRID_TAB_SWITCHER_FOR_TABLETS_POLISH);
                         add(ThemeUtils.ENABLE_FULL_DYNAMIC_COLORS);
                     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
index 6c89a45..779af070 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java
@@ -397,7 +397,7 @@
         for (LegalMessageLine line : legalMessageLines) {
             SpannableString text = new SpannableString(line.text);
             for (final LegalMessageLine.Link link : line.links) {
-                text.setSpan(new NoUnderlineClickableSpan(context.getResources(),
+                text.setSpan(new NoUnderlineClickableSpan(context,
                                      (view) -> CustomTabActivity.showInfoPage(context, link.url)),
                         link.start, link.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
             }
@@ -420,7 +420,7 @@
             Context context, int stringResourceId, String url) {
         return SpanApplier.applySpans(context.getString(stringResourceId),
                 new SpanApplier.SpanInfo("<link1>", "</link1>",
-                        new NoUnderlineClickableSpan(context.getResources(),
-                                (view) -> CustomTabActivity.showInfoPage(context, url))));
+                        new NoUnderlineClickableSpan(
+                                context, (view) -> CustomTabActivity.showInfoPage(context, url))));
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java
index 47e9d31..76d7320 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPreferenceFragment.java
@@ -90,7 +90,7 @@
         }
 
         mGoogleServicesSettingsLink = findPreference(PREF_GOOGLE_SERVICES_SETTINGS_LINK);
-        NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(getResources(), view -> {
+        NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(getContext(), view -> {
             SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
             settingsLauncher.launchSettingsActivity(requireContext(), GoogleServicesSettings.class);
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
index 9e56129d..4d6136f2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/base/SplitPreloader.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.base;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.os.SystemClock;
 
 import androidx.collection.SimpleArrayMap;
@@ -14,6 +15,7 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.AsyncTask;
 import org.chromium.base.task.TaskTraits;
+import org.chromium.chrome.browser.language.GlobalAppLocaleController;
 
 /**
  * Handles preloading split Contexts on a background thread. Loading a new isolated split
@@ -87,7 +89,13 @@
 
         private Context createSplitContext() {
             if (BundleUtils.isIsolatedSplitInstalled(mContext, mName)) {
-                return BundleUtils.createIsolatedSplitContext(mContext, mName);
+                Context context = BundleUtils.createIsolatedSplitContext(mContext, mName);
+                if (GlobalAppLocaleController.getInstance().isOverridden()) {
+                    Configuration config =
+                            GlobalAppLocaleController.getInstance().getOverrideConfig(context);
+                    context = context.createConfigurationContext(config);
+                }
+                return context;
             }
             return mContext;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java
index e7097db..bb220e9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataCheckBoxPreference.java
@@ -101,7 +101,7 @@
         // Linkify <link></link> span.
         final SpannableString summaryWithLink = SpanApplier.applySpans(summaryString,
                 new SpanApplier.SpanInfo("<link>", "</link>",
-                        new NoUnderlineClickableSpan(getContext().getResources(), (widget) -> {
+                        new NoUnderlineClickableSpan(getContext(), (widget) -> {
                             if (mLinkClickDelegate != null) mLinkClickDelegate.run();
                         })));
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java
index 71bb4902..ab0fcc0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/ClearBrowsingDataFragmentBasic.java
@@ -177,10 +177,10 @@
     private SpannableString buildGoogleSearchHistoryText() {
         return SpanApplier.applySpans(getContext().getString(R.string.clear_search_history_link),
                 new SpanInfo("<link1>", "</link1>",
-                        new NoUnderlineClickableSpan(getContext().getResources(),
+                        new NoUnderlineClickableSpan(getContext(),
                                 createOpenMyActivityCallback(/* openSearchHistory = */ true))),
                 new SpanInfo("<link2>", "</link2>",
-                        new NoUnderlineClickableSpan(getContext().getResources(),
+                        new NoUnderlineClickableSpan(getContext(),
                                 createOpenMyActivityCallback(/* openSearchHistory = */ false))));
     }
 
@@ -188,7 +188,7 @@
         return SpanApplier.applySpans(
                 getContext().getString(R.string.clear_search_history_link_other_forms),
                 new SpanInfo("<link1>", "</link1>",
-                        new NoUnderlineClickableSpan(getContext().getResources(),
+                        new NoUnderlineClickableSpan(getContext(),
                                 createOpenMyActivityCallback(/* openSearchHistory = */ false))));
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/OtherFormsOfHistoryDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/OtherFormsOfHistoryDialogFragment.java
index 19f09069..8f20f2e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/OtherFormsOfHistoryDialogFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/browsing_data/OtherFormsOfHistoryDialogFragment.java
@@ -52,7 +52,7 @@
         TextView textView = (TextView) view.findViewById(R.id.text);
         final SpannableString textWithLink = SpanApplier.applySpans(textView.getText().toString(),
                 new SpanApplier.SpanInfo("<link>", "</link>",
-                        new NoUnderlineClickableSpan(getResources(), (widget) -> {
+                        new NoUnderlineClickableSpan(getContext(), (widget) -> {
                             new TabDelegate(false /* incognito */)
                                     .launchUrl(UrlConstants.MY_ACTIVITY_URL_IN_CBD_NOTICE,
                                             TabLaunchType.FROM_CHROME_UI);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
index f791f72..2cb9b13 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPromoControl.java
@@ -348,7 +348,7 @@
         // Fill in text with link to Settings.
         TextView promoText = (TextView) view.findViewById(R.id.contextual_search_promo_text);
 
-        NoUnderlineClickableSpan settingsLink = new NoUnderlineClickableSpan(view.getResources(),
+        NoUnderlineClickableSpan settingsLink = new NoUnderlineClickableSpan(view.getContext(),
                 (View ignored) -> ContextualSearchPromoControl.this.handleClickSettingsLink());
 
         promoText.setText(SpanApplier.applySpans(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
index 9d3dd97d..f960f8a9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -21,7 +21,6 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.CommandLine;
-import org.chromium.base.MathUtils;
 import org.chromium.base.PathUtils;
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.TraceEvent;
@@ -35,6 +34,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.chrome.browser.ui.native_page.FrozenNativePage;
 import org.chromium.chrome.browser.ui.native_page.NativePage;
@@ -184,12 +184,8 @@
 
         mPriorityTabIds = new int[mFullResThumbnailsMaxSize];
 
-        if (TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()
-                || ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION.getValue()) {
-            mExpectedThumbnailAspectRatio =
-                    (float) TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO.getValue();
-            mExpectedThumbnailAspectRatio =
-                    MathUtils.clamp(mExpectedThumbnailAspectRatio, 0.5f, 2.0f);
+        if (ALLOW_TO_REFETCH_TAB_THUMBNAIL_VARIATION.getValue()) {
+            mExpectedThumbnailAspectRatio = TabUtils.getTabThumbnailAspectRatio(context);
         }
     }
 
@@ -214,7 +210,8 @@
 
         mNativeTabContentManager = TabContentManagerJni.get().init(TabContentManager.this,
                 mFullResThumbnailsMaxSize, approximationCacheSize, compressionQueueMaxSize,
-                writeQueueMaxSize, useApproximationThumbnails, saveJpegThumbnails);
+                writeQueueMaxSize, useApproximationThumbnails, saveJpegThumbnails,
+                mExpectedThumbnailAspectRatio);
     }
 
     /**
@@ -475,7 +472,8 @@
 
                             mRefectchedTabIds.add(tabId);
                             TabContentManagerJni.get().getEtc1TabThumbnail(mNativeTabContentManager,
-                                    TabContentManager.this, tabId, callback);
+                                    TabContentManager.this, tabId, mExpectedThumbnailAspectRatio,
+                                    callback);
                             return;
                         }
                     }
@@ -485,8 +483,8 @@
                     return;
                 }
                 if (mNativeTabContentManager == 0 || !mSnapshotsEnabled) return;
-                TabContentManagerJni.get().getEtc1TabThumbnail(
-                        mNativeTabContentManager, TabContentManager.this, tabId, (etc1) -> {
+                TabContentManagerJni.get().getEtc1TabThumbnail(mNativeTabContentManager,
+                        TabContentManager.this, tabId, mExpectedThumbnailAspectRatio, (etc1) -> {
                             if (etc1 != null) {
                                 recordThumbnailFetchingResult(ThumbnailFetchingResult.GOT_ETC1);
                             } else {
@@ -519,7 +517,8 @@
         Bitmap nativeBitmap = readbackNativeBitmap(tab, mThumbnailScale);
         if (nativeBitmap == null) return null;
         TabContentManagerJni.get().cacheTabWithBitmap(mNativeTabContentManager,
-                TabContentManager.this, tab, nativeBitmap, mThumbnailScale);
+                TabContentManager.this, tab, nativeBitmap, mThumbnailScale,
+                mExpectedThumbnailAspectRatio);
         return nativeBitmap;
     }
 
@@ -555,10 +554,8 @@
             Matrix matrix = new Matrix();
             matrix.setScale(downsamplingScale, downsamplingScale);
             Bitmap resized = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
-                    TabUiFeatureUtilities.isTabThumbnailAspectRatioNotOne()
-                            ? Math.min(bitmap.getHeight(),
-                                    (int) (bitmap.getWidth() * 1.0 / mExpectedThumbnailAspectRatio))
-                            : min(bitmap.getWidth(), bitmap.getHeight()),
+                    Math.min(bitmap.getHeight(),
+                            (int) (bitmap.getWidth() * 1.0 / mExpectedThumbnailAspectRatio)),
                     matrix, true);
             callback.onResult(resized);
         } else {
@@ -568,8 +565,8 @@
             // This faster path is essential to Tab-to-Grid animation to be smooth.
             final float downsamplingScale = writeToCache ? 1 : 0.5f;
             TabContentManagerJni.get().captureThumbnail(mNativeTabContentManager,
-                    TabContentManager.this, tab, mThumbnailScale * downsamplingScale, writeToCache,
-                    callback);
+                    TabContentManager.this, tab, mThumbnailScale * downsamplingScale,
+                    mExpectedThumbnailAspectRatio, writeToCache, callback);
         }
     }
 
@@ -653,23 +650,24 @@
         // Class Object Methods
         long init(TabContentManager caller, int defaultCacheSize, int approximationCacheSize,
                 int compressionQueueMaxSize, int writeQueueMaxSize,
-                boolean useApproximationThumbnail, boolean saveJpegThumbnails);
+                boolean useApproximationThumbnail, boolean saveJpegThumbnails, float aspectRatio);
 
         void attachTab(long nativeTabContentManager, TabContentManager caller, Tab tab, int tabId);
         void detachTab(long nativeTabContentManager, TabContentManager caller, Tab tab, int tabId);
         boolean hasFullCachedThumbnail(
                 long nativeTabContentManager, TabContentManager caller, int tabId);
         void captureThumbnail(long nativeTabContentManager, TabContentManager caller, Object tab,
-                float thumbnailScale, boolean writeToCache, Callback<Bitmap> callback);
+                float thumbnailScale, float aspectRatio, boolean writeToCache,
+                Callback<Bitmap> callback);
         void cacheTabWithBitmap(long nativeTabContentManager, TabContentManager caller, Object tab,
-                Object bitmap, float thumbnailScale);
+                Object bitmap, float thumbnailScale, float aspectRatio);
         void invalidateIfChanged(
                 long nativeTabContentManager, TabContentManager caller, int tabId, GURL url);
         void updateVisibleIds(long nativeTabContentManager, TabContentManager caller,
                 int[] priority, int primaryTabId);
         void removeTabThumbnail(long nativeTabContentManager, TabContentManager caller, int tabId);
         void getEtc1TabThumbnail(long nativeTabContentManager, TabContentManager caller, int tabId,
-                Callback<Bitmap> callback);
+                float aspectRatio, Callback<Bitmap> callback);
         void setCaptureMinRequestTimeForTesting(
                 long nativeTabContentManager, TabContentManager caller, int timeMs);
         int getPendingReadbacksForTesting(long nativeTabContentManager, TabContentManager caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index 0814829a..6a07e73 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -184,8 +184,7 @@
             }
         };
         mNewTabButton = new TintedCompositorButton(context, NEW_TAB_BUTTON_WIDTH_DP,
-                NEW_TAB_BUTTON_HEIGHT_DP, newTabClickHandler,
-                R.drawable.btn_tabstrip_new_tab_normal);
+                NEW_TAB_BUTTON_HEIGHT_DP, newTabClickHandler, R.drawable.btn_tabstrip_new_tab);
 
         mNewTabButton.setTintResources(R.color.new_tab_button_tint,
                 R.color.new_tab_button_pressed_tint, R.color.modern_white,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
index 1d0b375..32059cf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/resources/StaticResourcePreloads.java
@@ -18,8 +18,7 @@
     private static int[] sSynchronousResources = new int[] {
             R.drawable.bg_tabstrip_tab,
             R.drawable.btn_tab_close_normal,
-            R.drawable.btn_tabstrip_new_tab_normal,
-            R.drawable.btn_tabstrip_new_incognito_tab_normal,
+            R.drawable.btn_tabstrip_new_tab,
             R.drawable.spinner,
             R.drawable.spinner_white,
     };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
index 0d8283f..2edc4a9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -666,12 +666,15 @@
 
     /**
      * Overrides the decided/undecided state for the user preference.
-     * @param decidedState Whether the user has decided or not.
+     * @param decidedState Whether the user has decided to opt-in to sending page content or not.
+     * @return whether the previous decided state was fully enabled or not.
      */
     @VisibleForTesting
-    void overrideDecidedStateForTesting(boolean decidedState) {
+    boolean overrideDecidedStateForTesting(boolean decidedState) {
+        boolean wasEnabled = mFullyEnabledForTesting;
         mDidOverrideFullyEnabledForTesting = true;
         mFullyEnabledForTesting = decidedState;
+        return wasEnabled;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/device_dialog/UsbChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/device_dialog/UsbChooserDialog.java
index e57e090..587419b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/device_dialog/UsbChooserDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/device_dialog/UsbChooserDialog.java
@@ -84,16 +84,15 @@
         String noneFound = activity.getString(R.string.usb_chooser_dialog_no_devices_found_prompt);
         SpannableString statusActive = SpanApplier.applySpans(
                 activity.getString(R.string.usb_chooser_dialog_footnote_text),
-                new SpanInfo("<link>", "</link>",
-                        new NoUnderlineClickableSpan(activity.getResources(), (view) -> {
-                            if (mNativeUsbChooserDialogPtr == 0) return;
+                new SpanInfo("<link>", "</link>", new NoUnderlineClickableSpan(activity, (view) -> {
+                    if (mNativeUsbChooserDialogPtr == 0) return;
 
-                            Natives jni = UsbChooserDialogJni.get();
-                            jni.loadUsbHelpPage(mNativeUsbChooserDialogPtr);
+                    Natives jni = UsbChooserDialogJni.get();
+                    jni.loadUsbHelpPage(mNativeUsbChooserDialogPtr);
 
-                            // Get rid of the highlight background on selection.
-                            view.invalidate();
-                        })));
+                    // Get rid of the highlight background on selection.
+                    view.invalidate();
+                })));
         SpannableString statusIdleNoneFound = statusActive;
         SpannableString statusIdleSomeFound = statusActive;
         String positiveButton = activity.getString(R.string.usb_chooser_dialog_connect_button_text);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
index 074ffcbc..052afce0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.firstrun;
 
-import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -109,13 +108,12 @@
         setContentView(LayoutInflater.from(LightweightFirstRunActivity.this)
                                .inflate(R.layout.lightweight_fre_tos, null));
 
-        final Resources resources = getResources();
         NoUnderlineClickableSpan clickableGoogleTermsSpan = new NoUnderlineClickableSpan(
-                resources, (view) -> showInfoPage(R.string.google_terms_of_service_url));
+                this, (view) -> showInfoPage(R.string.google_terms_of_service_url));
         NoUnderlineClickableSpan clickableChromeAdditionalTermsSpan = new NoUnderlineClickableSpan(
-                resources, (view) -> showInfoPage(R.string.chrome_additional_terms_of_service_url));
+                this, (view) -> showInfoPage(R.string.chrome_additional_terms_of_service_url));
         NoUnderlineClickableSpan clickableGooglePrivacySpan = new NoUnderlineClickableSpan(
-                resources, (view) -> showInfoPage(R.string.google_privacy_policy_url));
+                this, (view) -> showInfoPage(R.string.google_privacy_policy_url));
         String associatedAppName =
                 IntentUtils.safeGetStringExtra(getIntent(), EXTRA_ASSOCIATED_APP_NAME);
         if (associatedAppName == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
index 5249707..b57392a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
@@ -194,7 +194,7 @@
 
     private SpanInfo buildTermsOfServiceLink() {
         NoUnderlineClickableSpan clickableGoogleTermsSpan =
-                new NoUnderlineClickableSpan(getResources(), (view1) -> {
+                new NoUnderlineClickableSpan(getContext(), (view1) -> {
                     if (!isAdded()) return;
                     getPageDelegate().showInfoPage(R.string.google_terms_of_service_url);
                 });
@@ -203,7 +203,7 @@
 
     private SpanInfo buildAdditionalTermsOfServiceLink() {
         NoUnderlineClickableSpan clickableChromeAdditionalTermsSpan =
-                new NoUnderlineClickableSpan(getResources(), (view1) -> {
+                new NoUnderlineClickableSpan(getContext(), (view1) -> {
                     if (!isAdded()) return;
                     getPageDelegate().showInfoPage(R.string.chrome_additional_terms_of_service_url);
                 });
@@ -212,7 +212,7 @@
 
     private SpanInfo buildPrivacyPolicyLink() {
         NoUnderlineClickableSpan clickableFamilyLinkPrivacySpan =
-                new NoUnderlineClickableSpan(getResources(), (view1) -> {
+                new NoUnderlineClickableSpan(getContext(), (view1) -> {
                     if (!isAdded()) return;
                     getPageDelegate().showInfoPage(R.string.google_privacy_policy_url);
                 });
@@ -222,7 +222,7 @@
 
     private SpanInfo buildMetricsAndCrashReportingLink() {
         NoUnderlineClickableSpan clickableUMADialogSpan =
-                new NoUnderlineClickableSpan(getResources(), (view1) -> openUmaDialog());
+                new NoUnderlineClickableSpan(getContext(), (view1) -> openUmaDialog());
         return new SpanInfo("<UMA_LINK>", "</UMA_LINK>", clickableUMADialogSpan);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
index a78acca..72c2a29 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -4,7 +4,7 @@
 
 package org.chromium.chrome.browser.history;
 
-import android.content.res.Resources;
+import android.content.Context;
 import android.text.SpannableString;
 import android.text.method.LinkMovementMethod;
 import android.view.LayoutInflater;
@@ -325,7 +325,7 @@
                 privacyDisclaimerContainer.findViewById(R.id.privacy_disclaimer);
         privacyDisclaimerTextView.setMovementMethod(LinkMovementMethod.getInstance());
         privacyDisclaimerTextView.setText(
-                getPrivacyDisclaimerText(privacyDisclaimerTextView.getResources()));
+                getPrivacyDisclaimerText(privacyDisclaimerTextView.getContext()));
         mPrivacyDisclaimerBottomSpace =
                 privacyDisclaimerContainer.findViewById(R.id.privacy_disclaimer_bottom_space);
 
@@ -361,11 +361,11 @@
      * Create a {@SpannableString} for privacy disclaimer.
      * @return The {@SpannableString} with the privacy disclaimer string resource and url.
      */
-    private SpannableString getPrivacyDisclaimerText(Resources resources) {
+    private SpannableString getPrivacyDisclaimerText(Context context) {
         NoUnderlineClickableSpan link = new NoUnderlineClickableSpan(
-                resources, (view) -> mManager.onPrivacyDisclaimerLinkClicked());
+                context, (view) -> mManager.onPrivacyDisclaimerLinkClicked());
         return SpanApplier.applySpans(
-                resources.getString(R.string.android_history_other_forms_of_history),
+                context.getResources().getString(R.string.android_history_other_forms_of_history),
                 new SpanApplier.SpanInfo("<link>", "</link>", link));
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillOfferNotificationInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillOfferNotificationInfoBar.java
index 32089d6..56f021d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillOfferNotificationInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillOfferNotificationInfoBar.java
@@ -84,7 +84,7 @@
             String linkText =
                     getContext().getString(R.string.autofill_offers_reminder_deep_link_text);
             NoUnderlineClickableSpan noUnderlineClickableSpan = new NoUnderlineClickableSpan(
-                    getContext().getResources(),
+                    getContext(),
                     (view)
                             -> AutofillOfferNotificationInfoBarJni.get().onOfferDeepLinkClicked(
                                     mNativeAutofillOfferNotificationInfoBar,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillVirtualCardEnrollmentInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillVirtualCardEnrollmentInfoBar.java
index 3c8bac36..a3ae494 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillVirtualCardEnrollmentInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillVirtualCardEnrollmentInfoBar.java
@@ -182,7 +182,7 @@
         if (!TextUtils.isEmpty(mDescriptionText) && !TextUtils.isEmpty(mLearnMoreLinkText)) {
             SpannableString text = new SpannableString(mDescriptionText);
             int offset = mDescriptionText.length() - mLearnMoreLinkText.length();
-            text.setSpan(new NoUnderlineClickableSpan(layout.getResources(), (unused) -> {
+            text.setSpan(new NoUnderlineClickableSpan(layout.getContext(), (unused) -> {
                 AutofillVirtualCardEnrollmentInfoBarJni.get().onInfobarLinkClicked(
                         mNativeAutofillVirtualCardEnrollmentInfoBar,
                         AutofillVirtualCardEnrollmentInfoBar.this,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
index 3449820b..6a736fe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
@@ -52,7 +52,7 @@
         InfoBarControlLayout detailsMessageLayout = layout.addControlLayout();
         SpannableString detailsMessageWithLink = new SpannableString(mDetailsMessage);
         detailsMessageWithLink.setSpan(
-                new NoUnderlineClickableSpan(layout.getResources(), (view) -> onLinkClicked()),
+                new NoUnderlineClickableSpan(layout.getContext(), (view) -> onLinkClicked()),
                 mInlineLinkRangeStart, mInlineLinkRangeEnd, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
         detailsMessageLayout.addDescription(detailsMessageWithLink);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java
index 9d2048c..f9d62efe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/PermissionInfoBar.java
@@ -133,9 +133,8 @@
         SpannableStringBuilder descriptionMessage = new SpannableStringBuilder(mDescription);
         if (mLearnMoreLinkText != null && !mLearnMoreLinkText.isEmpty()) {
             SpannableString link = new SpannableString(mLearnMoreLinkText);
-            link.setSpan(
-                    new NoUnderlineClickableSpan(layout.getResources(), view -> onLinkClicked()), 0,
-                    link.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+            link.setSpan(new NoUnderlineClickableSpan(layout.getContext(), view -> onLinkClicked()),
+                    0, link.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
             descriptionMessage.append(" ").append(link);
         }
         layout.getMessageLayout().addDescription(descriptionMessage);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SafetyTipInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SafetyTipInfoBar.java
index 32c2f883..0a396f0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SafetyTipInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SafetyTipInfoBar.java
@@ -61,9 +61,8 @@
         SpannableStringBuilder descriptionMessage = new SpannableStringBuilder(mDescription);
         if (mLearnMoreLinkText != null && !mLearnMoreLinkText.isEmpty()) {
             SpannableString link = new SpannableString(mLearnMoreLinkText);
-            link.setSpan(
-                    new NoUnderlineClickableSpan(layout.getResources(), view -> onLinkClicked()), 0,
-                    link.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+            link.setSpan(new NoUnderlineClickableSpan(layout.getContext(), view -> onLinkClicked()),
+                    0, link.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
             descriptionMessage.append(" ").append(link);
         }
         layout.getMessageLayout().addDescription(descriptionMessage);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
index fcde867..4ecc8eb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
@@ -93,7 +93,7 @@
             }
         });
 
-        mClickableSpan = new NoUnderlineClickableSpan(layout.getResources(), (widget) -> {
+        mClickableSpan = new NoUnderlineClickableSpan(layout.getContext(), (widget) -> {
             // Prevent double clicking on the text span.
             if (mClicked) return;
             showSurvey();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LegacyIncognitoDescriptionView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LegacyIncognitoDescriptionView.java
index 323f386..e414841 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LegacyIncognitoDescriptionView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LegacyIncognitoDescriptionView.java
@@ -310,7 +310,7 @@
         SpannableString textWithLearnMoreLink = new SpannableString(concatenatedText.toString());
 
         NoUnderlineClickableSpan span = new NoUnderlineClickableSpan(
-                getResources(), R.color.modern_blue_300, (view) -> mLearnMore.callOnClick());
+                getContext(), R.color.modern_blue_300, (view) -> mLearnMore.callOnClick());
         textWithLearnMoreLink.setSpan(
                 span, subtitleText.length() + 1, textWithLearnMoreLink.length(), 0 /* flags */);
         mSubtitle.setText(textWithLearnMoreLink);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RevampedIncognitoDescriptionView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RevampedIncognitoDescriptionView.java
index 92f04af2d..0cd2cfd7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RevampedIncognitoDescriptionView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RevampedIncognitoDescriptionView.java
@@ -257,7 +257,7 @@
 
         // Make the text between the <a> tags to be clickable, blue, without underline.
         SpanApplier.SpanInfo spanInfo = new SpanApplier.SpanInfo("<a>", "</a>",
-                new NoUnderlineClickableSpan(getResources(), R.color.default_text_color_link_light,
+                new NoUnderlineClickableSpan(getContext(), R.color.default_text_color_link_light,
                         onClickListener::onClick));
 
         SpannableString formattedText = SpanApplier.applySpans(text, spanInfo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/AboutThisSiteView.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/AboutThisSiteView.java
index b35ac59..fc50888 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/AboutThisSiteView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/AboutThisSiteView.java
@@ -59,8 +59,8 @@
         mDescriptionView.setText(description.getDescription());
 
         String link = LINK_START + description.getSource().getLabel() + LINK_END;
-        final ClickableSpan linkSpan = new NoUnderlineClickableSpan(
-                getContext().getResources(), (view) -> { onSourceClicked.run(); });
+        final ClickableSpan linkSpan =
+                new NoUnderlineClickableSpan(getContext(), (view) -> { onSourceClicked.run(); });
         String sourceString = getContext().getResources().getString(
                 R.string.page_info_about_this_site_subpage_from_label, link);
         mSourceView.setText(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
index 0eee9c3..ad1bc563f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -1145,7 +1145,7 @@
         }
 
         NoUnderlineClickableSpan settingsSpan = new NoUnderlineClickableSpan(
-                mContext.getResources(), (widget) -> mClient.onCardAndAddressSettingsClicked());
+                mContext, (widget) -> mClient.onCardAndAddressSettingsClicked());
         SpannableString spannableMessage = SpanApplier.applySpans(
                 message, new SpanInfo("BEGIN_LINK", "END_LINK", settingsSpan));
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/NotificationBlockedDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/NotificationBlockedDialog.java
index 4ee506f..f0aa34b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/NotificationBlockedDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/NotificationBlockedDialog.java
@@ -66,7 +66,7 @@
             fullString.append(" ");
             int start = fullString.length();
             fullString.append(learnMoreText);
-            fullString.setSpan(new NoUnderlineClickableSpan(mContext.getResources(), (v) -> {
+            fullString.setSpan(new NoUnderlineClickableSpan(mContext, (v) -> {
                 NotificationBlockedDialogJni.get().onLearnMoreClicked(mNativeDialogController);
             }), start, fullString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
index c0ae26c3..2c1b5678 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
@@ -146,7 +146,7 @@
 
     private SpannableString buildSyncAndServicesLink() {
         SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-        NoUnderlineClickableSpan servicesLink = new NoUnderlineClickableSpan(getResources(), v -> {
+        NoUnderlineClickableSpan servicesLink = new NoUnderlineClickableSpan(getContext(), v -> {
             settingsLauncher.launchSettingsActivity(getActivity(), GoogleServicesSettings.class);
         });
         if (IdentityServicesProvider.get()
@@ -159,7 +159,7 @@
                     new SpanApplier.SpanInfo("<link>", "</link>", servicesLink));
         }
         // Otherwise, show the string with both links to "Sync" and "Google Services".
-        NoUnderlineClickableSpan syncLink = new NoUnderlineClickableSpan(getResources(), v -> {
+        NoUnderlineClickableSpan syncLink = new NoUnderlineClickableSpan(getContext(), v -> {
             settingsLauncher.launchSettingsActivity(getActivity(), ManageSyncSettings.class,
                     ManageSyncSettings.createArguments(false));
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java
index 25c70998..3fa8cc1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SyncConsentFragmentBase.java
@@ -355,7 +355,7 @@
 
     private void updateSigninDetailsDescription(boolean addSettingsLink) {
         final @Nullable Object settingsLinkSpan = addSettingsLink
-                ? new NoUnderlineClickableSpan(getResources(), this::onSettingsLinkClicked)
+                ? new NoUnderlineClickableSpan(getContext(), this::onSettingsLinkClicked)
                 : null;
         final SpanApplier.SpanInfo spanInfo =
                 new SpanApplier.SpanInfo(SETTINGS_LINK_OPEN, SETTINGS_LINK_CLOSE, settingsLinkSpan);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java
index 5b5aaaec..a13091a4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java
@@ -6,12 +6,14 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.view.Display;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.chrome.R;
@@ -33,7 +35,10 @@
  */
 public class TabUtils {
     private static final String REQUEST_DESKTOP_SCREEN_WIDTH_PARAM = "screen_width_dp";
-
+    @VisibleForTesting
+    static final float TABLET_LANDSCAPE_TAB_THUMBNAIL_ASPECT_RATIO = 1.33f;
+    @VisibleForTesting
+    static final float TAB_THUMBNAIL_ASPECT_RATIO = 0.85f;
     // Do not instantiate this class.
     private TabUtils() {}
 
@@ -157,4 +162,19 @@
                        profile, ContentSettingsType.REQUEST_DESKTOP_SITE, url, url)
                 == ContentSettingValues.ALLOW;
     }
+
+    /**
+     * Return tab thumbnail aspect ratio for grid view.
+     * @param context - to retrieve info on device and layout.
+     * @return aspect ratio.
+     */
+    public static float getTabThumbnailAspectRatio(Context context) {
+        if (context != null && DeviceFormFactor.isNonMultiDisplayContextOnTablet(context)
+                && context.getResources().getConfiguration().orientation
+                        == Configuration.ORIENTATION_LANDSCAPE) {
+            return TABLET_LANDSCAPE_TAB_THUMBNAIL_ASPECT_RATIO;
+        }
+
+        return TAB_THUMBNAIL_ASPECT_RATIO;
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
index 6db5145..140c312 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFakeServer.java
@@ -270,7 +270,11 @@
             mDidStartResolution = false;
             mDidFinishResolution = false;
 
-            mTestHost.triggerResolve(getNodeId());
+            if (mPolicy.shouldPreviousGestureResolve()) {
+                mTestHost.triggerResolve(getNodeId());
+            } else {
+                mTestHost.triggerNonResolve(getNodeId());
+            }
             mTestHost.waitForSelectionToBe(getSearchTerm());
 
             if (mPolicy.shouldPreviousGestureResolve()) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
index 756f0363..7ab79e1 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationBase.java
@@ -276,7 +276,6 @@
         @Override
         public Iterable<ParameterSet> getParameters() {
             return Arrays.asList(new ParameterSet().value(EnabledFeature.NONE).name("default"),
-                    new ParameterSet().value(EnabledFeature.LONGPRESS).name("enableLongpress"),
                     new ParameterSet()
                             .value(EnabledFeature.TRANSLATIONS)
                             .name("enableTranslations"));
@@ -293,8 +292,7 @@
     private static final int PANEL_INTERACTION_MAX_RETRIES = 3;
     private static final int PANEL_INTERACTION_RETRY_DELAY_MS = 200;
 
-    // TODO(donnd): get these from TemplateURL once the low-priority or Contextual Search API
-    // is fully supported.
+    // Search request URL paths and CGI parameters.
     private static final String LOW_PRIORITY_SEARCH_ENDPOINT = "/s?";
     private static final String NORMAL_PRIORITY_SEARCH_ENDPOINT = "/search?";
     private static final String LOW_PRIORITY_INVALID_SEARCH_ENDPOINT = "/s/invalid";
@@ -304,51 +302,34 @@
     // Feature maps that we use for parameterized tests.
     //--------------------------------------------------------------------------------------------
 
-    /**
-     * This represents the current fully-launched configuration.
-     */
-    protected static final ImmutableMap<String, Boolean> ENABLE_NONE =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
-    /**
-     * This represents the Longpress with LiteralTap configurations, a good launch candidate.
-     */
-    private static final ImmutableMap<String, Boolean> ENABLE_LONGPRESS =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
-    /**
-     * This represents the Translations addition to the Longpress with LiteralTap configuration.
-     */
+    /** This represents the current fully-launched configuration, with no other Features. */
+    protected static final ImmutableMap<String, Boolean> ENABLE_NONE = ImmutableMap.of();
+
+    /** This is the Translations Feature addition. */
     private static final ImmutableMap<String, Boolean> ENABLE_TRANSLATIONS =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
+            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
 
-    /**
-     * This is the privacy-neutral-engagement feature set.
-     */
+    /** This is the privacy-neutral-engagement feature set. */
     private static final ImmutableMap<String, Boolean> ENABLE_PRIVACY_NEUTRAL =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_DELAYED_INTELLIGENCE, true);
+            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true);
 
-    /**
-     * This is the privacy-neutral-engagement feature set that include Related Searches.
-     */
+    /** This is the privacy-neutral-engagement feature set, plus Related Searches. */
     private static final ImmutableMap<String, Boolean>
             ENABLE_PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES =
                     ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true,
-                            ChromeFeatureList.CONTEXTUAL_SEARCH_DELAYED_INTELLIGENCE, true,
                             ChromeFeatureList.RELATED_SEARCHES, true,
                             ChromeFeatureList.RELATED_SEARCHES_IN_BAR, true,
                             ChromeFeatureList.RELATED_SEARCHES_UI, true);
 
-    /**
-     * This is the contextual triggers feature set that alters tap selection.
-     * Currently with two Features but a third is in development and should be added soon.
-     */
+    /** This is the contextual triggers feature set that alters tap to show selection handles. */
     private static final ImmutableMap<String, Boolean> ENABLE_CONTEXTUAL_TRIGGERS =
+            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, true);
+
+    /**
+     * This is the contextual triggers feature set that alters tap to show handles and shows the
+     * context menu.
+     */
+    private static final ImmutableMap<String, Boolean> ENABLE_CONTEXTUAL_TRIGGERS_MENU =
             ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_HANDLES, true,
                     ChromeFeatureList.CONTEXTUAL_TRIGGERS_SELECTION_MENU, true);
 
@@ -382,17 +363,17 @@
     // State for an individual test.
     private FakeSlowResolveSearch mLatestSlowResolveSearch;
 
-    @IntDef({EnabledFeature.NONE, EnabledFeature.LONGPRESS, EnabledFeature.TRANSLATIONS,
-            EnabledFeature.PRIVACY_NEUTRAL, EnabledFeature.PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES,
-            EnabledFeature.CONTEXTUAL_TRIGGERS})
+    @IntDef({EnabledFeature.NONE, EnabledFeature.TRANSLATIONS, EnabledFeature.PRIVACY_NEUTRAL,
+            EnabledFeature.PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES,
+            EnabledFeature.CONTEXTUAL_TRIGGERS, EnabledFeature.CONTEXTUAL_TRIGGERS_MENU})
     @Retention(RetentionPolicy.SOURCE)
     @interface EnabledFeature {
         int NONE = 0;
-        int LONGPRESS = 1;
-        int TRANSLATIONS = 2;
-        int PRIVACY_NEUTRAL = 3;
-        int PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES = 4;
-        int CONTEXTUAL_TRIGGERS = 5;
+        int TRANSLATIONS = 1;
+        int PRIVACY_NEUTRAL = 2;
+        int PRIVACY_NEUTRAL_WITH_RELATED_SEARCHES = 3;
+        int CONTEXTUAL_TRIGGERS = 4;
+        int CONTEXTUAL_TRIGGERS_MENU = 5;
     }
 
     // Tracks whether a long-press triggering experiment is active.
@@ -463,9 +444,6 @@
             case EnabledFeature.NONE:
                 whichFeature = ENABLE_NONE;
                 break;
-            case EnabledFeature.LONGPRESS:
-                whichFeature = ENABLE_LONGPRESS;
-                break;
             case EnabledFeature.TRANSLATIONS:
                 whichFeature = ENABLE_TRANSLATIONS;
                 break;
@@ -478,6 +456,9 @@
             case EnabledFeature.CONTEXTUAL_TRIGGERS:
                 whichFeature = ENABLE_CONTEXTUAL_TRIGGERS;
                 break;
+            case EnabledFeature.CONTEXTUAL_TRIGGERS_MENU:
+                whichFeature = ENABLE_CONTEXTUAL_TRIGGERS_MENU;
+                break;
         }
         Assert.assertNotNull(
                 "Did you change test Features without setting the correct Map?", whichFeature);
@@ -509,24 +490,16 @@
     private class ContextualSearchInstrumentationTestHost implements ContextualSearchTestHost {
         @Override
         public void triggerNonResolve(String nodeId) throws TimeoutException {
-            if (mPolicy.isLiteralSearchTapEnabled()) {
-                clickWordNode(nodeId);
-            } else if (!mPolicy.canResolveLongpress()) {
-                longPressNode(nodeId);
-            } else {
-                Assert.fail(
-                        "Cannot trigger a non-resolving gesture with literal tap or non-resolve!");
-            }
+            boolean previousOptedInState = mPolicy.overrideDecidedStateForTesting(false);
+            clickWordNode(nodeId);
+            mPolicy.overrideDecidedStateForTesting(previousOptedInState);
         }
 
         @Override
         public void triggerResolve(String nodeId) throws TimeoutException {
-            if (mPolicy.canResolveLongpress()) {
-                longPressNode(nodeId);
-            } else {
-                // When tap can trigger a resolve, we use a tap (aka click).
-                clickWordNode(nodeId);
-            }
+            boolean previousOptedInState = mPolicy.overrideDecidedStateForTesting(true);
+            clickWordNode(nodeId);
+            mPolicy.overrideDecidedStateForTesting(previousOptedInState);
         }
 
         @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationTest.java
index aa6cfb0..a8d06162 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInstrumentationTest.java
@@ -49,7 +49,6 @@
         @Override
         public Iterable<ParameterSet> getParameters() {
             return Arrays.asList(new ParameterSet().value(EnabledFeature.NONE).name("default"),
-                    new ParameterSet().value(EnabledFeature.LONGPRESS).name("enableLongpress"),
                     new ParameterSet()
                             .value(EnabledFeature.TRANSLATIONS)
                             .name("enableTranslations"),
@@ -57,6 +56,9 @@
                             .value(EnabledFeature.CONTEXTUAL_TRIGGERS)
                             .name("enableContextualTriggers"),
                     new ParameterSet()
+                            .value(EnabledFeature.CONTEXTUAL_TRIGGERS_MENU)
+                            .name("enableContextualTriggersMenu"),
+                    new ParameterSet()
                             .value(EnabledFeature.PRIVACY_NEUTRAL)
                             .name("enablePrivacyNeutralEngagement"),
                     new ParameterSet()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 7a22f1b7..7434c58 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -19,6 +19,7 @@
 import android.content.SharedPreferences;
 import android.graphics.Point;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
 import android.text.TextUtils;
@@ -198,36 +199,20 @@
      */
 
     /** This represents the current fully-launched configuration. */
-    private static final ImmutableMap<String, Boolean> ENABLE_NONE =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, false);
+    private static final ImmutableMap<String, Boolean> ENABLE_NONE = ImmutableMap.of();
+
     /**
      * This represents the Translations addition to the Longpress with LiteralTap configuration.
      * This is likely the best launch candidate.
      */
     private static final ImmutableMap<String, Boolean> ENABLE_TRANSLATIONS =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_LONGPRESS_RESOLVE, false,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_LITERAL_SEARCH_TAP, true,
-                    ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
+            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_TRANSLATIONS, true);
 
     /** Feature maps that we use for individual tests. */
-    private static final ImmutableMap<String, Boolean> ENABLE_RELATED_SEARCHES = ImmutableMap.of(
-            ChromeFeatureList.RELATED_SEARCHES, true, ChromeFeatureList.RELATED_SEARCHES_UI, false);
-    private static final ImmutableMap<String, Boolean> ENABLE_RELATED_SEARCHES_UI = ImmutableMap.of(
-            ChromeFeatureList.RELATED_SEARCHES, true, ChromeFeatureList.RELATED_SEARCHES_UI, true);
     private static final ImmutableMap<String, Boolean> ENABLE_RELATED_SEARCHES_IN_BAR =
             ImmutableMap.of(ChromeFeatureList.RELATED_SEARCHES, true,
                     ChromeFeatureList.RELATED_SEARCHES_UI, true,
                     ChromeFeatureList.RELATED_SEARCHES_IN_BAR, true);
-    private static final ImmutableMap<String, Boolean> ENABLE_RELATED_SEARCHES_IN_PANEL =
-            ImmutableMap.of(ChromeFeatureList.RELATED_SEARCHES, true,
-                    ChromeFeatureList.RELATED_SEARCHES_UI, true,
-                    ChromeFeatureList.RELATED_SEARCHES_ALTERNATE_UX, true);
-    private static final ImmutableMap<String, Boolean> DISABLE_FORCE_CAPTION =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, false);
-    private static final ImmutableMap<String, Boolean> ENABLE_FORCE_CAPTION =
-            ImmutableMap.of(ChromeFeatureList.CONTEXTUAL_SEARCH_FORCE_CAPTION, true);
 
     private ActivityMonitor mActivityMonitor;
     private ContextualSearchFakeServer mFakeServer;
@@ -339,25 +324,16 @@
     private class ContextualSearchManagerTestHost implements ContextualSearchTestHost {
         @Override
         public void triggerNonResolve(String nodeId) throws TimeoutException {
-            // TODO(donnd): remove support for the LiteralSearchTap Feature.
-            if (mPolicy.isLiteralSearchTapEnabled()) {
-                clickWordNode(nodeId);
-            } else if (!mPolicy.canResolveLongpress()) {
-                longPressNode(nodeId);
-            } else {
-                Assert.fail(
-                        "Cannot trigger a non-resolving gesture with literal tap or non-resolve!");
-            }
+            boolean wasOptedIn = mPolicy.overrideDecidedStateForTesting(false);
+            clickWordNode(nodeId);
+            mPolicy.overrideDecidedStateForTesting(wasOptedIn);
         }
 
         @Override
         public void triggerResolve(String nodeId) throws TimeoutException {
-            if (mPolicy.canResolveLongpress()) {
-                longPressNode(nodeId);
-            } else {
-                // When tap can trigger a resolve, we use a tap (aka click).
-                clickWordNode(nodeId);
-            }
+            boolean wasOptedIn = mPolicy.overrideDecidedStateForTesting(true);
+            clickWordNode(nodeId);
+            mPolicy.overrideDecidedStateForTesting(wasOptedIn);
         }
 
         @Override
@@ -850,11 +826,7 @@
      * @param nodeId A string containing the node ID.
      */
     public void triggerNode(Tab tab, String nodeId) throws TimeoutException {
-        if (mPolicy.canResolveLongpress()) {
-            DOMUtils.longPressNode(tab.getWebContents(), nodeId);
-        } else {
-            DOMUtils.clickNode(tab.getWebContents(), nodeId);
-        }
+        DOMUtils.clickNode(tab.getWebContents(), nodeId);
     }
 
     /**
@@ -2123,11 +2095,11 @@
         final NavigationHandle navigationHandle =
                 new NavigationHandle(0 /* nativeNavigationHandleProxy*/,
                         new GURL("intent://test/#Intent;scheme=test;package=com.chrome.test;end"),
-                        GURL.emptyGURL() /* referrerUrl */, null /* baseUrlForDataUrl */,
-                        true /* isInPrimaryMainFrame */, false /* isSameDocument*/,
-                        true /* isRendererInitiated */, null /* initiatorOrigin */,
-                        null /* impressionData */, PageTransition.LINK, false /* isPost */,
-                        true /* hasUserGesture */, false /* isRedirect */,
+                        GURL.emptyGURL() /* referrerUrl */,
+                        GURL.emptyGURL() /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
+                        false /* isSameDocument*/, true /* isRendererInitiated */,
+                        null /* initiatorOrigin */, null /* impressionData */, PageTransition.LINK,
+                        false /* isPost */, true /* hasUserGesture */, false /* isRedirect */,
                         true /* isExternalProtocol */, 0 /* navigationId */);
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -2162,7 +2134,7 @@
         GURL initialUrl = new GURL("http://test.com");
         final NavigationHandle initialNavigationHandle = new NavigationHandle(
                 0 /* nativeNavigationHandleProxy*/, initialUrl, GURL.emptyGURL() /* referrerUrl */,
-                null /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
+                GURL.emptyGURL() /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
                 false /* isSameDocument*/, true /* isRendererInitiated */,
                 null /* initiatorOrigin */, null /* impressionData */, PageTransition.LINK,
                 false /* isPost */, true /* hasUserGesture */, false /* isRedirect */,
@@ -2172,7 +2144,7 @@
                 new GURL("intent://test/#Intent;scheme=test;package=com.chrome.test;end");
         final NavigationHandle redirectedNavigationHandle = new NavigationHandle(
                 0 /* nativeNavigationHandleProxy*/, redirectUrl, GURL.emptyGURL() /* referrerUrl */,
-                null /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
+                GURL.emptyGURL() /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
                 false /* isSameDocument*/, true /* isRendererInitiated */,
                 null /* initiatorOrigin */, null /* impressionData */, PageTransition.LINK,
                 false /* isPost */, false /* hasUserGesture */, true /* isRedirect */,
@@ -2211,7 +2183,7 @@
         GURL url = new GURL("intent://test/#Intent;scheme=test;package=com.chrome.test;end");
         final NavigationHandle navigationHandle = new NavigationHandle(
                 0 /* nativeNavigationHandleProxy*/, url, GURL.emptyGURL() /* referrerUrl */,
-                null /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
+                GURL.emptyGURL() /* baseUrlForDataUrl */, true /* isInPrimaryMainFrame */,
                 false /* isSameDocument*/, true /* isRendererInitiated */,
                 null /* initiatorOrigin */, null /* impressionData */, PageTransition.LINK,
                 false /* isPost */, false /* hasUserGesture */, false /* isRedirect */,
@@ -2733,7 +2705,8 @@
         mManager.setContextualSearchInternalStateController(internalStateControllerWrapper);
 
         // Simulate a resolving search to show the Bar.
-        simulateResolveSearch("search");
+        longPressNode(SIMPLE_SEARCH_NODE_ID);
+        fakeAResponse();
 
         Assert.assertEquals("Some states were started but never finished",
                 internalStateControllerWrapper.getStartedStates(),
@@ -2755,7 +2728,10 @@
     @SmallTest
     @Feature({"ContextualSearch"})
     // Previously flaky and disabled 4/2021.  https://crbug.com/1192285
-    public void testAllInternalStatesVisitedNonResolveLongpress() throws Exception {
+    @DisabledTest(
+            message = "TODO(donnd): reenable after unifying resolving and non-resolving longpress.")
+    public void
+    testAllInternalStatesVisitedNonResolveLongpress() throws Exception {
         FeatureList.setTestFeatures(ENABLE_NONE);
 
         // Set up a tracking version of the Internal State Controller.
@@ -2823,6 +2799,7 @@
     @Feature({"ContextualSearch"})
     @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING)
     @MinAndroidSdkLevel(Build.VERSION_CODES.N)
+    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R, message = "crbug.com/1301017")
     @ParameterAnnotations.UseMethodParameter(FeatureParamProvider.class)
     public void testTabReparenting(@EnabledFeature int enabledFeature) throws Exception {
         // Move our "tap_test" tab to another activity.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserverTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserverTest.java
index e56edb9..a8133dc 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserverTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserverTest.java
@@ -51,7 +51,6 @@
         @Override
         public Iterable<ParameterSet> getParameters() {
             return Arrays.asList(new ParameterSet().value(EnabledFeature.NONE).name("default"),
-                    new ParameterSet().value(EnabledFeature.LONGPRESS).name("enableLongpress"),
                     new ParameterSet()
                             .value(EnabledFeature.TRANSLATIONS)
                             .name("enableTranslations"),
@@ -59,6 +58,9 @@
                             .value(EnabledFeature.CONTEXTUAL_TRIGGERS)
                             .name("enableContextualTriggers"),
                     new ParameterSet()
+                            .value(EnabledFeature.CONTEXTUAL_TRIGGERS_MENU)
+                            .name("enableContextualTriggersMenu"),
+                    new ParameterSet()
                             .value(EnabledFeature.PRIVACY_NEUTRAL)
                             .name("enablePrivacyNeutralEngagement"),
                     new ParameterSet()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java
index 90eda6c2..2de3642 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSystemTest.java
@@ -65,7 +65,6 @@
         @Override
         public Iterable<ParameterSet> getParameters() {
             return Arrays.asList(new ParameterSet().value(EnabledFeature.NONE).name("default"),
-                    new ParameterSet().value(EnabledFeature.LONGPRESS).name("enableLongpress"),
                     new ParameterSet()
                             .value(EnabledFeature.TRANSLATIONS)
                             .name("enableTranslations"),
@@ -73,6 +72,9 @@
                             .value(EnabledFeature.CONTEXTUAL_TRIGGERS)
                             .name("enableContextualTriggers"),
                     new ParameterSet()
+                            .value(EnabledFeature.CONTEXTUAL_TRIGGERS_MENU)
+                            .name("enableContextualTriggersMenu"),
+                    new ParameterSet()
                             .value(EnabledFeature.PRIVACY_NEUTRAL)
                             .name("enablePrivacyNeutralEngagement"),
                     new ParameterSet()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
index ec347dc0..bb22e78 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesTest.java
@@ -10,6 +10,9 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.endsWith;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.view.KeyEvent;
@@ -32,6 +35,7 @@
 
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
@@ -50,12 +54,14 @@
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils;
 import org.chromium.chrome.test.util.OmniboxTestUtils.SuggestionInfo;
-import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.components.omnibox.AutocompleteMatch.NavsuggestTile;
 import org.chromium.components.omnibox.AutocompleteMatchBuilder;
 import org.chromium.components.omnibox.AutocompleteResult;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.net.test.EmbeddedTestServer;
+import org.chromium.ui.modaldialog.ModalDialogManager;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.url.GURL;
 
 import java.util.Arrays;
@@ -75,6 +81,7 @@
     // Note: since we use the TestAutocompleteController, this could be any string.
     private static final String START_PAGE_LOCATION = "/echo/start.html";
     private static final String SEARCH_QUERY = "related search query";
+    private static final int MV_TILE_CAROUSEL_MATCH_POSITION = 1;
 
     @ClassRule
     public static final ChromeTabbedActivityTestRule sActivityTestRule =
@@ -171,6 +178,7 @@
         // Second suggestion is the MV Tiles.
         builder.setType(OmniboxSuggestionType.TILE_NAVSUGGEST);
         builder.setNavsuggestTiles(Arrays.asList(new NavsuggestTile[] {mTile1, mTile2, mTile3}));
+        builder.setDeletable(true);
         autocompleteResult.getSuggestionsList().add(builder.build());
         builder.reset();
 
@@ -210,9 +218,19 @@
         });
     }
 
+    private void longClickTileAtPosition(int position) {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            LayoutManager manager = mCarousel.view.getRecyclerViewForTest().getLayoutManager();
+            Assert.assertTrue(position < manager.getItemCount());
+            manager.scrollToPosition(position);
+            View view = manager.findViewByPosition(position);
+            Assert.assertNotNull(view);
+            view.performLongClick();
+        });
+    }
+
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void keyboardNavigation_highlightingNextTileUpdatesUrlBarText()
             throws InterruptedException {
         // Skip past the 'what-you-typed' suggestion.
@@ -233,7 +251,6 @@
 
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void keyboardNavigation_highlightingPreviousTileUpdatesUrlBarText()
             throws InterruptedException {
         // Skip past the 'what-you-typed' suggestion.
@@ -254,7 +271,6 @@
 
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void keyboardNavigation_highlightAlwaysStartsWithFirstElement()
             throws InterruptedException {
         // Skip past the 'what-you-typed' suggestion.
@@ -281,7 +297,6 @@
 
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void touchNavigation_clickOnFirstMVTile() throws Exception {
         clickTileAtPosition(0);
         ChromeTabUtils.waitForTabPageLoaded(mTab, mTile1.url.getSpec());
@@ -289,7 +304,6 @@
 
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void touchNavigation_clickOnMiddleMVTile() throws Exception {
         clickTileAtPosition(1);
         ChromeTabUtils.waitForTabPageLoaded(mTab, mTile2.url.getSpec());
@@ -297,9 +311,51 @@
 
     @Test
     @MediumTest
-    @EnableFeatures("OmniboxMostVisitedTiles")
     public void touchNavigation_clickOnLastMVTile() throws Exception {
         clickTileAtPosition(2);
         ChromeTabUtils.waitForTabPageLoaded(mTab, mTile3.url.getSpec());
     }
+
+    @Test
+    @MediumTest
+    public void touchNavigation_deleteMostVisitedTile() throws Exception {
+        final int tileToDelete = 2;
+        ModalDialogManager manager = mAutocomplete.getModalDialogManagerForTest();
+        longClickTileAtPosition(tileToDelete);
+
+        // Wait for the delete dialog to come up...
+        CriteriaHelper.pollUiThread(() -> {
+            PropertyModel deleteDialog = manager.getCurrentDialogForTest();
+            if (deleteDialog == null) return false;
+            deleteDialog.get(ModalDialogProperties.CONTROLLER)
+                    .onClick(deleteDialog, ModalDialogProperties.ButtonType.POSITIVE);
+            return true;
+        });
+
+        // ... and go away.
+        CriteriaHelper.pollUiThread(() -> { return manager.getCurrentDialogForTest() == null; });
+
+        verify(mController, times(1))
+                .deleteMatchElement(eq(MV_TILE_CAROUSEL_MATCH_POSITION), eq(tileToDelete));
+    }
+
+    @Test
+    @MediumTest
+    public void touchNavigation_dismissDeleteMostVisitedTile() throws Exception {
+        ModalDialogManager manager = mAutocomplete.getModalDialogManagerForTest();
+        longClickTileAtPosition(2);
+
+        // Wait for the delete dialog to come up...
+        CriteriaHelper.pollUiThread(() -> {
+            PropertyModel deleteDialog = manager.getCurrentDialogForTest();
+            if (deleteDialog == null) return false;
+            deleteDialog.get(ModalDialogProperties.CONTROLLER)
+                    .onClick(deleteDialog, ModalDialogProperties.ButtonType.NEGATIVE);
+            return true;
+        });
+
+        // ... and go away.
+        CriteriaHelper.pollUiThread(() -> { return manager.getCurrentDialogForTest() == null; });
+        verify(mController, never()).deleteMatchElement(anyInt(), anyInt());
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
index df89582..ba8899c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -11,6 +11,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.support.test.InstrumentationRegistry;
 import android.util.Pair;
 
@@ -786,6 +787,7 @@
      */
     @Test
     @SmallTest
+    @DisableIf.Build(message = "https://crbug.com/1300979", sdk_is_less_than = VERSION_CODES.N)
     @Feature({"Preferences"})
     public void testPopupsNotBlocked() {
         new TwoStatePermissionTestCase(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java
index 8b8701dc..4275e0b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java
@@ -12,7 +12,6 @@
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_VIEWER_NON_DAYDREAM;
 
 import android.graphics.PointF;
-import android.os.Build;
 import android.os.SystemClock;
 import android.view.MotionEvent;
 import android.view.View;
@@ -32,7 +31,7 @@
 import org.chromium.base.test.params.ParameterSet;
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisableIf;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.vr.rules.XrActivityRestriction;
@@ -93,14 +92,11 @@
      */
     @Test
     @MediumTest
-    @DisableIf
-            .Build(message = "Flaky on K/L crbug.com/762126",
-                    sdk_is_less_than = Build.VERSION_CODES.M)
-            @Restriction(RESTRICTION_TYPE_SVR)
-            @CommandLineFlags.Add({"enable-features=WebXR"})
-            @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
-            public void
-            testScreenTapsNotRegistered_WebXr() throws InterruptedException {
+    @DisabledTest(message = "https://crbug.com/1300966")
+    @Restriction(RESTRICTION_TYPE_SVR)
+    @CommandLineFlags.Add({"enable-features=WebXR"})
+    @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
+    public void testScreenTapsNotRegistered_WebXr() throws InterruptedException {
         screenTapsNotRegisteredImpl("webxr_test_screen_taps_not_registered", mWebXrVrTestFramework);
     }
 
@@ -133,6 +129,7 @@
      */
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1300966")
     @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE)
     @CommandLineFlags.Add({"enable-features=WebXR"})
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
@@ -392,6 +389,7 @@
      */
     @Test
     @MediumTest
+    @DisabledTest(message = "https://crbug.com/1300966")
     @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM_OR_STANDALONE)
     @CommandLineFlags.Add({"enable-features=WebXR"})
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java
index e625b82..48f3874 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java
@@ -246,10 +246,10 @@
      */
     @Test
     @MediumTest
-            @CommandLineFlags.Add({"enable-features=WebXR"})
-            @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
-            public void testWindowRafStopsFiringWhilePresenting_WebXr()
-            throws InterruptedException {
+    @DisabledTest(message = "https://crbug.com/1300966")
+    @CommandLineFlags.Add({"enable-features=WebXR"})
+    @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
+    public void testWindowRafStopsFiringWhilePresenting_WebXr() throws InterruptedException {
         windowRafStopsFiringWhilePresentingImpl(
 
                 "webxr_test_window_raf_stops_firing_during_immersive_session",
@@ -311,9 +311,10 @@
      */
     @Test
     @MediumTest
-            @CommandLineFlags.Add({"enable-features=WebXR"})
-            @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
-            public void testNonImmersiveStopsDuringImmersive() {
+    @DisabledTest(message = "https://crbug.com/1300966")
+    @CommandLineFlags.Add({"enable-features=WebXR"})
+    @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
+    public void testNonImmersiveStopsDuringImmersive() {
         mWebXrVrTestFramework.loadFileAndAwaitInitialization(
                 "test_non_immersive_stops_during_immersive", PAGE_LOAD_TIMEOUT_S);
         mWebXrVrTestFramework.executeStepAndWait("stepBeforeImmersive()");
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
index d15603d..2755592d 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/QualityEnforcerUnitTest.java
@@ -258,7 +258,7 @@
         when(mTab.getOriginalUrl()).thenReturn(url);
 
         NavigationHandle navigation = new NavigationHandle(0 /* navigationHandleProxy */, url,
-                null /* referrerUrl */, null /* baseUrlForDataUrl */,
+                GURL.emptyGURL() /* referrerUrl */, GURL.emptyGURL() /* baseUrlForDataUrl */,
                 true /* isInPrimaryMainFrame */, false /* isSameDocument */,
                 false /* isRendererInitiated */, null /* initiatorOrigin */,
                 null /* impressionData */, 0 /* pageTransition */, false /* isPost */,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifierTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifierTest.java
index 6d437df9..ff29b90f 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifierTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/controller/CurrentPageVerifierTest.java
@@ -185,7 +185,7 @@
         GURL gurl = createMockGurl(url);
         when(mTab.getUrl()).thenReturn(gurl);
         NavigationHandle navigation = new NavigationHandle(0 /* navigationHandleProxy */, gurl,
-                null /* referrerUrl */, null /* baseUrlForDataUrl */,
+                GURL.emptyGURL() /* referrerUrl */, GURL.emptyGURL() /* baseUrlForDataUrl */,
                 true /* isInPrimaryMainFrame */, false /* isSameDocument */,
                 false /* isRendererInitiated */, null /* initiatorOrigin */,
                 null /* impressionData */, 0 /* pageTransition */, false /* isPost */,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTestTabHolder.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTestTabHolder.java
index 071bfda..6b3f9427 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTestTabHolder.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTestTabHolder.java
@@ -125,7 +125,7 @@
         when(gurlOrigin.getSpec()).thenAnswer(invocation -> url);
 
         NavigationHandle navigation = new NavigationHandle(0 /* navigationHandleProxy */, gurl,
-                null /* referrerUrl */, null /* baseUrlForDataUrl */,
+                GURL.emptyGURL() /* referrerUrl */, GURL.emptyGURL() /* baseUrlForDataUrl */,
                 true /* isInPrimaryMainFrame */, isSameDocument, false /* isRendererInitiated */,
                 null /* initiatorOrigin */, null /* impressionData */, 0 /* pageTransition */,
                 false /* isPost */, false /* hasUserGesture */, false /* isRedirect */,
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index a9236e4e..1ca98a4d 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-100.0.4896.13_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-100.0.4896.14_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chrome_exe_main_mac.cc b/chrome/app/chrome_exe_main_mac.cc
index c7ea1a9..a4eb032 100644
--- a/chrome/app/chrome_exe_main_mac.cc
+++ b/chrome/app/chrome_exe_main_mac.cc
@@ -20,6 +20,8 @@
 #include <memory>
 
 #include "base/allocator/early_zone_registration_mac.h"
+#include "build/branding_buildflags.h"
+#include "build/build_config.h"
 #include "chrome/common/chrome_version.h"
 
 #if defined(HELPER_EXECUTABLE)
@@ -33,10 +35,99 @@
 // Crashpad directly.
 void abort_report_np(const char* fmt, ...);
 }
+
 namespace {
 
 typedef int (*ChromeMainPtr)(int, char**);
 
+#if !defined(HELPER_EXECUTABLE) && defined(OFFICIAL_BUILD) && \
+    BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(ARCH_CPU_X86_64)
+// This is for https://crbug.com/1300598, and more generally,
+// https://crbug.com/1297588 (and all of the associated bugs). It's horrible!
+//
+// When the main executable is updated on disk while the application is running,
+// and the offset of the Mach-O image at the main executable's path changes from
+// the offset that was determined when the executable was loaded, SecCode ceases
+// to be able to work with the executable. This may be triggered when the
+// product is updated on disk but the application has not yet relaunched. This
+// affects SecCodeCopySelf and SecCodeCopyGuestWithAttributes. Bugs are evident
+// even when validation (SecCodeCheckValidity) is not attempted.
+//
+// Practically, this is only a concern for fat (universal) files, because the
+// offset of a Mach-O image in a thin (single-architecture) file is always 0.
+// The branded product always ships a fat executable, and because some uses of
+// SecCode are in OS code beyond Chrome's control, an effort is made to freeze
+// the geometry of the branded (BUILDFLAG(GOOGLE_CHROME_BRANDING))
+// for-public-release (defined(OFFICIAL_BUILD)) main executable.
+//
+// The fat file is produced by installer/mac/universalizer.py. The x86_64 slice
+// always precedes the arm64 slice: lipo, as used by universalizer.py, always
+// places the arm64 slice last. See Xcode 12.0
+// https://github.com/apple-oss-distributions/cctools/blob/cctools-973.0.1/misc/lipo.c#L2672
+// cmp_qsort, used by create_fat at #L962. universalizer.py ensures that the
+// first slice in the file is located at a constant offset (16kB since
+// 98.0.4758.80), but if the first slice's size changes, it can affect the
+// offset of the second slice, the arm64 one, triggering SecCode-related bugs
+// for arm64 users across updates.
+//
+// As quite a hack of a workaround, the offset of the arm64 slice within the fat
+// main executable is influenced to land at the desired location by introducing
+// padding to the x86_64 slice that precedes it. The arm64 slice needs to remain
+// at offset 304kB (since 98.0.4758.80). The signed x86_64 slice has size 287296
+// bytes in 98.0.4758.80, but has shrunk since then, and before the introduction
+// of any padding, would now be 216784 bytes long. To make up the 70512-byte
+// difference, 68kB (69632 bytes) of padding is added to the x86_64 slice to
+// ensure that its size is stable, causing the arm64 slice to land where it
+// needs to be when universalized. This padding needs to be added to the thin
+// form of the x86_64 image before being fed to universalizer.py. Why 69632
+// bytes and not 70512? To keep it an even multiple of linker pages (not machine
+// pages: linker pages are 4kB for lld targeting x86_64 and 16kB for ld64
+// targeting x86_64, but Chrome uses lld). In any case, I'll make up almost all
+// of the 880-byte difference with one more weird trick below.
+//
+// There are several terrible ways to insert this padding into the x86_64 image.
+// Best would be something that considers the size of the x86_64 image without
+// padding, and inserts the precise amount required. It may be possible to do
+// this after linking, but the options that have been attempted so far were not
+// successful. So this quick and very dirty 68kB buffer is added to increase the
+// size of __TEXT,__const in a way that no tool could possibly see as suspicious
+// after link time. The variable is marked with the "used" attribute to prevent
+// the compiler from issuing warnings about the referenced variable, to prevent
+// the compiler from removing it under optimization, and to set the
+// S_ATTR_NO_DEAD_STRIP section attribute to prevent the linker from removing it
+// under -dead_strip. Note that the standardized [[maybe_unused]] attribute only
+// suppresses the warning, but does not prevent the compiler or linker from
+// removing it.
+//
+// The introduction of this fixed 68kB of padding causes the unsigned linker
+// output to grow by 68kB precisely, but the signed output will grow by slightly
+// more. This is because the code signature's code directory contains SHA-1 and
+// SHA-256 hashes of each 4kB code signing page (note, not machine pages or
+// linker pages) in the image, adding 20 and 32 bytes each (macOS 12.0.1
+// https://github.com/apple-oss-distributions/Security/blob/main/OSX/libsecurity_codesigning/lib/signer.cpp#L298
+// Security::CodeSigning::SecCodeSigner::Signer::prepare). For the 68kB
+// addition, the code signature grows by (68 / 4) * (20 + 32) = 884 bytes, thus
+// the total size of the linker output grows by 68kB + 884 = 70516 bytes. It is
+// not possible to control this any more granularly: if the buffer were sized at
+// 68kB - 884 = 68748 bytes, it would either cause no change in the space
+// allocated to the __TEXT segment (due to padding for alignment) or would cause
+// the segment to shrink by a linker page (note, not a code signing or machine
+// page) which would which would cause the linker output to shrink by the same
+// amount and would be absolutely undesirable. Luckily, the net growth of 70516
+// bytes is almost at the target of 70512 on the nose. In any event, having the
+// signed x86_64 slice sized at 287300 bytes instead of 287296 should not be a
+// problem. Subtle differences in characteristics including the code signature
+// itself can easily produce differences of that magnitude. It's necessary for
+// the size to wind up in the range (278528, 294912], and as long as that's met,
+// the 16kB alignment for the arm64 slice that follows it in the fat file will
+// cause it to appear at the desired 304kB.
+//
+// If the main executable has a significant change in size, this will need to be
+// revised. Hopefully a more elegant solution will become apparent before that's
+// required.
+__attribute__((used)) const char kGrossPaddingForCrbug1300598[68 * 1024] = {};
+#endif
+
 [[noreturn]] void FatalError(const char* format, ...) {
   va_list valist;
   va_start(valist, format);
diff --git a/chrome/app/chrome_exe_main_win.cc b/chrome/app/chrome_exe_main_win.cc
index 092ee21..225c2b7 100644
--- a/chrome/app/chrome_exe_main_win.cc
+++ b/chrome/app/chrome_exe_main_win.cc
@@ -5,6 +5,7 @@
 #include "chrome/app/chrome_exe_main_win.h"
 
 #include <windows.h>
+
 #include <malloc.h>
 #include <stddef.h>
 #include <tchar.h>
@@ -17,7 +18,6 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/containers/cxx20_erase.h"
-#include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
@@ -118,11 +118,11 @@
   const wchar_t kPrefetchArgumentPrefix[] = L"/prefetch:";
 
   for (const auto& arg : command_line.argv()) {
-    if (arg.size() == base::size(kPrefetchArgumentPrefix) &&
+    if (arg.size() == std::size(kPrefetchArgumentPrefix) &&
         base::StartsWith(arg, kPrefetchArgumentPrefix,
                          base::CompareCase::SENSITIVE)) {
-      return arg[base::size(kPrefetchArgumentPrefix) - 1] >= L'1' &&
-             arg[base::size(kPrefetchArgumentPrefix) - 1] <= L'8';
+      return arg[std::size(kPrefetchArgumentPrefix) - 1] >= L'1' &&
+             arg[std::size(kPrefetchArgumentPrefix) - 1] <= L'8';
     }
   }
   return false;
@@ -176,7 +176,7 @@
   // Retrieve the product & version details we need to report the crash
   // correctly.
   wchar_t exe_file[MAX_PATH] = {};
-  CHECK(::GetModuleFileName(nullptr, exe_file, base::size(exe_file)));
+  CHECK(::GetModuleFileName(nullptr, exe_file, std::size(exe_file)));
 
   std::wstring product_name, version, channel_name, special_build;
   install_static::GetExecutableVersionDetails(exe_file, &product_name, &version,
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 7c710c51..97dca8cc 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -5,6 +5,7 @@
 #include "chrome/app/chrome_main_delegate.h"
 
 #include <stddef.h>
+
 #include <string>
 
 #include "base/base_paths.h"
@@ -12,7 +13,6 @@
 #include "base/command_line.h"
 #include "base/cpu.h"
 #include "base/cpu_reduction_experiment.h"
-#include "base/cxx17_backports.h"
 #include "base/dcheck_is_on.h"
 #include "base/files/file_path.h"
 #include "base/i18n/rtl.h"
@@ -213,7 +213,7 @@
     chrome::kChromeSearchScheme, content::kChromeDevToolsScheme,
     content::kChromeUIScheme, content::kChromeUIUntrustedScheme};
 const size_t ChromeMainDelegate::kNonWildcardDomainNonPortSchemesSize =
-    base::size(kNonWildcardDomainNonPortSchemes);
+    std::size(kNonWildcardDomainNonPortSchemes);
 
 namespace {
 
@@ -259,7 +259,7 @@
 
   // Record product, version, channel and special build strings.
   wchar_t exe_file[MAX_PATH] = {};
-  CHECK(::GetModuleFileName(nullptr, exe_file, base::size(exe_file)));
+  CHECK(::GetModuleFileName(nullptr, exe_file, std::size(exe_file)));
 
   std::wstring product_name, version_number, channel_name, special_build;
   install_static::GetExecutableVersionDetails(
@@ -397,9 +397,9 @@
   wchar_t user_data_dir_buf[MAX_PATH], invalid_user_data_dir_buf[MAX_PATH];
 
   // In tests this may return false, implying the user data dir should be unset.
-  if (GetUserDataDirectoryThunk(
-          user_data_dir_buf, base::size(user_data_dir_buf),
-          invalid_user_data_dir_buf, base::size(invalid_user_data_dir_buf))) {
+  if (GetUserDataDirectoryThunk(user_data_dir_buf, std::size(user_data_dir_buf),
+                                invalid_user_data_dir_buf,
+                                std::size(invalid_user_data_dir_buf))) {
     base::FilePath user_data_dir(user_data_dir_buf);
     if (invalid_user_data_dir_buf[0] != 0) {
       chrome::SetInvalidSpecifiedUserDataDir(
@@ -905,7 +905,7 @@
     base::CommandLine interim_command_line(command_line.GetProgram());
     const char* const kSwitchNames[] = {switches::kUserDataDir, };
     interim_command_line.CopySwitchesFrom(command_line, kSwitchNames,
-                                          base::size(kSwitchNames));
+                                          std::size(kSwitchNames));
     interim_command_line.AppendSwitch(switches::kDiagnostics);
     interim_command_line.AppendSwitch(switches::kDiagnosticsRecovery);
 
@@ -1245,7 +1245,7 @@
 #endif
   };
 
-  for (size_t i = 0; i < base::size(kMainFunctions); ++i) {
+  for (size_t i = 0; i < std::size(kMainFunctions); ++i) {
     if (process_type == kMainFunctions[i].name)
       return kMainFunctions[i].function(std::move(main_function_params));
   }
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index e389555..5b931cd3 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -317,8 +317,9 @@
           Chromium OS
         </message>
       </if>
-      <!-- Chrome enterprise logo won't be used in Chromium -->
-      <message name="IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT" desc="Alt text for the Chromium Enterprise logo image."/>
+      <message name="IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT" desc="Alt text for the Chromium Enterprise logo image." formatter_data="android_java">
+        Chromium Enterprise logo
+      </message>
       <if expr="is_win">
         <message name="IDS_SHORTCUT_NEW_WINDOW" desc="The text label of the New window shortcut context menu entry as of Windows 8">
           New window
diff --git a/chrome/app/chromium_strings_grd/IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT.png.sha1
new file mode 100644
index 0000000..205f37f
--- /dev/null
+++ b/chrome/app/chromium_strings_grd/IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT.png.sha1
@@ -0,0 +1 @@
+2dd6a90de0bfae209aac64da53318fc31c03b4e4
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 84cb9dd..c9be34e9 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9878,7 +9878,7 @@
                 Wrong index.
         </message>
         <message name="IDS_JAVASCRIPT_UNSUPPORTED_ERROR_APPLESCRIPT_MAC" desc="Error dialog title to be displayed when the user attempts to execute JavaScript via AppleScript. Mac-only.">
-          Executing JavaScript through AppleScript is turned off. To turn it on, from the menu bar, go to View > Developer > Allow JavaScript from Apple Events. For more information: https://support.google.com/chrome/?p=applescript
+          Executing JavaScript through AppleScript is turned off. To turn it on, from the menu bar, go to View &gt; Developer &gt; Allow JavaScript from Apple Events. For more information: https://support.google.com/chrome/?p=applescript
         </message>
       </if> <!-- is_macosx -->
 
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 33ff512..b2b3600 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -335,7 +335,7 @@
           </message>
         </if>
       </if>
-      <message name="IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT" desc="Alt text for the Chrome Enterprise logo image.">
+      <message name="IDS_PRODUCT_LOGO_ENTERPRISE_ALT_TEXT" desc="Alt text for the Chrome Enterprise logo image." formatter_data="android_java">
         Chrome Enterprise logo
       </message>
       <if expr="is_win">
diff --git a/chrome/app/nearby_share_strings.grdp b/chrome/app/nearby_share_strings.grdp
index af185a7..8fba23e 100644
--- a/chrome/app/nearby_share_strings.grdp
+++ b/chrome/app/nearby_share_strings.grdp
@@ -335,6 +335,15 @@
   <message name="IDS_NEARBY_NOTIFICATION_GO_VISIBLE_ACTION" desc="Text shown on the notification to enter High Visibility Mode. High visibility mode allows the user to be discovered by nearby devices that are trying to share.">
     Enable
   </message>
+  <message name="IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE" desc="Text shown as the title of a notification that reminds users of their visibility settings">
+    Review your settings
+  </message>
+  <message name="IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE" desc="Text shown as the message of a notification that reminds users of their visibility settings">
+    Nearby contacts can share with you. Click to change.
+  </message>
+  <message name="IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION" desc="Text shown on the notification to go to visibility setting page">
+    Settings
+  </message>
   <message name="IDS_NEARBY_NOTIFICATION_DISMISS_ACTION" desc="Text shown on the notification to close the notification.">
     Dismiss
   </message>
diff --git a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION.png.sha1 b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION.png.sha1
new file mode 100644
index 0000000..f6ccbc72
--- /dev/null
+++ b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION.png.sha1
@@ -0,0 +1 @@
+a080a6cf9b03ece5e68ee92f2208f9b8b49e0619
\ No newline at end of file
diff --git a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE.png.sha1 b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE.png.sha1
new file mode 100644
index 0000000..f6ccbc72
--- /dev/null
+++ b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE.png.sha1
@@ -0,0 +1 @@
+a080a6cf9b03ece5e68ee92f2208f9b8b49e0619
\ No newline at end of file
diff --git a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE.png.sha1 b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE.png.sha1
new file mode 100644
index 0000000..f6ccbc72
--- /dev/null
+++ b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE.png.sha1
@@ -0,0 +1 @@
+a080a6cf9b03ece5e68ee92f2208f9b8b49e0619
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index c3217a9..044eb9b 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -2863,6 +2863,9 @@
   <message name="IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED" desc="Settings > Internet > Network details: Text to show when a network configuration is controlled by the primary user.">
     Network configuration is controlled by <ph name="USER_EMAIL">$1<ex>joe@gmail.com</ex></ph>.
   </message>
+  <message name="IDS_SETTINGS_INTERNET_A11Y_MANAGED_BY_ADMINISTRATOR" desc="Settings > Internet > Network details: A11Y label for managed by administrator icon, indicating which network settings is being managed by an administrator">
+    <ph name="NETWORK_NAME">$1<ex>Google-A</ex></ph> is managed by your administrator
+  </message>
   <message name="IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED" desc="Settings > Internet > Network details: Advanced section label.">
     Advanced
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_A11Y_MANAGED_BY_ADMINISTRATOR.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_A11Y_MANAGED_BY_ADMINISTRATOR.png.sha1
new file mode 100644
index 0000000..8135e7ca
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_INTERNET_A11Y_MANAGED_BY_ADMINISTRATOR.png.sha1
@@ -0,0 +1 @@
+c358b370a2849ae918db329da492ac9e85158049
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ecd1ee3..d121a56 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -7592,12 +7592,15 @@
 }
 
 # Use a static library here because many test binaries depend on this but don't
-# require many files from it.This makes linking more efficient.
+# require many files from it. This makes linking more efficient.
 static_library("test_support") {
   testonly = true
 
   # Always include this via the main test support target.
-  visibility = [ "//chrome/test:test_support" ]
+  visibility = [
+    "//chrome/browser/extensions:test_support",
+    "//chrome/test:test_support",
+  ]
 
   sources = [
     "autofill/mock_autofill_popup_controller.cc",
@@ -7852,52 +7855,18 @@
 
   if (enable_extensions) {
     sources += [
-      "extensions/chrome_extension_test_notification_observer.cc",
-      "extensions/chrome_extension_test_notification_observer.h",
-      "extensions/chrome_test_extension_loader.cc",
-      "extensions/chrome_test_extension_loader.h",
-      "extensions/extension_action_test_util.cc",
-      "extensions/extension_action_test_util.h",
-      "extensions/load_error_waiter.cc",
-      "extensions/load_error_waiter.h",
-      "extensions/mock_extension_special_storage_policy.cc",
-      "extensions/mock_extension_special_storage_policy.h",
-      "extensions/test_blocklist.cc",
-      "extensions/test_blocklist.h",
-      "extensions/test_blocklist_state_fetcher.cc",
-      "extensions/test_blocklist_state_fetcher.h",
-      "extensions/test_extension_message_bubble_delegate.cc",
-      "extensions/test_extension_message_bubble_delegate.h",
-      "extensions/test_extension_service.cc",
-      "extensions/test_extension_service.h",
-      "extensions/test_extension_system.cc",
-      "extensions/test_extension_system.h",
       "media_galleries/media_galleries_test_util.cc",
       "media_galleries/media_galleries_test_util.h",
     ]
     deps += [
       "//components/crx_file",
-      "//components/drive:test_support",
-      "//components/safe_browsing/core/browser/db:v4_test_util",
-      "//components/services/unzip:in_process",
-      "//components/storage_monitor:test_support",
-      "//components/value_store:test_support",
-      "//extensions:test_support",
       "//extensions/browser",
-      "//extensions/browser:test_support",
-      "//extensions/common:mojom",
-      "//google_apis:test_support",
-      "//services/data_decoder/public/cpp:test_support",
     ]
-    if (!is_fuchsia) {
-      # Native Messaging is not available under Fuchsia.
-      sources += [
-        "extensions/api/messaging/native_messaging_test_util.cc",
-        "extensions/api/messaging/native_messaging_test_util.h",
-      ]
-    }
     if (is_chromeos_ash) {
-      deps += [ "//chrome/browser/chromeos" ]
+      deps += [
+        "//chrome/browser/chromeos",
+        "//extensions:test_support",
+      ]
     }
   }
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 0b2a8dd..1ae0f89b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -20,7 +20,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/i18n/base_i18n_switches.h"
 #include "base/memory/singleton.h"
@@ -400,9 +399,9 @@
 
 const FeatureEntry::FeatureVariation kElasticOverscrollVariations[] = {
     {"Pixel shader stretch", kElasticOverscrollFilterType,
-     base::size(kElasticOverscrollFilterType), nullptr},
+     std::size(kElasticOverscrollFilterType), nullptr},
     {"Transform stretch", kElasticOverscrollTransformType,
-     base::size(kElasticOverscrollTransformType), nullptr}};
+     std::size(kElasticOverscrollTransformType), nullptr}};
 
 const FeatureEntry::FeatureParam kCCTResizablePolicyParamUseAllowlist[] = {
     {"default_policy", "use-allowlist"}};
@@ -412,9 +411,9 @@
 const FeatureEntry::FeatureVariation
     kCCTResizableThirdPartiesDefaultPolicyVariations[] = {
         {"Use Allowlist", kCCTResizablePolicyParamUseAllowlist,
-         base::size(kCCTResizablePolicyParamUseAllowlist), nullptr},
+         std::size(kCCTResizablePolicyParamUseAllowlist), nullptr},
         {"Use Denylist", kCCTResizablePolicyParamUseDenylist,
-         base::size(kCCTResizablePolicyParamUseDenylist), nullptr}};
+         std::size(kCCTResizablePolicyParamUseDenylist), nullptr}};
 
 const FeatureEntry::Choice kReaderModeHeuristicsChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
@@ -450,7 +449,7 @@
 
 const FeatureEntry::FeatureVariation kReaderModeDiscoverabilityVariations[] = {
     {"available in settings", kReaderModeOfferInSettings,
-     base::size(kReaderModeOfferInSettings), nullptr}};
+     std::size(kReaderModeOfferInSettings), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_ANDROID)
@@ -464,13 +463,13 @@
     {"mode", "always-voice"}};
 const FeatureEntry::FeatureVariation kAdaptiveButtonInTopToolbarVariations[] = {
     {"Always None", kAdaptiveButton_AlwaysNone,
-     base::size(kAdaptiveButton_AlwaysNone), nullptr},
+     std::size(kAdaptiveButton_AlwaysNone), nullptr},
     {"Always New Tab", kAdaptiveButton_AlwaysNewTab,
-     base::size(kAdaptiveButton_AlwaysNewTab), nullptr},
+     std::size(kAdaptiveButton_AlwaysNewTab), nullptr},
     {"Always Share", kAdaptiveButton_AlwaysShare,
-     base::size(kAdaptiveButton_AlwaysShare), nullptr},
+     std::size(kAdaptiveButton_AlwaysShare), nullptr},
     {"Always Voice", kAdaptiveButton_AlwaysVoice,
-     base::size(kAdaptiveButton_AlwaysVoice), nullptr},
+     std::size(kAdaptiveButton_AlwaysVoice), nullptr},
 };
 
 const FeatureEntry::FeatureParam kAdaptiveButtonCustomization_NewTab[] = {
@@ -485,11 +484,11 @@
 const FeatureEntry::FeatureVariation
     kAdaptiveButtonInTopToolbarCustomizationVariations[] = {
         {"New Tab", kAdaptiveButtonCustomization_NewTab,
-         base::size(kAdaptiveButtonCustomization_NewTab), nullptr},
+         std::size(kAdaptiveButtonCustomization_NewTab), nullptr},
         {"Share", kAdaptiveButtonCustomization_Share,
-         base::size(kAdaptiveButtonCustomization_Share), nullptr},
+         std::size(kAdaptiveButtonCustomization_Share), nullptr},
         {"Voice", kAdaptiveButtonCustomization_Voice,
-         base::size(kAdaptiveButtonCustomization_Voice), nullptr},
+         std::size(kAdaptiveButtonCustomization_Voice), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -537,21 +536,21 @@
 
 const FeatureEntry::FeatureVariation kForceDarkVariations[] = {
     {"with simple HSL-based inversion", kForceDark_SimpleHsl,
-     base::size(kForceDark_SimpleHsl), nullptr},
+     std::size(kForceDark_SimpleHsl), nullptr},
     {"with simple CIELAB-based inversion", kForceDark_SimpleCielab,
-     base::size(kForceDark_SimpleCielab), nullptr},
+     std::size(kForceDark_SimpleCielab), nullptr},
     {"with simple RGB-based inversion", kForceDark_SimpleRgb,
-     base::size(kForceDark_SimpleRgb), nullptr},
+     std::size(kForceDark_SimpleRgb), nullptr},
     {"with selective image inversion", kForceDark_SelectiveImageInversion,
-     base::size(kForceDark_SelectiveImageInversion), nullptr},
+     std::size(kForceDark_SelectiveImageInversion), nullptr},
     {"with selective inversion of non-image elements",
      kForceDark_SelectiveElementInversion,
-     base::size(kForceDark_SelectiveElementInversion), nullptr},
+     std::size(kForceDark_SelectiveElementInversion), nullptr},
     {"with selective inversion of everything",
      kForceDark_SelectiveGeneralInversion,
-     base::size(kForceDark_SelectiveGeneralInversion), nullptr},
+     std::size(kForceDark_SelectiveGeneralInversion), nullptr},
     {"with increased text contrast", kForceDark_IncreaseTextContrast,
-     base::size(kForceDark_IncreaseTextContrast), nullptr}};
+     std::size(kForceDark_IncreaseTextContrast), nullptr}};
 #endif  // !BUILDFLAG(IS_CHROMEOS)
 
 const FeatureEntry::FeatureParam kMBIModeLegacy[] = {{"mode", "legacy"}};
@@ -561,11 +560,11 @@
     {"mode", "per_site_instance"}};
 
 const FeatureEntry::FeatureVariation kMBIModeVariations[] = {
-    {"legacy mode", kMBIModeLegacy, base::size(kMBIModeLegacy), nullptr},
+    {"legacy mode", kMBIModeLegacy, std::size(kMBIModeLegacy), nullptr},
     {"per render process host", kMBIModeEnabledPerRenderProcessHost,
-     base::size(kMBIModeEnabledPerRenderProcessHost), nullptr},
+     std::size(kMBIModeEnabledPerRenderProcessHost), nullptr},
     {"per site instance", kMBIModeEnabledPerSiteInstance,
-     base::size(kMBIModeEnabledPerSiteInstance), nullptr}};
+     std::size(kMBIModeEnabledPerSiteInstance), nullptr}};
 
 const FeatureEntry::FeatureParam kIntensiveWakeUpThrottlingAfter10Seconds[] = {
     {blink::features::kIntensiveWakeUpThrottling_GracePeriodSeconds_Name,
@@ -574,7 +573,7 @@
 const FeatureEntry::FeatureVariation kIntensiveWakeUpThrottlingVariations[] = {
     {"10 seconds after a tab is hidden (facilitates testing)",
      kIntensiveWakeUpThrottlingAfter10Seconds,
-     base::size(kIntensiveWakeUpThrottlingAfter10Seconds), nullptr},
+     std::size(kIntensiveWakeUpThrottlingAfter10Seconds), nullptr},
 };
 
 const FeatureEntry::FeatureParam kFencedFramesImplementationTypeShadowDOM[] = {
@@ -585,10 +584,10 @@
 const FeatureEntry::FeatureVariation
     kFencedFramesImplementationTypeVariations[] = {
         {"with ShadowDOM", kFencedFramesImplementationTypeShadowDOM,
-         base::size(kFencedFramesImplementationTypeShadowDOM), nullptr},
+         std::size(kFencedFramesImplementationTypeShadowDOM), nullptr},
         {"with multiple page architecture",
          kFencedFramesImplementationTypeMPArch,
-         base::size(kFencedFramesImplementationTypeMPArch), nullptr}};
+         std::size(kFencedFramesImplementationTypeMPArch), nullptr}};
 
 #if BUILDFLAG(IS_ANDROID)
 const FeatureEntry::FeatureParam kCloseTabSuggestionsStale_Immediate[] = {
@@ -615,17 +614,17 @@
 
 const FeatureEntry::FeatureVariation kCloseTabSuggestionsStaleVariations[] = {
     {"Close Immediate", kCloseTabSuggestionsStale_Immediate,
-     base::size(kCloseTabSuggestionsStale_Immediate), nullptr},
+     std::size(kCloseTabSuggestionsStale_Immediate), nullptr},
     {"Group+Close Immediate", kGroupAndCloseTabSuggestions_Immediate,
-     base::size(kGroupAndCloseTabSuggestions_Immediate), nullptr},
+     std::size(kGroupAndCloseTabSuggestions_Immediate), nullptr},
     {"4 hours", kCloseTabSuggestionsStale_4Hours,
-     base::size(kCloseTabSuggestionsStale_4Hours), nullptr},
+     std::size(kCloseTabSuggestionsStale_4Hours), nullptr},
     {"8 hours", kCloseTabSuggestionsStale_8Hours,
-     base::size(kCloseTabSuggestionsStale_8Hours), nullptr},
+     std::size(kCloseTabSuggestionsStale_8Hours), nullptr},
     {"7 days", kCloseTabSuggestionsStale_7Days,
-     base::size(kCloseTabSuggestionsStale_7Days), nullptr},
+     std::size(kCloseTabSuggestionsStale_7Days), nullptr},
     {"Time & Site Engagement", kCloseTabSuggestionsTimeSiteEngagement,
-     base::size(kCloseTabSuggestionsTimeSiteEngagement), nullptr},
+     std::size(kCloseTabSuggestionsTimeSiteEngagement), nullptr},
 };
 
 const FeatureEntry::FeatureParam kLongScreenshot_AutoscrollDragSlow[] = {
@@ -634,9 +633,9 @@
     {"autoscroll", "2"}};
 const FeatureEntry::FeatureVariation kLongScreenshotVariations[] = {
     {"Autoscroll Experiment 1", kLongScreenshot_AutoscrollDragSlow,
-     base::size(kLongScreenshot_AutoscrollDragSlow), nullptr},
+     std::size(kLongScreenshot_AutoscrollDragSlow), nullptr},
     {"Autoscroll Experiment 2", kLongScreenshot_AutoscrollDragQuick,
-     base::size(kLongScreenshot_AutoscrollDragQuick), nullptr}};
+     std::size(kLongScreenshot_AutoscrollDragQuick), nullptr}};
 
 const FeatureEntry::FeatureParam kShowSingleRowMVTiles[] = {
     {"most_visited_max_rows_normal_screen", "1"},
@@ -648,9 +647,9 @@
     {"small_screen_height_threshold_dp", "700"}};
 const FeatureEntry::FeatureVariation kQueryTilesVariations[] = {
     {"(show single row of MV tiles)", kShowSingleRowMVTiles,
-     base::size(kShowSingleRowMVTiles), nullptr},
+     std::size(kShowSingleRowMVTiles), nullptr},
     {"(show two rows of MV tiles)", kShowTwoRowsMVTiles,
-     base::size(kShowTwoRowsMVTiles), nullptr}};
+     std::size(kShowTwoRowsMVTiles), nullptr}};
 
 const FeatureEntry::FeatureParam kDangerousDownloadNoFilledNegativeButton = {
     "filled_negative_button", "false"};
@@ -859,7 +858,7 @@
 // Ensure that all effective connection types returned by Network Quality
 // Estimator (NQE) are also exposed via flags.
 static_assert(net::EFFECTIVE_CONNECTION_TYPE_LAST + 2 ==
-                  base::size(kForceEffectiveConnectionTypeChoices),
+                  std::size(kForceEffectiveConnectionTypeChoices),
               "ECT enum value is not handled.");
 static_assert(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN == 0,
               "ECT enum value is not handled.");
@@ -889,23 +888,23 @@
 const FeatureEntry::FeatureVariation
     kIsolatedPrerenderFeatureWithPrefetchLimit[] = {
         {"Unlimited Prefetches", kIsolatedPrerenderPrefetchLimitNone,
-         base::size(kIsolatedPrerenderPrefetchLimitNone), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitNone), nullptr},
         {"Zero Prefetches", kIsolatedPrerenderPrefetchLimitZero,
-         base::size(kIsolatedPrerenderPrefetchLimitZero), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitZero), nullptr},
         {"One Prefetch", kIsolatedPrerenderPrefetchLimitOne,
-         base::size(kIsolatedPrerenderPrefetchLimitOne), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitOne), nullptr},
         {"Two Prefetches", kIsolatedPrerenderPrefetchLimitTwo,
-         base::size(kIsolatedPrerenderPrefetchLimitTwo), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitTwo), nullptr},
         {"Three Prefetches", kIsolatedPrerenderPrefetchLimitThree,
-         base::size(kIsolatedPrerenderPrefetchLimitThree), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitThree), nullptr},
         {"Four Prefetches", kIsolatedPrerenderPrefetchLimitFour,
-         base::size(kIsolatedPrerenderPrefetchLimitFour), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitFour), nullptr},
         {"Five Prefetches", kIsolatedPrerenderPrefetchLimitFive,
-         base::size(kIsolatedPrerenderPrefetchLimitFive), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitFive), nullptr},
         {"Ten Prefetches", kIsolatedPrerenderPrefetchLimitTen,
-         base::size(kIsolatedPrerenderPrefetchLimitTen), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitTen), nullptr},
         {"Fifteen Prefetches", kIsolatedPrerenderPrefetchLimitFifteen,
-         base::size(kIsolatedPrerenderPrefetchLimitFifteen), nullptr},
+         std::size(kIsolatedPrerenderPrefetchLimitFifteen), nullptr},
 };
 
 const FeatureEntry::Choice kMemlogModeChoices[] = {
@@ -969,10 +968,10 @@
 const FeatureEntry::FeatureVariation kPageContentAnnotationsVariations[] = {
     {"All Annotations and Persistence on Content",
      kPageContentAnnotationsContentParams,
-     base::size(kPageContentAnnotationsContentParams), nullptr},
+     std::size(kPageContentAnnotationsContentParams), nullptr},
     {"All Annotations and Persistence on Title",
      kPageContentAnnotationsTitleParams,
-     base::size(kPageContentAnnotationsTitleParams), nullptr},
+     std::size(kPageContentAnnotationsTitleParams), nullptr},
 };
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
@@ -1006,14 +1005,14 @@
 
 const FeatureEntry::FeatureVariation kOmniboxDocumentProviderVariations[] = {
     {"server scores", kOmniboxDocumentProviderServerScoring,
-     base::size(kOmniboxDocumentProviderServerScoring), nullptr},
+     std::size(kOmniboxDocumentProviderServerScoring), nullptr},
     {"server scores capped by rank",
      kOmniboxDocumentProviderServerScoringCappedByRank,
-     base::size(kOmniboxDocumentProviderServerScoringCappedByRank), nullptr},
+     std::size(kOmniboxDocumentProviderServerScoringCappedByRank), nullptr},
     {"client scores", kOmniboxDocumentProviderClientScoring,
-     base::size(kOmniboxDocumentProviderClientScoring), nullptr},
+     std::size(kOmniboxDocumentProviderClientScoring), nullptr},
     {"server and client scores", kOmniboxDocumentProviderServerAndClientScoring,
-     base::size(kOmniboxDocumentProviderServerAndClientScoring), nullptr}};
+     std::size(kOmniboxDocumentProviderServerAndClientScoring), nullptr}};
 
 // 3 permutations of the 2 rich autocompletion params:
 // - Title AC: Autocompletes suggestions when the input matches the title.
@@ -1032,11 +1031,11 @@
 
 const FeatureEntry::FeatureVariation kOmniboxRichAutocompletionVariations[] = {
     {"Title AC", kOmniboxRichAutocompletionTitle,
-     base::size(kOmniboxRichAutocompletionTitle), nullptr},
+     std::size(kOmniboxRichAutocompletionTitle), nullptr},
     {"Non-Prefix AC", kOmniboxRichAutocompletionNonPrefix,
-     base::size(kOmniboxRichAutocompletionNonPrefix), nullptr},
+     std::size(kOmniboxRichAutocompletionNonPrefix), nullptr},
     {"Title AC & Non-Prefix AC", kOmniboxRichAutocompletionTitleNonPrefix,
-     base::size(kOmniboxRichAutocompletionTitleNonPrefix), nullptr}};
+     std::size(kOmniboxRichAutocompletionTitleNonPrefix), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxRichAutocompletionMinChar00[] = {
     {"RichAutocompletionAutocompleteTitlesMinChar", "0"},
@@ -1060,17 +1059,17 @@
 const FeatureEntry::FeatureVariation
     kOmniboxRichAutocompletionMinCharVariations[] = {
         {"Title 0 / Non Prefix 0", kOmniboxRichAutocompletionMinChar00,
-         base::size(kOmniboxRichAutocompletionMinChar00), nullptr},
+         std::size(kOmniboxRichAutocompletionMinChar00), nullptr},
         {"Title 0 / Non Prefix 3", kOmniboxRichAutocompletionMinChar03,
-         base::size(kOmniboxRichAutocompletionMinChar03), nullptr},
+         std::size(kOmniboxRichAutocompletionMinChar03), nullptr},
         {"Title 0 / Non Prefix 5", kOmniboxRichAutocompletionMinChar05,
-         base::size(kOmniboxRichAutocompletionMinChar05), nullptr},
+         std::size(kOmniboxRichAutocompletionMinChar05), nullptr},
         {"Title 3 / Non Prefix 3", kOmniboxRichAutocompletionMinChar33,
-         base::size(kOmniboxRichAutocompletionMinChar33), nullptr},
+         std::size(kOmniboxRichAutocompletionMinChar33), nullptr},
         {"Title 3 / Non Prefix 5", kOmniboxRichAutocompletionMinChar35,
-         base::size(kOmniboxRichAutocompletionMinChar35), nullptr},
+         std::size(kOmniboxRichAutocompletionMinChar35), nullptr},
         {"Title 5 / Non Prefix 5", kOmniboxRichAutocompletionMinChar55,
-         base::size(kOmniboxRichAutocompletionMinChar55), nullptr}};
+         std::size(kOmniboxRichAutocompletionMinChar55), nullptr}};
 
 const FeatureEntry::FeatureParam
     kOmniboxRichAutocompletionAdditionalTextHide[] = {
@@ -1080,7 +1079,7 @@
     kOmniboxRichAutocompletionShowAdditionalTextVariations[] = {
         {"Show Additional Text", {}, 0, nullptr},
         {"Hide Additional Text", kOmniboxRichAutocompletionAdditionalTextHide,
-         base::size(kOmniboxRichAutocompletionAdditionalTextHide), nullptr}};
+         std::size(kOmniboxRichAutocompletionAdditionalTextHide), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxRichAutocompletionTitlesUrls5[] = {
     {"RichAutocompletionSplitTitleCompletion", "true"},
@@ -1100,13 +1099,13 @@
 const FeatureEntry::FeatureVariation
     kOmniboxRichAutocompletionSplitVariations[] = {
         {"Titles & URLs, min char 5", kOmniboxRichAutocompletionTitlesUrls5,
-         base::size(kOmniboxRichAutocompletionTitlesUrls5), nullptr},
+         std::size(kOmniboxRichAutocompletionTitlesUrls5), nullptr},
         {"Titles & URLs, min char 3", kOmniboxRichAutocompletionTitlesUrls3,
-         base::size(kOmniboxRichAutocompletionTitlesUrls3), nullptr},
+         std::size(kOmniboxRichAutocompletionTitlesUrls3), nullptr},
         {"Titles, min char 5", kOmniboxRichAutocompletionTitles5,
-         base::size(kOmniboxRichAutocompletionTitles5), nullptr},
+         std::size(kOmniboxRichAutocompletionTitles5), nullptr},
         {"Titles, min char 3", kOmniboxRichAutocompletionTitles3,
-         base::size(kOmniboxRichAutocompletionTitles3), nullptr}};
+         std::size(kOmniboxRichAutocompletionTitles3), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxRichAutocompletionPreferUrls[] = {
     {"RichAutocompletionAutocompletePreferUrlsOverPrefixes", "true"}};
@@ -1115,7 +1114,7 @@
     kOmniboxRichAutocompletionPreferUrlsOverPrefixesVariations[] = {
         {"Prefer prefixes", {}, 0, nullptr},
         {"Prefer URLs", kOmniboxRichAutocompletionPreferUrls,
-         base::size(kOmniboxRichAutocompletionPreferUrls), nullptr}};
+         std::size(kOmniboxRichAutocompletionPreferUrls), nullptr}};
 
 // A limited number of combinations of the above variations that are most
 // promising.
@@ -1148,19 +1147,19 @@
     kOmniboxRichAutocompletionPromisingVariations[] = {
         {"Aggressive - Title, Non-Prefix, min 0/0",
          kOmniboxRichAutocompletionAggressive,
-         base::size(kOmniboxRichAutocompletionAggressive), nullptr},
+         std::size(kOmniboxRichAutocompletionAggressive), nullptr},
         {"Aggressive Moderate - Title, Non-Prefix, min 3/5",
          kOmniboxRichAutocompletionAggressiveModerate,
-         base::size(kOmniboxRichAutocompletionAggressiveModerate), nullptr},
+         std::size(kOmniboxRichAutocompletionAggressiveModerate), nullptr},
         {"Conservative Moderate - Title, Shortcut Non-Prefix, min 3/5",
          kOmniboxRichAutocompletionConservativeModerate,
-         base::size(kOmniboxRichAutocompletionConservativeModerate), nullptr},
+         std::size(kOmniboxRichAutocompletionConservativeModerate), nullptr},
         {"Conservative Moderate 2 - Shortcut Title, Shortcut Non-Prefix, min "
          "3/5",
          kOmniboxRichAutocompletionConservativeModerate2,
-         base::size(kOmniboxRichAutocompletionConservativeModerate2), nullptr},
+         std::size(kOmniboxRichAutocompletionConservativeModerate2), nullptr},
         {"Conservative - Title, min 3", kOmniboxRichAutocompletionConservative,
-         base::size(kOmniboxRichAutocompletionConservative), nullptr}};
+         std::size(kOmniboxRichAutocompletionConservative), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxBookmarkPathsReplaceTitle[] = {
     {"OmniboxBookmarkPathsUiReplaceTitle", "true"}};
@@ -1174,15 +1173,15 @@
 const FeatureEntry::FeatureVariation kOmniboxBookmarkPathsVariations[] = {
     {"Default UI (Title - URL)", {}, 0, nullptr},
     {"Replace title (Path/Title - URL)", kOmniboxBookmarkPathsReplaceTitle,
-     base::size(kOmniboxBookmarkPathsReplaceTitle), nullptr},
+     std::size(kOmniboxBookmarkPathsReplaceTitle), nullptr},
     {"Replace URL (Title - Path)", kOmniboxBookmarkPathsReplaceUrl,
-     base::size(kOmniboxBookmarkPathsReplaceUrl), nullptr},
+     std::size(kOmniboxBookmarkPathsReplaceUrl), nullptr},
     {"Append after title (Title : Path - URL)",
      kOmniboxBookmarkPathsAppendAfterTitle,
-     base::size(kOmniboxBookmarkPathsAppendAfterTitle), nullptr},
+     std::size(kOmniboxBookmarkPathsAppendAfterTitle), nullptr},
     {"Dynamic Replace URL (Title - Path|URL)",
      kOmniboxBookmarkPathsDynamicReplaceUrl,
-     base::size(kOmniboxBookmarkPathsDynamicReplaceUrl), nullptr}};
+     std::size(kOmniboxBookmarkPathsDynamicReplaceUrl), nullptr}};
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) ||
         // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
 
@@ -1219,27 +1218,22 @@
     {"MaxZeroSuggestMatches", "15"}};
 
 const FeatureEntry::FeatureVariation kMaxZeroSuggestMatchesVariations[] = {
-    {"5", kMaxZeroSuggestMatches5, base::size(kMaxZeroSuggestMatches5),
+    {"5", kMaxZeroSuggestMatches5, std::size(kMaxZeroSuggestMatches5), nullptr},
+    {"6", kMaxZeroSuggestMatches6, std::size(kMaxZeroSuggestMatches6), nullptr},
+    {"7", kMaxZeroSuggestMatches7, std::size(kMaxZeroSuggestMatches7), nullptr},
+    {"8", kMaxZeroSuggestMatches8, std::size(kMaxZeroSuggestMatches8), nullptr},
+    {"9", kMaxZeroSuggestMatches9, std::size(kMaxZeroSuggestMatches9), nullptr},
+    {"10", kMaxZeroSuggestMatches10, std::size(kMaxZeroSuggestMatches10),
      nullptr},
-    {"6", kMaxZeroSuggestMatches6, base::size(kMaxZeroSuggestMatches6),
+    {"11", kMaxZeroSuggestMatches11, std::size(kMaxZeroSuggestMatches11),
      nullptr},
-    {"7", kMaxZeroSuggestMatches7, base::size(kMaxZeroSuggestMatches7),
+    {"12", kMaxZeroSuggestMatches12, std::size(kMaxZeroSuggestMatches12),
      nullptr},
-    {"8", kMaxZeroSuggestMatches8, base::size(kMaxZeroSuggestMatches8),
+    {"13", kMaxZeroSuggestMatches13, std::size(kMaxZeroSuggestMatches13),
      nullptr},
-    {"9", kMaxZeroSuggestMatches9, base::size(kMaxZeroSuggestMatches9),
+    {"14", kMaxZeroSuggestMatches14, std::size(kMaxZeroSuggestMatches14),
      nullptr},
-    {"10", kMaxZeroSuggestMatches10, base::size(kMaxZeroSuggestMatches10),
-     nullptr},
-    {"11", kMaxZeroSuggestMatches11, base::size(kMaxZeroSuggestMatches11),
-     nullptr},
-    {"12", kMaxZeroSuggestMatches12, base::size(kMaxZeroSuggestMatches12),
-     nullptr},
-    {"13", kMaxZeroSuggestMatches13, base::size(kMaxZeroSuggestMatches13),
-     nullptr},
-    {"14", kMaxZeroSuggestMatches14, base::size(kMaxZeroSuggestMatches14),
-     nullptr},
-    {"15", kMaxZeroSuggestMatches15, base::size(kMaxZeroSuggestMatches15),
+    {"15", kMaxZeroSuggestMatches15, std::size(kMaxZeroSuggestMatches15),
      nullptr}};
 
 const FeatureEntry::FeatureVariation
@@ -1264,11 +1258,11 @@
 constexpr FeatureEntry::FeatureVariation
     kOmniboxZeroSuggestPrefetchingVariations[] = {
         {"15 seconds", kOmniboxZeroSuggestCacheDuration15Secs,
-         base::size(kOmniboxZeroSuggestCacheDuration15Secs), nullptr},
+         std::size(kOmniboxZeroSuggestCacheDuration15Secs), nullptr},
         {"30 seconds", kOmniboxZeroSuggestCacheDuration30Secs,
-         base::size(kOmniboxZeroSuggestCacheDuration30Secs), nullptr},
+         std::size(kOmniboxZeroSuggestCacheDuration30Secs), nullptr},
         {"60 seconds", kOmniboxZeroSuggestCacheDuration60Secs,
-         base::size(kOmniboxZeroSuggestCacheDuration60Secs), nullptr}};
+         std::size(kOmniboxZeroSuggestCacheDuration60Secs), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxUIMaxAutocompleteMatches3[] = {
     {OmniboxFieldTrial::kUIMaxAutocompleteMatchesParam, "3"}};
@@ -1292,23 +1286,23 @@
 const FeatureEntry::FeatureVariation
     kOmniboxUIMaxAutocompleteMatchesVariations[] = {
         {"3 matches", kOmniboxUIMaxAutocompleteMatches3,
-         base::size(kOmniboxUIMaxAutocompleteMatches3), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches3), nullptr},
         {"4 matches", kOmniboxUIMaxAutocompleteMatches4,
-         base::size(kOmniboxUIMaxAutocompleteMatches4), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches4), nullptr},
         {"5 matches", kOmniboxUIMaxAutocompleteMatches5,
-         base::size(kOmniboxUIMaxAutocompleteMatches5), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches5), nullptr},
         {"6 matches", kOmniboxUIMaxAutocompleteMatches6,
-         base::size(kOmniboxUIMaxAutocompleteMatches6), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches6), nullptr},
         {"7 matches", kOmniboxUIMaxAutocompleteMatches7,
-         base::size(kOmniboxUIMaxAutocompleteMatches7), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches7), nullptr},
         {"8 matches", kOmniboxUIMaxAutocompleteMatches8,
-         base::size(kOmniboxUIMaxAutocompleteMatches8), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches8), nullptr},
         {"9 matches", kOmniboxUIMaxAutocompleteMatches9,
-         base::size(kOmniboxUIMaxAutocompleteMatches9), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches9), nullptr},
         {"10 matches", kOmniboxUIMaxAutocompleteMatches10,
-         base::size(kOmniboxUIMaxAutocompleteMatches10), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches10), nullptr},
         {"12 matches", kOmniboxUIMaxAutocompleteMatches12,
-         base::size(kOmniboxUIMaxAutocompleteMatches12), nullptr}};
+         std::size(kOmniboxUIMaxAutocompleteMatches12), nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxMaxURLMatches2[] = {
     {OmniboxFieldTrial::kOmniboxMaxURLMatchesParam, "2"}};
@@ -1322,15 +1316,15 @@
     {OmniboxFieldTrial::kOmniboxMaxURLMatchesParam, "6"}};
 
 const FeatureEntry::FeatureVariation kOmniboxMaxURLMatchesVariations[] = {
-    {"2 matches", kOmniboxMaxURLMatches2, base::size(kOmniboxMaxURLMatches2),
+    {"2 matches", kOmniboxMaxURLMatches2, std::size(kOmniboxMaxURLMatches2),
      nullptr},
-    {"3 matches", kOmniboxMaxURLMatches3, base::size(kOmniboxMaxURLMatches3),
+    {"3 matches", kOmniboxMaxURLMatches3, std::size(kOmniboxMaxURLMatches3),
      nullptr},
-    {"4 matches", kOmniboxMaxURLMatches4, base::size(kOmniboxMaxURLMatches4),
+    {"4 matches", kOmniboxMaxURLMatches4, std::size(kOmniboxMaxURLMatches4),
      nullptr},
-    {"5 matches", kOmniboxMaxURLMatches5, base::size(kOmniboxMaxURLMatches5),
+    {"5 matches", kOmniboxMaxURLMatches5, std::size(kOmniboxMaxURLMatches5),
      nullptr},
-    {"6 matches", kOmniboxMaxURLMatches6, base::size(kOmniboxMaxURLMatches6),
+    {"6 matches", kOmniboxMaxURLMatches6, std::size(kOmniboxMaxURLMatches6),
      nullptr}};
 
 const FeatureEntry::FeatureParam kOmniboxDynamicMaxAutocomplete90[] = {
@@ -1355,17 +1349,17 @@
 const FeatureEntry::FeatureVariation
     kOmniboxDynamicMaxAutocompleteVariations[] = {
         {"9 suggestions if 0 or fewer URLs", kOmniboxDynamicMaxAutocomplete90,
-         base::size(kOmniboxDynamicMaxAutocomplete90), nullptr},
+         std::size(kOmniboxDynamicMaxAutocomplete90), nullptr},
         {"9 suggestions if 1 or fewer URLs", kOmniboxDynamicMaxAutocomplete91,
-         base::size(kOmniboxDynamicMaxAutocomplete91), nullptr},
+         std::size(kOmniboxDynamicMaxAutocomplete91), nullptr},
         {"9 suggestions if 2 or fewer URLs", kOmniboxDynamicMaxAutocomplete92,
-         base::size(kOmniboxDynamicMaxAutocomplete92), nullptr},
+         std::size(kOmniboxDynamicMaxAutocomplete92), nullptr},
         {"10 suggestions if 0 or fewer URLs", kOmniboxDynamicMaxAutocomplete100,
-         base::size(kOmniboxDynamicMaxAutocomplete100), nullptr},
+         std::size(kOmniboxDynamicMaxAutocomplete100), nullptr},
         {"10 suggestions if 1 or fewer URLs", kOmniboxDynamicMaxAutocomplete101,
-         base::size(kOmniboxDynamicMaxAutocomplete101), nullptr},
+         std::size(kOmniboxDynamicMaxAutocomplete101), nullptr},
         {"10 suggestions if 2 or fewer URLs", kOmniboxDynamicMaxAutocomplete102,
-         base::size(kOmniboxDynamicMaxAutocomplete102), nullptr}};
+         std::size(kOmniboxDynamicMaxAutocomplete102), nullptr}};
 
 const FeatureEntry::FeatureParam kMinimumTabWidthSettingPinned[] = {
     {features::kMinimumTabWidthFeatureParameterName, "54"}};
@@ -1378,13 +1372,13 @@
 
 const FeatureEntry::FeatureVariation kTabScrollingVariations[] = {
     {" - tabs shrink to pinned tab width", kMinimumTabWidthSettingPinned,
-     base::size(kMinimumTabWidthSettingPinned), nullptr},
+     std::size(kMinimumTabWidthSettingPinned), nullptr},
     {" - tabs shrink to a medium width", kMinimumTabWidthSettingMedium,
-     base::size(kMinimumTabWidthSettingMedium), nullptr},
+     std::size(kMinimumTabWidthSettingMedium), nullptr},
     {" - tabs shrink to a large width", kMinimumTabWidthSettingLarge,
-     base::size(kMinimumTabWidthSettingLarge), nullptr},
+     std::size(kMinimumTabWidthSettingLarge), nullptr},
     {" - tabs don't shrink", kMinimumTabWidthSettingFull,
-     base::size(kMinimumTabWidthSettingFull), nullptr}};
+     std::size(kMinimumTabWidthSettingFull), nullptr}};
 
 const FeatureEntry::FeatureParam kAlsoShowMediaTabsinOpenTabsSection[] = {
     {features::kTabSearchAlsoShowMediaTabsinOpenTabsSectionParameterName,
@@ -1393,7 +1387,7 @@
 const FeatureEntry::FeatureVariation kTabSearchMediaTabsVariations[] = {
     {" - media tabs also shown in open tabs",
      kAlsoShowMediaTabsinOpenTabsSection,
-     base::size(kAlsoShowMediaTabsinOpenTabsSection), nullptr}};
+     std::size(kAlsoShowMediaTabsinOpenTabsSection), nullptr}};
 
 const FeatureEntry::FeatureParam kTabSearchSearchThresholdSmall[] = {
     {features::kTabSearchSearchThresholdName, "0.3"}};
@@ -1404,18 +1398,18 @@
 
 const FeatureEntry::FeatureVariation kTabSearchSearchThresholdVariations[] = {
     {" - fuzzy level: small", kTabSearchSearchThresholdSmall,
-     base::size(kTabSearchSearchThresholdSmall), nullptr},
+     std::size(kTabSearchSearchThresholdSmall), nullptr},
     {" - fuzzy level: medium", kTabSearchSearchThresholdMedium,
-     base::size(kTabSearchSearchThresholdMedium), nullptr},
+     std::size(kTabSearchSearchThresholdMedium), nullptr},
     {" - fuzzy level: large", kTabSearchSearchThresholdLarge,
-     base::size(kTabSearchSearchThresholdLarge), nullptr}};
+     std::size(kTabSearchSearchThresholdLarge), nullptr}};
 
 const FeatureEntry::FeatureParam kTabHoverCardImagesAlternateFormat[] = {
     {features::kTabHoverCardAlternateFormat, "1"}};
 
 const FeatureEntry::FeatureVariation kTabHoverCardImagesVariations[] = {
     {" alternate hover card format", kTabHoverCardImagesAlternateFormat,
-     base::size(kTabHoverCardImagesAlternateFormat), nullptr}};
+     std::size(kTabHoverCardImagesAlternateFormat), nullptr}};
 
 #if !BUILDFLAG(IS_ANDROID)
 
@@ -1441,13 +1435,13 @@
     {ntp_features::kNtpChromeCartModuleCouponParam, "true"}};
 const FeatureEntry::FeatureVariation kNtpChromeCartModuleVariations[] = {
     {"- Fake Data And Discount", kNtpChromeCartModuleFakeData,
-     base::size(kNtpChromeCartModuleFakeData), nullptr},
+     std::size(kNtpChromeCartModuleFakeData), nullptr},
     {"- Abandoned Cart Discount", kNtpChromeCartModuleAbandonedCartDiscount,
-     base::size(kNtpChromeCartModuleAbandonedCartDiscount), nullptr},
+     std::size(kNtpChromeCartModuleAbandonedCartDiscount), nullptr},
     {"- Heuristics Improvement", kNtpChromeCartModuleHeuristicsImprovement,
-     base::size(kNtpChromeCartModuleHeuristicsImprovement), nullptr},
+     std::size(kNtpChromeCartModuleHeuristicsImprovement), nullptr},
     {"- RBD and Coupons", kNtpChromeCartModuleRBDAndCouponDiscount,
-     base::size(kNtpChromeCartModuleRBDAndCouponDiscount), nullptr},
+     std::size(kNtpChromeCartModuleRBDAndCouponDiscount), nullptr},
 };
 
 // The following are consent v2 variations in the Chrome Cart module.
@@ -1459,25 +1453,25 @@
     {ntp_features::kNtpChromeCartModuleDiscountConsentNtpVariationParam, "3"}};
 const FeatureEntry::FeatureVariation kDiscountConsentV2Variations[] = {
     {"Changing string", kDiscountConsentNtpStringChange,
-     base::size(kDiscountConsentNtpStringChange), nullptr},
+     std::size(kDiscountConsentNtpStringChange), nullptr},
     {"Inline Consent", kDiscountConsentNtpInline,
-     base::size(kDiscountConsentNtpInline), nullptr},
+     std::size(kDiscountConsentNtpInline), nullptr},
     {"Dialog Consent", kDiscountConsentNtpDialog,
-     base::size(kDiscountConsentNtpDialog), nullptr},
+     std::size(kDiscountConsentNtpDialog), nullptr},
 };
 
 const FeatureEntry::FeatureParam kNtpRecipeTasksModuleFakeData[] = {
     {ntp_features::kNtpRecipeTasksModuleDataParam, "fake"}};
 const FeatureEntry::FeatureVariation kNtpRecipeTasksModuleVariations[] = {
     {"- Fake Data", kNtpRecipeTasksModuleFakeData,
-     base::size(kNtpRecipeTasksModuleFakeData), nullptr},
+     std::size(kNtpRecipeTasksModuleFakeData), nullptr},
 };
 
 const FeatureEntry::FeatureParam kNtpShoppingTasksModuleFakeData[] = {
     {ntp_features::kNtpShoppingTasksModuleDataParam, "fake"}};
 const FeatureEntry::FeatureVariation kNtpShoppingTasksModuleVariations[] = {
     {"- Fake Data", kNtpShoppingTasksModuleFakeData,
-     base::size(kNtpShoppingTasksModuleFakeData), nullptr},
+     std::size(kNtpShoppingTasksModuleFakeData), nullptr},
 };
 
 const FeatureEntry::FeatureParam kNtpDriveModuleFakeData[] = {
@@ -1485,10 +1479,10 @@
 const FeatureEntry::FeatureParam kNtpDriveModuleManagedUsersOnly[] = {
     {ntp_features::kNtpDriveModuleManagedUsersOnlyParam, "true"}};
 const FeatureEntry::FeatureVariation kNtpDriveModuleVariations[] = {
-    {"- Fake Data", kNtpDriveModuleFakeData,
-     base::size(kNtpDriveModuleFakeData), nullptr},
+    {"- Fake Data", kNtpDriveModuleFakeData, std::size(kNtpDriveModuleFakeData),
+     nullptr},
     {"- Managed Users Only", kNtpDriveModuleManagedUsersOnly,
-     base::size(kNtpDriveModuleManagedUsersOnly), nullptr},
+     std::size(kNtpDriveModuleManagedUsersOnly), nullptr},
 };
 
 const FeatureEntry::FeatureParam kNtpPhotosModuleFakeData0[] = {
@@ -1504,15 +1498,15 @@
 
 const FeatureEntry::FeatureVariation kNtpPhotosModuleVariations[] = {
     {" - Fake memories: 0", kNtpPhotosModuleFakeData0,
-     base::size(kNtpPhotosModuleFakeData0), nullptr},
+     std::size(kNtpPhotosModuleFakeData0), nullptr},
     {" - Fake memories: 1", kNtpPhotosModuleFakeData1,
-     base::size(kNtpPhotosModuleFakeData1), nullptr},
+     std::size(kNtpPhotosModuleFakeData1), nullptr},
     {" - Fake memories: 2", kNtpPhotosModuleFakeData2,
-     base::size(kNtpPhotosModuleFakeData2), nullptr},
+     std::size(kNtpPhotosModuleFakeData2), nullptr},
     {" - Fake memories: 3", kNtpPhotosModuleFakeData3,
-     base::size(kNtpPhotosModuleFakeData3), nullptr},
+     std::size(kNtpPhotosModuleFakeData3), nullptr},
     {" - Fake memories: 4", kNtpPhotosModuleFakeData4,
-     base::size(kNtpPhotosModuleFakeData4), nullptr}};
+     std::size(kNtpPhotosModuleFakeData4), nullptr}};
 
 const FeatureEntry::FeatureParam kNtpPhotosModuleOptInRHTitle[] = {
     {ntp_features::kNtpPhotosModuleOptInTitleParam, "0"}};
@@ -1525,13 +1519,13 @@
 
 const FeatureEntry::FeatureVariation kNtpPhotosModuleOptInTitleVariations[] = {
     {" - Recent Highlights", kNtpPhotosModuleOptInRHTitle,
-     base::size(kNtpPhotosModuleOptInRHTitle), nullptr},
+     std::size(kNtpPhotosModuleOptInRHTitle), nullptr},
     {" - Favorite people", kNtpPhotosModuleOptInFavoriteTitle,
-     base::size(kNtpPhotosModuleOptInFavoriteTitle), nullptr},
+     std::size(kNtpPhotosModuleOptInFavoriteTitle), nullptr},
     {" - Personalized title", kNtpPhotosModuleOptInPersonalizedTitle,
-     base::size(kNtpPhotosModuleOptInPersonalizedTitle), nullptr},
+     std::size(kNtpPhotosModuleOptInPersonalizedTitle), nullptr},
     {" - Trips title", kNtpPhotosModuleOptInTripsTitle,
-     base::size(kNtpPhotosModuleOptInTripsTitle), nullptr}};
+     std::size(kNtpPhotosModuleOptInTripsTitle), nullptr}};
 
 const FeatureEntry::FeatureParam kNtpPhotosModuleLogo1ArtWork[] = {
     {ntp_features::kNtpPhotosModuleOptInArtWorkParam, "1"}};
@@ -1544,13 +1538,13 @@
 
 const FeatureEntry::FeatureVariation kNtpPhotosModuleOptInArtWorkVariations[] =
     {{" - Artwork with Logo - 1", kNtpPhotosModuleLogo1ArtWork,
-      base::size(kNtpPhotosModuleLogo1ArtWork), nullptr},
+      std::size(kNtpPhotosModuleLogo1ArtWork), nullptr},
      {" - Artwork with Logo - 2", kNtpPhotosModuleLogo2ArtWork,
-      base::size(kNtpPhotosModuleLogo2ArtWork), nullptr},
+      std::size(kNtpPhotosModuleLogo2ArtWork), nullptr},
      {" - Artwork with Illustrations", kNtpPhotosModuleIllustrationsArtWork,
-      base::size(kNtpPhotosModuleIllustrationsArtWork), nullptr},
+      std::size(kNtpPhotosModuleIllustrationsArtWork), nullptr},
      {" - Artwork with Stockpile", kNtpPhotosModuleStockpileArtWork,
-      base::size(kNtpPhotosModuleStockpileArtWork), nullptr}};
+      std::size(kNtpPhotosModuleStockpileArtWork), nullptr}};
 
 const FeatureEntry::FeatureParam kRealboxMatchOmniboxThemeVar1[] = {
     {ntp_features::kRealboxMatchOmniboxThemeVariantParam, "1"}};
@@ -1560,11 +1554,11 @@
 const FeatureEntry::FeatureVariation kRealboxMatchOmniboxThemeVariations[] = {
     {"(NTP background on steady state and Omnibox steady state background on "
      "hover)",
-     kRealboxMatchOmniboxThemeVar1, base::size(kRealboxMatchOmniboxThemeVar1),
+     kRealboxMatchOmniboxThemeVar1, std::size(kRealboxMatchOmniboxThemeVar1),
      nullptr},
     {"(NTP background on steady state and Omnibox active state background on "
      "hover)",
-     kRealboxMatchOmniboxThemeVar2, base::size(kRealboxMatchOmniboxThemeVar2),
+     kRealboxMatchOmniboxThemeVar2, std::size(kRealboxMatchOmniboxThemeVar2),
      nullptr}};
 
 const FeatureEntry::FeatureParam kRealboxMatchSearchboxThemeRoundedCorners[] = {
@@ -1572,14 +1566,14 @@
 
 const FeatureEntry::FeatureVariation kRealboxMatchSearchboxThemeVariations[] = {
     {"(Rounded Corners)", kRealboxMatchSearchboxThemeRoundedCorners,
-     base::size(kRealboxMatchSearchboxThemeRoundedCorners), nullptr}};
+     std::size(kRealboxMatchSearchboxThemeRoundedCorners), nullptr}};
 
 const FeatureEntry::FeatureParam kNtpSafeBrowsingModuleFastCooldown[] = {
     {ntp_features::kNtpSafeBrowsingModuleCooldownPeriodDaysParam, "0.001"},
     {ntp_features::kNtpSafeBrowsingModuleCountMaxParam, "1"}};
 const FeatureEntry::FeatureVariation kNtpSafeBrowsingModuleVariations[] = {
     {"(Fast Cooldown)", kNtpSafeBrowsingModuleFastCooldown,
-     base::size(kNtpSafeBrowsingModuleFastCooldown), nullptr},
+     std::size(kNtpSafeBrowsingModuleFastCooldown), nullptr},
 };
 #endif  // !BUILDFLAG(IS_ANDROID)
 
@@ -1594,9 +1588,9 @@
 const FeatureEntry::FeatureVariation
     kTranslateForceTriggerOnEnglishVariations[] = {
         {"(Geo model without Ranker)", kTranslateForceTriggerOnEnglishGeo,
-         base::size(kTranslateForceTriggerOnEnglishGeo), nullptr},
+         std::size(kTranslateForceTriggerOnEnglishGeo), nullptr},
         {"(Zero threshold)", kTranslateForceTriggerOnEnglishBackoff,
-         base::size(kTranslateForceTriggerOnEnglishBackoff), nullptr}};
+         std::size(kTranslateForceTriggerOnEnglishBackoff), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 const FeatureEntry::FeatureParam kOverridePrefsForHrefTranslateForceAuto[] = {
@@ -1606,13 +1600,13 @@
     kOverrideLanguagePrefsForHrefTranslateVariations[] = {
         {"(Force automatic translation of blocked languages for hrefTranslate)",
          kOverridePrefsForHrefTranslateForceAuto,
-         base::size(kOverridePrefsForHrefTranslateForceAuto), nullptr}};
+         std::size(kOverridePrefsForHrefTranslateForceAuto), nullptr}};
 
 const FeatureEntry::FeatureVariation
     kOverrideSitePrefsForHrefTranslateVariations[] = {
         {"(Force automatic translation of blocked sites for hrefTranslate)",
          kOverridePrefsForHrefTranslateForceAuto,
-         base::size(kOverridePrefsForHrefTranslateForceAuto), nullptr}};
+         std::size(kOverridePrefsForHrefTranslateForceAuto), nullptr}};
 
 const FeatureEntry::FeatureParam
     kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto[] = {
@@ -1623,7 +1617,7 @@
         {"(Force automatic translation of pages with unknown language for "
          "hrefTranslate)",
          kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto,
-         base::size(kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto),
+         std::size(kOverrideUnsupportedPageLanguageForHrefTranslateForceAuto),
          nullptr}};
 
 const FeatureEntry::FeatureParam
@@ -1635,7 +1629,7 @@
         {"(Force automatic translation of pages with the same language as the "
          "target language for hrefTranslate)",
          kOverrideSimilarLanguagesForHrefTranslateForceAuto,
-         base::size(kOverrideSimilarLanguagesForHrefTranslateForceAuto),
+         std::size(kOverrideSimilarLanguagesForHrefTranslateForceAuto),
          nullptr}};
 
 #if BUILDFLAG(IS_ANDROID)
@@ -1655,9 +1649,9 @@
 const FeatureEntry::FeatureVariation kExploreSitesVariations[] = {
     {"Experimental", &kExploreSitesExperimental, 1, nullptr},
     {"Dense Title Bottom", kExploreSitesDenseTitleBottom,
-     base::size(kExploreSitesDenseTitleBottom), nullptr},
+     std::size(kExploreSitesDenseTitleBottom), nullptr},
     {"Dense Title Right", kExploreSitesDenseTitleRight,
-     base::size(kExploreSitesDenseTitleRight), nullptr}};
+     std::size(kExploreSitesDenseTitleRight), nullptr}};
 const FeatureEntry::FeatureParam kLongpressResolvePreserveTap = {
     contextual_search::kLongpressResolveParamName,
     contextual_search::kLongpressResolvePreserveTap};
@@ -1712,16 +1706,13 @@
      nullptr},
     {"with 110sp ellipsized default query chip",
      kRelatedSearchesInBarShowDefaultChipWith110SpEllipsis,
-     base::size(kRelatedSearchesInBarShowDefaultChipWith110SpEllipsis),
-     nullptr},
+     std::size(kRelatedSearchesInBarShowDefaultChipWith110SpEllipsis), nullptr},
     {"with 115sp ellipsized default query chip",
      kRelatedSearchesInBarShowDefaultChipWith115SpEllipsis,
-     base::size(kRelatedSearchesInBarShowDefaultChipWith115SpEllipsis),
-     nullptr},
+     std::size(kRelatedSearchesInBarShowDefaultChipWith115SpEllipsis), nullptr},
     {"with 120sp ellipsized default query chip",
      kRelatedSearchesInBarShowDefaultChipWith120SpEllipsis,
-     base::size(kRelatedSearchesInBarShowDefaultChipWith120SpEllipsis),
-     nullptr},
+     std::size(kRelatedSearchesInBarShowDefaultChipWith120SpEllipsis), nullptr},
 };
 
 const FeatureEntry::FeatureParam kRelatedSearchesAlternateUxNoShowDefaultChip =
@@ -1747,15 +1738,15 @@
      nullptr},
     {"with 110sp ellipsized default query chip",
      kRelatedSearchesAlternateUxShowDefaultChipWith110SpEllipsis,
-     base::size(kRelatedSearchesAlternateUxShowDefaultChipWith110SpEllipsis),
+     std::size(kRelatedSearchesAlternateUxShowDefaultChipWith110SpEllipsis),
      nullptr},
     {"with 115sp ellipsized default query chip",
      kRelatedSearchesAlternateUxShowDefaultChipWith115SpEllipsis,
-     base::size(kRelatedSearchesAlternateUxShowDefaultChipWith115SpEllipsis),
+     std::size(kRelatedSearchesAlternateUxShowDefaultChipWith115SpEllipsis),
      nullptr},
     {"with 120sp ellipsized default query chip",
      kRelatedSearchesAlternateUxShowDefaultChipWith120SpEllipsis,
-     base::size(kRelatedSearchesAlternateUxShowDefaultChipWith120SpEllipsis),
+     std::size(kRelatedSearchesAlternateUxShowDefaultChipWith120SpEllipsis),
      nullptr},
 };
 
@@ -1775,18 +1766,18 @@
 
 const FeatureEntry::FeatureVariation kResamplingInputEventsFeatureVariations[] =
     {{features::kPredictorNameLsq, kResamplingInputEventsLSQEnabled,
-      base::size(kResamplingInputEventsLSQEnabled), nullptr},
+      std::size(kResamplingInputEventsLSQEnabled), nullptr},
      {features::kPredictorNameKalman, kResamplingInputEventsKalmanEnabled,
-      base::size(kResamplingInputEventsKalmanEnabled), nullptr},
+      std::size(kResamplingInputEventsKalmanEnabled), nullptr},
      {features::kPredictorNameLinearFirst,
       kResamplingInputEventsLinearFirstEnabled,
-      base::size(kResamplingInputEventsLinearFirstEnabled), nullptr},
+      std::size(kResamplingInputEventsLinearFirstEnabled), nullptr},
      {features::kPredictorNameLinearSecond,
       kResamplingInputEventsLinearSecondEnabled,
-      base::size(kResamplingInputEventsLinearSecondEnabled), nullptr},
+      std::size(kResamplingInputEventsLinearSecondEnabled), nullptr},
      {features::kPredictorNameLinearResampling,
       kResamplingInputEventsLinearResamplingEnabled,
-      base::size(kResamplingInputEventsLinearResamplingEnabled), nullptr}};
+      std::size(kResamplingInputEventsLinearResamplingEnabled), nullptr}};
 
 const FeatureEntry::FeatureParam
     kResamplingScrollEventsPredictionTimeBasedEnabled[] = {
@@ -1800,11 +1791,10 @@
     kResamplingScrollEventsExperimentalPredictionVariations[] = {
         {features::kPredictionTypeTimeBased,
          kResamplingScrollEventsPredictionTimeBasedEnabled,
-         base::size(kResamplingScrollEventsPredictionTimeBasedEnabled),
-         nullptr},
+         std::size(kResamplingScrollEventsPredictionTimeBasedEnabled), nullptr},
         {features::kPredictionTypeFramesBased,
          kResamplingScrollEventsPredictionFramesBasedEnabled,
-         base::size(kResamplingScrollEventsPredictionFramesBasedEnabled),
+         std::size(kResamplingScrollEventsPredictionFramesBasedEnabled),
          nullptr}};
 
 const FeatureEntry::FeatureParam kFilteringPredictionEmptyFilterEnabled[] = {
@@ -1814,9 +1804,9 @@
 
 const FeatureEntry::FeatureVariation kFilteringPredictionFeatureVariations[] = {
     {features::kFilterNameEmpty, kFilteringPredictionEmptyFilterEnabled,
-     base::size(kFilteringPredictionEmptyFilterEnabled), nullptr},
+     std::size(kFilteringPredictionEmptyFilterEnabled), nullptr},
     {features::kFilterNameOneEuro, kFilteringPredictionOneEuroFilterEnabled,
-     base::size(kFilteringPredictionOneEuroFilterEnabled), nullptr}};
+     std::size(kFilteringPredictionOneEuroFilterEnabled), nullptr}};
 
 #if BUILDFLAG(IS_ANDROID)
 const FeatureEntry::FeatureParam kTabSwitcherOnReturn_Immediate[] = {
@@ -1829,13 +1819,13 @@
     {"tab_switcher_on_return_time_ms", "3600000"}};
 const FeatureEntry::FeatureVariation kTabSwitcherOnReturnVariations[] = {
     {"Immediate", kTabSwitcherOnReturn_Immediate,
-     base::size(kTabSwitcherOnReturn_30Minutes), nullptr},
+     std::size(kTabSwitcherOnReturn_30Minutes), nullptr},
     {"1 minute", kTabSwitcherOnReturn_1Minute,
-     base::size(kTabSwitcherOnReturn_30Minutes), nullptr},
+     std::size(kTabSwitcherOnReturn_30Minutes), nullptr},
     {"30 minutes", kTabSwitcherOnReturn_30Minutes,
-     base::size(kTabSwitcherOnReturn_30Minutes), nullptr},
+     std::size(kTabSwitcherOnReturn_30Minutes), nullptr},
     {"60 minutes", kTabSwitcherOnReturn_60Minutes,
-     base::size(kTabSwitcherOnReturn_60Minutes), nullptr},
+     std::size(kTabSwitcherOnReturn_60Minutes), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -1848,7 +1838,6 @@
     {"tab_grid_layout_android_new_tab_tile", "NewTabTile"}};
 
 const FeatureEntry::FeatureParam kTabGridLayoutAndroid_TallNTV[] = {
-    {"thumbnail_aspect_ratio", "0.85"},
     {"allow_to_refetch", "true"},
     {"tab_grid_layout_android_new_tab", "NewTabVariation"},
     {"enable_launch_polish", "true"},
@@ -1868,18 +1857,18 @@
 
 const FeatureEntry::FeatureVariation kTabGridLayoutAndroidVariations[] = {
     {"New Tab Variation", kTabGridLayoutAndroid_NewTabVariation,
-     base::size(kTabGridLayoutAndroid_NewTabVariation), nullptr},
+     std::size(kTabGridLayoutAndroid_NewTabVariation), nullptr},
     {"New Tab Tile", kTabGridLayoutAndroid_NewTabTile,
-     base::size(kTabGridLayoutAndroid_NewTabTile), nullptr},
+     std::size(kTabGridLayoutAndroid_NewTabTile), nullptr},
     {"Tall NTV", kTabGridLayoutAndroid_TallNTV,
-     base::size(kTabGridLayoutAndroid_TallNTV), nullptr},
+     std::size(kTabGridLayoutAndroid_TallNTV), nullptr},
     {"Search term chip", kTabGridLayoutAndroid_SearchChip,
-     base::size(kTabGridLayoutAndroid_SearchChip), nullptr},
+     std::size(kTabGridLayoutAndroid_SearchChip), nullptr},
     {"Without auto group", kTabGridLayoutAndroid_TabGroupAutoCreation,
-     base::size(kTabGridLayoutAndroid_TabGroupAutoCreation), nullptr},
+     std::size(kTabGridLayoutAndroid_TabGroupAutoCreation), nullptr},
     {"Without auto group-group first",
      kTabGridLayoutAndroid_TabGroupAutoCreation_TabGroupFirst,
-     base::size(kTabGridLayoutAndroid_TabGroupAutoCreation_TabGroupFirst),
+     std::size(kTabGridLayoutAndroid_TabGroupAutoCreation_TabGroupFirst),
      nullptr},
 };
 
@@ -1971,32 +1960,32 @@
 
 const FeatureEntry::FeatureVariation kStartSurfaceAndroidVariations[] = {
     {"Canidate A", kStartSurfaceAndroid_CandidateA,
-     base::size(kStartSurfaceAndroid_CandidateA), nullptr},
+     std::size(kStartSurfaceAndroid_CandidateA), nullptr},
     {"Canidate A + Sync check", kStartSurfaceAndroid_CandidateA_SyncCheck,
-     base::size(kStartSurfaceAndroid_CandidateA_SyncCheck), nullptr},
+     std::size(kStartSurfaceAndroid_CandidateA_SyncCheck), nullptr},
     {"Canidate A + Sign in promo backgrounded time limit",
      kStartSurfaceAndroid_CandidateA_SigninPromoTimeLimit,
-     base::size(kStartSurfaceAndroid_CandidateA_SigninPromoTimeLimit), nullptr},
+     std::size(kStartSurfaceAndroid_CandidateA_SigninPromoTimeLimit), nullptr},
     {"Canidate B", kStartSurfaceAndroid_CandidateB,
-     base::size(kStartSurfaceAndroid_CandidateB), nullptr},
+     std::size(kStartSurfaceAndroid_CandidateB), nullptr},
     {"Single Surface", kStartSurfaceAndroid_SingleSurface,
-     base::size(kStartSurfaceAndroid_SingleSurface), nullptr},
+     std::size(kStartSurfaceAndroid_SingleSurface), nullptr},
     {"Single Surface Finale", kStartSurfaceAndroid_SingleSurfaceFinale,
-     base::size(kStartSurfaceAndroid_SingleSurfaceFinale), nullptr},
+     std::size(kStartSurfaceAndroid_SingleSurfaceFinale), nullptr},
     {"Single Surface Finale + NTP tiles on Omnibox",
      kStartSurfaceAndroid_SingleSurfaceFinale_NTPTilesOnOmnibox,
-     base::size(kStartSurfaceAndroid_SingleSurfaceFinale_NTPTilesOnOmnibox),
+     std::size(kStartSurfaceAndroid_SingleSurfaceFinale_NTPTilesOnOmnibox),
      nullptr},
     {"Single Surface V2", kStartSurfaceAndroid_SingleSurface_V2,
-     base::size(kStartSurfaceAndroid_SingleSurface_V2), nullptr},
+     std::size(kStartSurfaceAndroid_SingleSurface_V2), nullptr},
     {"Single Surface V2 Finale", kStartSurfaceAndroid_SingleSurface_V2Finale,
-     base::size(kStartSurfaceAndroid_SingleSurface_V2Finale), nullptr},
+     std::size(kStartSurfaceAndroid_SingleSurface_V2Finale), nullptr},
     {"Single Surface V2 Finale + NTP tiles on Omnibox",
      kStartSurfaceAndroid_SingleSurface_V2Finale_NTPTilesOnOmnibox,
-     base::size(kStartSurfaceAndroid_SingleSurface_V2Finale_NTPTilesOnOmnibox),
+     std::size(kStartSurfaceAndroid_SingleSurface_V2Finale_NTPTilesOnOmnibox),
      nullptr},
     {"Single Surface + Single Tab", kStartSurfaceAndroid_SingleSurfaceSingleTab,
-     base::size(kStartSurfaceAndroid_SingleSurfaceSingleTab), nullptr},
+     std::size(kStartSurfaceAndroid_SingleSurfaceSingleTab), nullptr},
 };
 
 const FeatureEntry::FeatureParam kFeatureNotificationGuide_low_engaged[] = {
@@ -2009,9 +1998,9 @@
 
 const FeatureEntry::FeatureVariation kFeatureNotificationGuideVariations[] = {
     {"Low engaged users", kFeatureNotificationGuide_low_engaged,
-     base::size(kFeatureNotificationGuide_low_engaged), nullptr},
+     std::size(kFeatureNotificationGuide_low_engaged), nullptr},
     {"Default browser", kFeatureNotificationGuide_default_browser,
-     base::size(kFeatureNotificationGuide_default_browser), nullptr},
+     std::size(kFeatureNotificationGuide_default_browser), nullptr},
 };
 const FeatureEntry::FeatureParam kWebFeed_accelerator[] = {
     {"intro_style", "accelerator"}};
@@ -2020,8 +2009,8 @@
 
 const FeatureEntry::FeatureVariation kWebFeedVariations[] = {
     {"accelerator recommendations", kWebFeed_accelerator,
-     base::size(kWebFeed_accelerator), nullptr},
-    {"IPH recommendations", kWebFeed_IPH, base::size(kWebFeed_IPH), nullptr},
+     std::size(kWebFeed_accelerator), nullptr},
+    {"IPH recommendations", kWebFeed_IPH, std::size(kWebFeed_IPH), nullptr},
 };
 
 const FeatureEntry::FeatureParam kConditionalTabStripAndroid_Immediate[] = {
@@ -2030,9 +2019,9 @@
     {"conditional_tab_strip_session_time_ms", "3600000"}};
 const FeatureEntry::FeatureVariation kConditionalTabStripAndroidVariations[] = {
     {"Immediate", kConditionalTabStripAndroid_Immediate,
-     base::size(kConditionalTabStripAndroid_Immediate), nullptr},
+     std::size(kConditionalTabStripAndroid_Immediate), nullptr},
     {"60 minutes", kConditionalTabStripAndroid_60Minutes,
-     base::size(kConditionalTabStripAndroid_60Minutes), nullptr},
+     std::size(kConditionalTabStripAndroid_60Minutes), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -2044,9 +2033,9 @@
 
 const FeatureEntry::FeatureVariation kAddToHomescreenIPHVariations[] = {
     {"Use Text Bubble", kAddToHomescreen_UseTextBubble,
-     base::size(kAddToHomescreen_UseTextBubble), nullptr},
+     std::size(kAddToHomescreen_UseTextBubble), nullptr},
     {"Use Message", kAddToHomescreen_UseMessage,
-     base::size(kAddToHomescreen_UseMessage), nullptr}};
+     std::size(kAddToHomescreen_UseMessage), nullptr}};
 #endif
 
 #if BUILDFLAG(IS_ANDROID)
@@ -2064,9 +2053,9 @@
 const FeatureEntry::FeatureVariation
     kAutofillUseMobileLabelDisambiguationVariations[] = {
         {"(show all)", kAutofillUseMobileLabelDisambiguationShowAll,
-         base::size(kAutofillUseMobileLabelDisambiguationShowAll), nullptr},
+         std::size(kAutofillUseMobileLabelDisambiguationShowAll), nullptr},
         {"(show one)", kAutofillUseMobileLabelDisambiguationShowOne,
-         base::size(kAutofillUseMobileLabelDisambiguationShowOne), nullptr}};
+         std::size(kAutofillUseMobileLabelDisambiguationShowOne), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_ANDROID)
@@ -2081,14 +2070,14 @@
     {"suppressing_sign_in_promo", "true"}};
 
 const FeatureEntry::FeatureVariation kHomepagePromoCardVariations[] = {
-    {"Large", kHomepagePromoCardLarge, base::size(kHomepagePromoCardLarge),
+    {"Large", kHomepagePromoCardLarge, std::size(kHomepagePromoCardLarge),
      nullptr},
-    {"Compact", kHomepagePromoCardCompact,
-     base::size(kHomepagePromoCardCompact), nullptr},
-    {"Slim", kHomepagePromoCardSlim, base::size(kHomepagePromoCardSlim),
+    {"Compact", kHomepagePromoCardCompact, std::size(kHomepagePromoCardCompact),
+     nullptr},
+    {"Slim", kHomepagePromoCardSlim, std::size(kHomepagePromoCardSlim),
      nullptr},
     {"Compact_SuppressingSignInPromo", kHomepagePromoCardSuppressing,
-     base::size(kHomepagePromoCardSuppressing), nullptr}};
+     std::size(kHomepagePromoCardSuppressing), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_ANDROID)
@@ -2108,22 +2097,22 @@
 
 const FeatureEntry::FeatureVariation kLensCameraAssistedSearchVariations[] = {
     {"(Lens then Mic)", kLensCameraAssistedSearchLensButtonStart,
-     base::size(kLensCameraAssistedSearchLensButtonStart), nullptr},
+     std::size(kLensCameraAssistedSearchLensButtonStart), nullptr},
     {"(Mic then Lens)", kLensCameraAssistedSearchLensButtonEnd,
-     base::size(kLensCameraAssistedSearchLensButtonEnd), nullptr},
+     std::size(kLensCameraAssistedSearchLensButtonEnd), nullptr},
     {"(without AGSA version check)",
      kLensCameraAssistedSkipAgsaVersionCheckEnabled,
-     base::size(kLensCameraAssistedSkipAgsaVersionCheckEnabled), nullptr},
+     std::size(kLensCameraAssistedSkipAgsaVersionCheckEnabled), nullptr},
     {"(with AGSA version check )",
      kLensCameraAssistedSkipAgsaVersionCheckDisabled,
-     base::size(kLensCameraAssistedSkipAgsaVersionCheckDisabled), nullptr}};
+     std::size(kLensCameraAssistedSkipAgsaVersionCheckDisabled), nullptr}};
 
 const FeatureEntry::FeatureParam kLensContextMenuTranslateHideRemoveIcon[] = {
     {"hideChipRemoveIcon", "true"}};
 
 const FeatureEntry::FeatureVariation kLensContextMenuTranslateVariations[] = {
     {"(Hide Remove Icon)", kLensContextMenuTranslateHideRemoveIcon,
-     base::size(kLensContextMenuTranslateHideRemoveIcon), nullptr},
+     std::size(kLensContextMenuTranslateHideRemoveIcon), nullptr},
 };
 
 const FeatureEntry::FeatureParam kLensContextMenuSearchOnTablet[] = {
@@ -2131,14 +2120,14 @@
 
 const FeatureEntry::FeatureVariation kLensContextMenuSearchVariations[] = {
     {"(on Tablet)", kLensContextMenuSearchOnTablet,
-     base::size(kLensContextMenuSearchOnTablet), nullptr},
+     std::size(kLensContextMenuSearchOnTablet), nullptr},
 };
 
 const FeatureEntry::FeatureParam kDynamicColorFull[] = {
     {"dynamic_color_full", "true"}};
 
 const FeatureEntry::FeatureVariation kDynamicColorAndroidVariations[] = {
-    {"(Full)", kDynamicColorFull, base::size(kDynamicColorFull), nullptr},
+    {"(Full)", kDynamicColorFull, std::size(kDynamicColorFull), nullptr},
 };
 
 #endif  // BUILDFLAG(IS_ANDROID)
@@ -2151,7 +2140,7 @@
 const FeatureEntry::FeatureVariation kLazyFrameLoadingVariations[] = {
     {"(Automatically lazily load where safe even if not marked "
      "'loading=lazy')",
-     kLazyFrameLoadingAutomatic, base::size(kLazyFrameLoadingAutomatic),
+     kLazyFrameLoadingAutomatic, std::size(kLazyFrameLoadingAutomatic),
      nullptr}};
 
 const FeatureEntry::FeatureParam kLazyImageLoadingAutomatic[] = {
@@ -2162,7 +2151,7 @@
 const FeatureEntry::FeatureVariation kLazyImageLoadingVariations[] = {
     {"(Automatically lazily load where safe even if not marked "
      "'loading=lazy')",
-     kLazyImageLoadingAutomatic, base::size(kLazyImageLoadingAutomatic),
+     kLazyImageLoadingAutomatic, std::size(kLazyImageLoadingAutomatic),
      nullptr}};
 
 const FeatureEntry::Choice kNotificationSchedulerChoices[] = {
@@ -2180,7 +2169,7 @@
 
 const FeatureEntry::FeatureVariation kAssistantConsentV2_Variations[] = {
     {"Limited Re-prompts", kAssistantConsentV2_reprompts_counter,
-     base::size(kAssistantConsentV2_reprompts_counter), nullptr},
+     std::size(kAssistantConsentV2_reprompts_counter), nullptr},
 };
 
 const FeatureEntry::FeatureParam kOmniboxAssistantVoiceSearchGreyMic[] = {
@@ -2200,11 +2189,11 @@
 const FeatureEntry::FeatureVariation kOmniboxAssistantVoiceSearchVariations[] =
     {
         {"(grey mic)", kOmniboxAssistantVoiceSearchGreyMic,
-         base::size(kOmniboxAssistantVoiceSearchGreyMic), nullptr},
+         std::size(kOmniboxAssistantVoiceSearchGreyMic), nullptr},
         {"(colorful mic)", kOmniboxAssistantVoiceSearchColorfulMic,
-         base::size(kOmniboxAssistantVoiceSearchColorfulMic), nullptr},
+         std::size(kOmniboxAssistantVoiceSearchColorfulMic), nullptr},
         {"(no account check)", kOmniboxAssistantVoiceSearchNoMultiAccountCheck,
-         base::size(kOmniboxAssistantVoiceSearchNoMultiAccountCheck), nullptr},
+         std::size(kOmniboxAssistantVoiceSearchNoMultiAccountCheck), nullptr},
 };
 
 const FeatureEntry::FeatureParam
@@ -2214,7 +2203,7 @@
     kPhotoPickerVideoSupportFeatureVariations[] = {
         {"(with animated thumbnails)",
          kPhotoPickerVideoSupportEnabledWithAnimatedThumbnails,
-         base::size(kPhotoPickerVideoSupportEnabledWithAnimatedThumbnails),
+         std::size(kPhotoPickerVideoSupportEnabledWithAnimatedThumbnails),
          nullptr}};
 
 // Request Desktop Site on Tablet by default variations.
@@ -2241,19 +2230,19 @@
     {"enabled", "true"}};
 const FeatureEntry::FeatureVariation kRequestDesktopSiteForTabletsVariations[] =
     {{"for 100dp+ screens", kRequestDesktopSiteForTablets100,
-      base::size(kRequestDesktopSiteForTablets100), nullptr},
+      std::size(kRequestDesktopSiteForTablets100), nullptr},
      {"for 600dp+ screens", kRequestDesktopSiteForTablets600,
-      base::size(kRequestDesktopSiteForTablets600), nullptr},
+      std::size(kRequestDesktopSiteForTablets600), nullptr},
      {"for 768dp+ screens", kRequestDesktopSiteForTablets768,
-      base::size(kRequestDesktopSiteForTablets768), nullptr},
+      std::size(kRequestDesktopSiteForTablets768), nullptr},
      {"for 960dp+ screens", kRequestDesktopSiteForTablets960,
-      base::size(kRequestDesktopSiteForTablets960), nullptr},
+      std::size(kRequestDesktopSiteForTablets960), nullptr},
      {"for 1024dp+ screens", kRequestDesktopSiteForTablets1024,
-      base::size(kRequestDesktopSiteForTablets1024), nullptr},
+      std::size(kRequestDesktopSiteForTablets1024), nullptr},
      {"for 1280dp+ screens", kRequestDesktopSiteForTablets1280,
-      base::size(kRequestDesktopSiteForTablets1280), nullptr},
+      std::size(kRequestDesktopSiteForTablets1280), nullptr},
      {"for 1920dp+ screens", kRequestDesktopSiteForTablets1920,
-      base::size(kRequestDesktopSiteForTablets1920), nullptr}};
+      std::size(kRequestDesktopSiteForTablets1920), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 // TODO(crbug.com/991082,1015377): Remove after proper support for back-forward
@@ -2270,9 +2259,9 @@
 
 const FeatureEntry::FeatureVariation kBackForwardCacheVariations[] = {
     {"same-site support (experimental)", kBackForwardCache_SameSite,
-     base::size(kBackForwardCache_SameSite), nullptr},
+     std::size(kBackForwardCache_SameSite), nullptr},
     {"force caching all pages (experimental)", kBackForwardCache_ForceCaching,
-     base::size(kBackForwardCache_ForceCaching), nullptr},
+     std::size(kBackForwardCache_ForceCaching), nullptr},
 };
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2362,23 +2351,23 @@
 const FeatureEntry::FeatureVariation kDrawPredictedPointVariations[] = {
     {flag_descriptions::kDraw1PredictedPoint12Ms,
      kDrawPredictedPointExperiment1Point12Ms,
-     base::size(kDrawPredictedPointExperiment1Point12Ms), nullptr},
+     std::size(kDrawPredictedPointExperiment1Point12Ms), nullptr},
     {flag_descriptions::kDraw2PredictedPoints6Ms,
      kDrawPredictedPointExperiment2Points6Ms,
-     base::size(kDrawPredictedPointExperiment2Points6Ms), nullptr},
+     std::size(kDrawPredictedPointExperiment2Points6Ms), nullptr},
     {flag_descriptions::kDraw1PredictedPoint6Ms,
      kDrawPredictedPointExperiment1Point6Ms,
-     base::size(kDrawPredictedPointExperiment1Point6Ms), nullptr},
+     std::size(kDrawPredictedPointExperiment1Point6Ms), nullptr},
     {flag_descriptions::kDraw2PredictedPoints3Ms,
      kDrawPredictedPointExperiment2Points3Ms,
-     base::size(kDrawPredictedPointExperiment2Points3Ms), nullptr}};
+     std::size(kDrawPredictedPointExperiment2Points3Ms), nullptr}};
 
 #if BUILDFLAG(IS_ANDROID)
 const FeatureEntry::FeatureParam kFedCmVariationAutoSignin[] = {
     {features::kFedCmAutoSigninFieldTrialParamName, "true"}};
 const FeatureEntry::FeatureVariation kFedCmFeatureVariations[] = {
     {"- with FedCM auto-signin", kFedCmVariationAutoSignin,
-     base::size(kFedCmVariationAutoSignin), nullptr}};
+     std::size(kFedCmVariationAutoSignin), nullptr}};
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2422,7 +2411,7 @@
     kPasswordChangeInSettingsFeatureVariations[] = {
         {"Force leak warnings for every site in settings.",
          kPasswordChangeInSettingsVariationWithForcedWarningForEverySite,
-         base::size(
+         std::size(
              kPasswordChangeInSettingsVariationWithForcedWarningForEverySite),
          nullptr}};
 
@@ -2436,7 +2425,7 @@
 const FeatureEntry::FeatureVariation kPasswordChangeFeatureVariations[] = {
     {"Force dialog after every successful form submission.",
      kPasswordChangeVariationWithForcedDialogAfterEverySuccessfulSubmission,
-     base::size(
+     std::size(
          kPasswordChangeVariationWithForcedDialogAfterEverySuccessfulSubmission),
      nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
@@ -2454,13 +2443,13 @@
 const FeatureEntry::FeatureVariation
     kPageInfoDiscoverabilityTimeoutVariations[] = {
         {"Long (6s)", kPermissionIconTimeout6000,
-         base::size(kPermissionIconTimeout6000), nullptr},
+         std::size(kPermissionIconTimeout6000), nullptr},
         {"Medium (4s)", kPermissionIconTimeout4000,
-         base::size(kPermissionIconTimeout4000), nullptr},
+         std::size(kPermissionIconTimeout4000), nullptr},
         {"Short (3s)", kPermissionIconTimeout3000,
-         base::size(kPermissionIconTimeout3000), nullptr},
+         std::size(kPermissionIconTimeout3000), nullptr},
         {"Extra-Short (2s)", kPermissionIconTimeout2000,
-         base::size(kPermissionIconTimeout2000), nullptr},
+         std::size(kPermissionIconTimeout2000), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -2474,9 +2463,9 @@
 
 const FeatureEntry::FeatureVariation kMetricsSettingsAndroidVariations[] = {
     {"Alternative FRE 1", kMetricsSettingsAndroidAlternativeOne,
-     base::size(kMetricsSettingsAndroidAlternativeOne), nullptr},
+     std::size(kMetricsSettingsAndroidAlternativeOne), nullptr},
     {"Alternative FRE 2", kMetricsSettingsAndroidAlternativeTwo,
-     base::size(kMetricsSettingsAndroidAlternativeTwo), nullptr},
+     std::size(kMetricsSettingsAndroidAlternativeTwo), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -2491,11 +2480,11 @@
 
 const FeatureEntry::FeatureVariation kSCTAuditingVariations[] = {
     {"Sampling rate 0%", kSCTAuditingSamplingRateNone,
-     base::size(kSCTAuditingSamplingRateNone), nullptr},
+     std::size(kSCTAuditingSamplingRateNone), nullptr},
     {"Sampling rate 0.01%", kSCTAuditingSamplingRateAlternativeOne,
-     base::size(kSCTAuditingSamplingRateAlternativeOne), nullptr},
+     std::size(kSCTAuditingSamplingRateAlternativeOne), nullptr},
     {"Sampling rate 0.1%", kSCTAuditingSamplingRateAlternativeTwo,
-     base::size(kSCTAuditingSamplingRateAlternativeTwo), nullptr},
+     std::size(kSCTAuditingSamplingRateAlternativeTwo), nullptr},
 };
 #endif  // !BUILDFLAG(IS_ANDROID)
 
@@ -2508,8 +2497,7 @@
 const FeatureEntry::FeatureVariation
     kContentLanguagesInLanguaePickerVariations[] = {
         {"Without observers", kContentLanguagesInLanguagePickerDisableObservers,
-         base::size(kContentLanguagesInLanguagePickerDisableObservers),
-         nullptr},
+         std::size(kContentLanguagesInLanguagePickerDisableObservers), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -2520,9 +2508,9 @@
 
 const FeatureEntry::FeatureVariation kCheckOfflineCapabilityVariations[] = {
     {"Warn-only", kCheckOfflineCapabilityWarnOnly,
-     base::size(kCheckOfflineCapabilityWarnOnly), nullptr},
+     std::size(kCheckOfflineCapabilityWarnOnly), nullptr},
     {"Enforce", kCheckOfflineCapabilityEnforce,
-     base::size(kCheckOfflineCapabilityEnforce), nullptr},
+     std::size(kCheckOfflineCapabilityEnforce), nullptr},
 };
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2537,18 +2525,18 @@
 
 const FeatureEntry::FeatureVariation kCategoricalSearchVariations[] = {
     {"Unranked", kCategoricalSearch_Unranked,
-     base::size(kCategoricalSearch_Unranked), nullptr},
-    {"By item", kCategoricalSearch_ByItem,
-     base::size(kCategoricalSearch_ByItem), nullptr},
+     std::size(kCategoricalSearch_Unranked), nullptr},
+    {"By item", kCategoricalSearch_ByItem, std::size(kCategoricalSearch_ByItem),
+     nullptr},
     {"By usage", kCategoricalSearch_ByUsage,
-     base::size(kCategoricalSearch_ByUsage), nullptr}};
+     std::size(kCategoricalSearch_ByUsage), nullptr}};
 
 const FeatureEntry::FeatureParam kProductivityLauncher_WithoutContinue[] = {
     {"enable_continue", "false"}};
 
 const FeatureEntry::FeatureVariation kProductivityLauncherVariations[] = {
     {"without Continue", kProductivityLauncher_WithoutContinue,
-     base::size(kProductivityLauncher_WithoutContinue), nullptr}};
+     std::size(kProductivityLauncher_WithoutContinue), nullptr}};
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -2559,7 +2547,7 @@
     kPlatformProvidedTrustTokensVariations[] = {
         {"with platform-provided trust token issuance",
          kPlatformProvidedTrustTokenIssuance,
-         base::size(kPlatformProvidedTrustTokenIssuance), nullptr}};
+         std::size(kPlatformProvidedTrustTokenIssuance), nullptr}};
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #if BUILDFLAG(HAS_ASH_AMBIENT_ANIMATION_RESOURCES)
@@ -2577,7 +2565,7 @@
 
 const FeatureEntry::FeatureVariation kPaintPreviewStartupVariations[] = {
     {"with accessibility support", kPaintPreviewStartupWithAccessibility,
-     base::size(kPaintPreviewStartupWithAccessibility), nullptr}};
+     std::size(kPaintPreviewStartupWithAccessibility), nullptr}};
 #endif  // BUILDFLAG(ENABLE_PAINT_PREVIEW) && BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2605,13 +2593,13 @@
 
 const FeatureEntry::FeatureVariation kContinuousSearchFeatureVariations[] = {
     {"show after second SRP", kContinuousSearchAfterSecondSrp,
-     base::size(kContinuousSearchAfterSecondSrp), nullptr},
+     std::size(kContinuousSearchAfterSecondSrp), nullptr},
     {"show on reverse scroll", kContinuousSearchOnReverseScroll,
-     base::size(kContinuousSearchOnReverseScroll), nullptr},
+     std::size(kContinuousSearchOnReverseScroll), nullptr},
     {"with permanent dismissal", kContinuousSearchPermanentDismissal,
-     base::size(kContinuousSearchPermanentDismissal), nullptr},
+     std::size(kContinuousSearchPermanentDismissal), nullptr},
     {"with double-row chips", kContinuousSearchDoubleRowChip,
-     base::size(kContinuousSearchDoubleRowChip), nullptr}};
+     std::size(kContinuousSearchDoubleRowChip), nullptr}};
 
 const FeatureEntry::FeatureParam kReadLaterUseRootBookmarkAsDefault[] = {
     {"use_root_bookmark_as_default", "true"}};
@@ -2628,13 +2616,13 @@
 
 const FeatureEntry::FeatureVariation kReadLaterVariations[] = {
     {"(use root bookmark as default)", kReadLaterUseRootBookmarkAsDefault,
-     base::size(kReadLaterUseRootBookmarkAsDefault), nullptr},
+     std::size(kReadLaterUseRootBookmarkAsDefault), nullptr},
     {"(with app menu item)", kReadLaterInAppMenu,
-     base::size(kReadLaterInAppMenu), nullptr},
+     std::size(kReadLaterInAppMenu), nullptr},
     {"(bookmarks semi-integration)", kReadLaterSemiIntegrated,
-     base::size(kReadLaterSemiIntegrated), nullptr},
-    {"(no custom tab)", kReadLaterNoCustomTab,
-     base::size(kReadLaterNoCustomTab), nullptr}};
+     std::size(kReadLaterSemiIntegrated), nullptr},
+    {"(no custom tab)", kReadLaterNoCustomTab, std::size(kReadLaterNoCustomTab),
+     nullptr}};
 
 const FeatureEntry::FeatureParam kBookmarksRefreshVisuals[] = {
     {"bookmark_visuals_enabled", "true"}};
@@ -2646,11 +2634,11 @@
 
 const FeatureEntry::FeatureVariation kBookmarksRefreshVariations[] = {
     {"(manager visuals only)", kBookmarksRefreshVisuals,
-     base::size(kBookmarksRefreshVisuals), nullptr},
+     std::size(kBookmarksRefreshVisuals), nullptr},
     {"(app menu item only)", kBookmarksRefreshAppMenu,
-     base::size(kBookmarksRefreshAppMenu), nullptr},
+     std::size(kBookmarksRefreshAppMenu), nullptr},
     {"(everything)", kBookmarksRefreshWithEverything,
-     base::size(kBookmarksRefreshWithEverything), nullptr}};
+     std::size(kBookmarksRefreshWithEverything), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
 const FeatureEntry::FeatureParam kLargeFaviconFromGoogle96[] = {
@@ -2659,10 +2647,10 @@
     {"favicon_size_in_dip", "128"}};
 
 const FeatureEntry::FeatureVariation kLargeFaviconFromGoogleVariations[] = {
-    {"(96dip)", kLargeFaviconFromGoogle96,
-     base::size(kLargeFaviconFromGoogle96), nullptr},
+    {"(96dip)", kLargeFaviconFromGoogle96, std::size(kLargeFaviconFromGoogle96),
+     nullptr},
     {"(128dip)", kLargeFaviconFromGoogle128,
-     base::size(kLargeFaviconFromGoogle128), nullptr}};
+     std::size(kLargeFaviconFromGoogle128), nullptr}};
 
 const FeatureEntry::Choice kDocumentTransitionSlowdownFactorChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
@@ -2699,11 +2687,11 @@
 
 const FeatureEntry::FeatureVariation kSnoopingProtectionVariations[] = {
     {"Precise", kSnoopingProtectionPrecision,
-     base::size(kSnoopingProtectionPrecision), nullptr},
+     std::size(kSnoopingProtectionPrecision), nullptr},
     {"Slow Precise", kSnoopingProtectionConfidence,
-     base::size(kSnoopingProtectionConfidence), nullptr},
+     std::size(kSnoopingProtectionConfidence), nullptr},
     {"Comprehensive", kSnoopingProtectionRecall,
-     base::size(kSnoopingProtectionRecall), nullptr}};
+     std::size(kSnoopingProtectionRecall), nullptr}};
 
 const FeatureEntry::FeatureParam kQuickDim6s[] = {
     {"QuickDim_quick_dim_ms", "6000"},
@@ -2772,16 +2760,16 @@
 
 const FeatureEntry::FeatureVariation kQuickDimVariations[] = {
     {"Dim6sLock66s", kQuickDim6sQuickLock66s,
-     base::size(kQuickDim6sQuickLock66s), nullptr},
+     std::size(kQuickDim6sQuickLock66s), nullptr},
     {"Dim6sLock126s", kQuickDim6sQuickLock126s,
-     base::size(kQuickDim6sQuickLock126s), nullptr},
+     std::size(kQuickDim6sQuickLock126s), nullptr},
     {"Dim45sLock105s", kQuickDim45sQuickLock105s,
-     base::size(kQuickDim45sQuickLock105s), nullptr},
+     std::size(kQuickDim45sQuickLock105s), nullptr},
     {"Dim45sLock165s", kQuickDim45sQuickLock165s,
-     base::size(kQuickDim45sQuickLock165s), nullptr},
+     std::size(kQuickDim45sQuickLock165s), nullptr},
     {"Dim120sLock240s", kQuickDim120sQuickLock240s,
-     base::size(kQuickDim120sQuickLock240s), nullptr},
-    {"Dim6sNoLock", kQuickDim6s, base::size(kQuickDim6s), nullptr},
+     std::size(kQuickDim120sQuickLock240s), nullptr},
+    {"Dim6sNoLock", kQuickDim6s, std::size(kQuickDim6s), nullptr},
 };
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2812,7 +2800,7 @@
 
 const FeatureEntry::FeatureVariation kGridTabSwitcherForTabletsVariations[] = {
     {"(Polished)", kGridTabSwitcherForTabletsPolished,
-     base::size(kGridTabSwitcherForTabletsPolished), nullptr},
+     std::size(kGridTabSwitcherForTabletsPolished), nullptr},
 };
 #endif  // BUILDFLAG(IS_ANDROID)
 
@@ -5984,10 +5972,6 @@
      flag_descriptions::kEnableRevenLogSourceDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kRevenLogSource)},
 
-    {"enable-pci-guard-ui", flag_descriptions::kEnablePciguardUiName,
-     flag_descriptions::kEnablePciguardUiDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kEnablePciguardUi)},
-
     {"enable-heuristic-stylus-palm-rejection",
      flag_descriptions::kEnableHeuristicStylusPalmRejectionName,
      flag_descriptions::kEnableHeuristicStylusPalmRejectionDescription, kOsCrOS,
@@ -6768,6 +6752,10 @@
      flag_descriptions::kNearbySharingSelfShareName,
      flag_descriptions::kNearbySharingSelfShareDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kNearbySharingSelfShare)},
+    {"nearby-sharing-visibility-reminder",
+     flag_descriptions::kNearbySharingVisibilityReminderName,
+     flag_descriptions::kNearbySharingVisibilityReminderDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(features::kNearbySharingVisibilityReminder)},
     {"nearby-sharing-wifilan", flag_descriptions::kNearbySharingWifiLanName,
      flag_descriptions::kNearbySharingWifiLanDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kNearbySharingWifiLan)},
@@ -7650,6 +7638,10 @@
      FEATURE_WITH_PARAMS_VALUE_TYPE(chrome::android::kDynamicColorAndroid,
                                     kDynamicColorAndroidVariations,
                                     "AndroidDynamicColor")},
+    {"dynamic-color-buttons-android",
+     flag_descriptions::kDynamicColorButtonsAndroidName,
+     flag_descriptions::kDynamicColorButtonsAndroidDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kDynamicColorButtonsAndroid)},
 #endif  //   BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_WIN)
@@ -8425,7 +8417,7 @@
 base::span<const FeatureEntry> GetFeatureEntries() {
   if (!GetEntriesForTesting()->empty())
     return base::span<FeatureEntry>(*GetEntriesForTesting());
-  return base::make_span(kFeatureEntries, base::size(kFeatureEntries));
+  return base::make_span(kFeatureEntries, std::size(kFeatureEntries));
 }
 
 }  // namespace testing
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
index 3a2f42b..bd8a1796 100644
--- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc
+++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -274,7 +274,7 @@
       autofill::ServerFieldType::ADDRESS_HOME_SORTING_CODE,
       autofill::ServerFieldType::ADDRESS_HOME_COUNTRY,
   };
-  size_t fields_size = base::size(kLabelFields);
+  size_t fields_size = std::size(kLabelFields);
 
   // For the case where country is omitted, do not use the last field.
   if (!with_country) {
diff --git a/chrome/browser/android/chrome_backup_agent.cc b/chrome/browser/android/chrome_backup_agent.cc
index 366d645..e95ac24 100644
--- a/chrome/browser/android/chrome_backup_agent.cc
+++ b/chrome/browser/android/chrome_backup_agent.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/android/chrome_backup_agent.h"
+
 #include <iterator>
 #include <string>
 #include <vector>
 
 #include "base/android/jni_array.h"
-#include "base/cxx17_backports.h"
 #include "chrome/android/chrome_jni_headers/ChromeBackupAgentImpl_jni.h"
-#include "chrome/browser/android/chrome_backup_agent.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync/base/pref_names.h"
@@ -43,7 +43,7 @@
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& jcaller) {
   PrefService* prefs = ProfileManager::GetLastUsedProfile()->GetPrefs();
-  constexpr int pref_count = base::size(backed_up_preferences_);
+  constexpr int pref_count = std::size(backed_up_preferences_);
   jboolean values[pref_count];
 
   for (int i = 0; i < pref_count; i++) {
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index 6f60ff72..7ca5769 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -44,8 +44,6 @@
 
 namespace {
 
-const double kDefaultThumbnailAspectRatio = 0.85;
-
 using TabReadbackCallback = base::OnceCallback<void(float, const SkBitmap&)>;
 
 }  // namespace
@@ -56,6 +54,7 @@
  public:
   TabReadbackRequest(content::RenderWidgetHostView* rwhv,
                      float thumbnail_scale,
+                     float aspect_ratio,
                      bool crop_to_match_aspect_ratio,
                      TabReadbackCallback end_callback)
       : thumbnail_scale_(thumbnail_scale),
@@ -73,10 +72,6 @@
       return;
     }
     if (crop_to_match_aspect_ratio) {
-      double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
-          chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
-          kDefaultThumbnailAspectRatio);
-      aspect_ratio = base::clamp(aspect_ratio, 0.5, 2.0);
       int height = std::min(view_size_in_pixels.height(),
                             (int)(view_size_in_pixels.width() / aspect_ratio));
       view_size_in_pixels.set_height(height);
@@ -131,11 +126,9 @@
                                      jint compression_queue_max_size,
                                      jint write_queue_max_size,
                                      jboolean use_approximation_thumbnail,
-                                     jboolean save_jpeg_thumbnails)
+                                     jboolean save_jpeg_thumbnails,
+                                     jfloat jpeg_aspect_ratio)
     : weak_java_tab_content_manager_(env, obj) {
-  double jpeg_aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
-      chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
-      kDefaultThumbnailAspectRatio);
   thumbnail_cache_ = std::make_unique<ThumbnailCache>(
       static_cast<size_t>(default_cache_size),
       static_cast<size_t>(approximation_cache_size),
@@ -262,6 +255,7 @@
     const JavaParamRef<jobject>& obj,
     const JavaParamRef<jobject>& tab,
     jfloat thumbnail_scale,
+    jfloat aspect_ratio,
     jboolean write_to_cache,
     const base::android::JavaParamRef<jobject>& j_callback) {
   TabAndroid* tab_android = TabAndroid::GetNativeTab(env, tab);
@@ -280,9 +274,10 @@
   }
   TabReadbackCallback readback_done_callback = base::BindOnce(
       &TabContentManager::OnTabReadback, weak_factory_.GetWeakPtr(), tab_id,
-      base::android::ScopedJavaGlobalRef<jobject>(j_callback), write_to_cache);
+      base::android::ScopedJavaGlobalRef<jobject>(j_callback), write_to_cache,
+      aspect_ratio);
   pending_tab_readbacks_[tab_id] = std::make_unique<TabReadbackRequest>(
-      rwhv, thumbnail_scale, !write_to_cache,
+      rwhv, thumbnail_scale, aspect_ratio, !write_to_cache,
       std::move(readback_done_callback));
 }
 
@@ -290,7 +285,8 @@
                                            const JavaParamRef<jobject>& obj,
                                            const JavaParamRef<jobject>& tab,
                                            const JavaParamRef<jobject>& bitmap,
-                                           jfloat thumbnail_scale) {
+                                           jfloat thumbnail_scale,
+                                           jfloat aspect_ratio) {
   TabAndroid* tab_android = TabAndroid::GetNativeTab(env, tab);
   DCHECK(tab_android);
   int tab_id = tab_android->GetAndroidId();
@@ -301,7 +297,8 @@
   skbitmap.setImmutable();
 
   if (thumbnail_cache_->CheckAndUpdateThumbnailMetaData(tab_id, url))
-    OnTabReadback(tab_id, nullptr, true, thumbnail_scale, skbitmap);
+    OnTabReadback(tab_id, nullptr, true, aspect_ratio, thumbnail_scale,
+                  skbitmap);
 }
 
 void TabContentManager::InvalidateIfChanged(JNIEnv* env,
@@ -345,13 +342,14 @@
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& obj,
     jint tab_id,
+    jfloat aspect_ratio,
     const base::android::JavaParamRef<jobject>& j_callback) {
   thumbnail_cache_->DecompressThumbnailFromFile(
       tab_id,
       base::BindOnce(&TabContentManager::SendThumbnailToJava,
                      weak_factory_.GetWeakPtr(),
                      base::android::ScopedJavaGlobalRef<jobject>(j_callback),
-                     /* need_downsampling */ true));
+                     /* need_downsampling */ true, aspect_ratio));
 }
 
 void TabContentManager::OnUIResourcesWereEvicted() {
@@ -368,6 +366,7 @@
     int tab_id,
     base::android::ScopedJavaGlobalRef<jobject> j_callback,
     bool write_to_cache,
+    float aspect_ratio,
     float thumbnail_scale,
     const SkBitmap& bitmap) {
   TabReadbackRequestMap::iterator readback_iter =
@@ -377,7 +376,7 @@
     pending_tab_readbacks_.erase(tab_id);
 
   if (j_callback) {
-    SendThumbnailToJava(j_callback, write_to_cache, true, bitmap);
+    SendThumbnailToJava(j_callback, write_to_cache, aspect_ratio, true, bitmap);
   }
 
   if (write_to_cache && thumbnail_scale > 0 && !bitmap.empty())
@@ -387,6 +386,7 @@
 void TabContentManager::SendThumbnailToJava(
     base::android::ScopedJavaGlobalRef<jobject> j_callback,
     bool need_downsampling,
+    float aspect_ratio,
     bool result,
     const SkBitmap& bitmap) {
   ScopedJavaLocalRef<jobject> j_bitmap;
@@ -397,11 +397,6 @@
     // portrait mode, or it would be shown in the wrong aspect ratio in
     // landscape mode.
     int scale = need_downsampling ? 2 : 1;
-    double aspect_ratio = base::GetFieldTrialParamByFeatureAsDouble(
-        chrome::android::kTabGridLayoutAndroid, "thumbnail_aspect_ratio",
-        kDefaultThumbnailAspectRatio);
-    aspect_ratio = base::clamp(aspect_ratio, 0.5, 2.0);
-
     int width = std::min(bitmap.width() / scale,
                          (int)(bitmap.height() * aspect_ratio / scale));
     int height = std::min(bitmap.height() / scale,
@@ -442,11 +437,12 @@
                                  jint compression_queue_max_size,
                                  jint write_queue_max_size,
                                  jboolean use_approximation_thumbnail,
-                                 jboolean save_jpeg_thumbnails) {
+                                 jboolean save_jpeg_thumbnails,
+                                 jfloat jpeg_aspect_ratio) {
   TabContentManager* manager = new TabContentManager(
       env, obj, default_cache_size, approximation_cache_size,
       compression_queue_max_size, write_queue_max_size,
-      use_approximation_thumbnail, save_jpeg_thumbnails);
+      use_approximation_thumbnail, save_jpeg_thumbnails, jpeg_aspect_ratio);
   return reinterpret_cast<intptr_t>(manager);
 }
 
diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h
index be66ab6..d8fc5c2 100644
--- a/chrome/browser/android/compositor/tab_content_manager.h
+++ b/chrome/browser/android/compositor/tab_content_manager.h
@@ -45,7 +45,8 @@
                     jint compression_queue_max_size,
                     jint write_queue_max_size,
                     jboolean use_approximation_thumbnail,
-                    jboolean save_jpeg_thumbnails);
+                    jboolean save_jpeg_thumbnails,
+                    jfloat jpeg_aspect_ratio);
 
   TabContentManager(const TabContentManager&) = delete;
   TabContentManager& operator=(const TabContentManager&) = delete;
@@ -88,13 +89,15 @@
                         const base::android::JavaParamRef<jobject>& obj,
                         const base::android::JavaParamRef<jobject>& tab,
                         jfloat thumbnail_scale,
+                        jfloat aspect_ratio,
                         jboolean write_to_cache,
                         const base::android::JavaParamRef<jobject>& j_callback);
   void CacheTabWithBitmap(JNIEnv* env,
                           const base::android::JavaParamRef<jobject>& obj,
                           const base::android::JavaParamRef<jobject>& tab,
                           const base::android::JavaParamRef<jobject>& bitmap,
-                          jfloat thumbnail_scale);
+                          jfloat thumbnail_scale,
+                          jfloat aspect_ratio);
   void InvalidateIfChanged(JNIEnv* env,
                            const base::android::JavaParamRef<jobject>& obj,
                            jint tab_id,
@@ -112,6 +115,7 @@
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj,
       jint tab_id,
+      jfloat aspect_ratio,
       const base::android::JavaParamRef<jobject>& j_callback);
   void SetCaptureMinRequestTimeForTesting(
       JNIEnv* env,
@@ -141,11 +145,13 @@
                      base::android::ScopedJavaGlobalRef<jobject> j_callback,
                      bool write_to_cache,
                      float thumbnail_scale,
+                     float aspect_ratio,
                      const SkBitmap& bitmap);
 
   void SendThumbnailToJava(
       base::android::ScopedJavaGlobalRef<jobject> j_callback,
       bool need_downsampling,
+      float aspect_ratio,
       bool result,
       const SkBitmap& bitmap);
 
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
index 24a0ab0f..d9431e7b 100644
--- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc
+++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -290,7 +290,7 @@
 
 void AutocompleteControllerAndroid::OnSuggestionSelected(
     JNIEnv* env,
-    jint selected_index,
+    jint match_index,
     const jint j_window_open_disposition,
     const JavaParamRef<jstring>& j_current_url,
     jint j_page_classification,
@@ -303,8 +303,7 @@
   content::WebContents* web_contents =
       content::WebContents::FromJavaWebContents(j_web_contents);
 
-  const auto& match =
-      autocomplete_controller_->result().match_at(selected_index);
+  const auto& match = autocomplete_controller_->result().match_at(match_index);
   SuggestionAnswer::LogAnswerUsed(match.answer);
   TemplateURLService* template_url_service =
       TemplateURLServiceFactory::GetForProfile(profile_);
@@ -336,7 +335,7 @@
                                                        : input_.text(),
       false,                /* don't know */
       input_.type(), false, /* not keyword mode */
-      OmniboxEventProto::INVALID, true, selected_index,
+      OmniboxEventProto::INVALID, true, match_index,
       static_cast<WindowOpenDisposition>(j_window_open_disposition), false,
       sessions::SessionTabHelper::IdForTab(web_contents),
       OmniboxEventProto::PageClassification(j_page_classification),
@@ -351,21 +350,29 @@
       ->OnOmniboxOpenedUrl(log);
 }
 
-void AutocompleteControllerAndroid::DeleteSuggestion(JNIEnv* env, jint index) {
-  const auto& match = autocomplete_controller_->result().match_at(index);
+void AutocompleteControllerAndroid::DeleteMatch(JNIEnv* env, jint match_index) {
+  const auto& match = autocomplete_controller_->result().match_at(match_index);
   if (match.SupportsDeletion())
     autocomplete_controller_->DeleteMatch(match);
 }
 
+void AutocompleteControllerAndroid::DeleteMatchElement(JNIEnv* env,
+                                                       jint match_index,
+                                                       jint element_index) {
+  const auto& match = autocomplete_controller_->result().match_at(match_index);
+  if (match.SupportsDeletion())
+    autocomplete_controller_->DeleteMatchElement(match, element_index);
+}
+
 ScopedJavaLocalRef<jobject> AutocompleteControllerAndroid::
     UpdateMatchDestinationURLWithAdditionalAssistedQueryStats(
         JNIEnv* env,
-        jint selected_index,
+        jint match_index,
         jlong elapsed_time_since_input_change,
         const JavaParamRef<jstring>& jnew_query_text,
         const JavaParamRef<jobjectArray>& jnew_query_params) {
   AutocompleteMatch match(
-      autocomplete_controller_->result().match_at(selected_index));
+      autocomplete_controller_->result().match_at(match_index));
 
   if (!jnew_query_text.is_null()) {
     std::u16string query =
@@ -395,9 +402,9 @@
 
 ScopedJavaLocalRef<jobject>
 AutocompleteControllerAndroid::GetMatchingTabForSuggestion(JNIEnv* env,
-                                                           jint index) {
+                                                           jint match_index) {
   const AutocompleteMatch& match =
-      autocomplete_controller_->result().match_at(index);
+      autocomplete_controller_->result().match_at(match_index);
   return match.GetMatchingJavaTab().get(env);
 }
 
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.h b/chrome/browser/android/omnibox/autocomplete_controller_android.h
index ff61340..e150fb3 100644
--- a/chrome/browser/android/omnibox/autocomplete_controller_android.h
+++ b/chrome/browser/android/omnibox/autocomplete_controller_android.h
@@ -63,24 +63,25 @@
 
   void OnSuggestionSelected(
       JNIEnv* env,
-      jint selected_index,
+      jint match_index,
       const jint j_window_open_disposition,
       const base::android::JavaParamRef<jstring>& j_current_url,
       jint j_page_classification,
       jlong elapsed_time_since_first_modified,
       jint completed_length,
       const base::android::JavaParamRef<jobject>& j_web_contents);
-  void DeleteSuggestion(JNIEnv* env, jint selected_index);
+  void DeleteMatch(JNIEnv* env, jint match_index);
+  void DeleteMatchElement(JNIEnv* env, jint match_index, jint element_index);
   base::android::ScopedJavaLocalRef<jobject>
   UpdateMatchDestinationURLWithAdditionalAssistedQueryStats(
       JNIEnv* env,
-      jint selected_index,
+      jint match_index,
       jlong elapsed_time_since_input_change,
       const base::android::JavaParamRef<jstring>& jnew_query_text,
       const base::android::JavaParamRef<jobjectArray>& jnew_query_params);
   base::android::ScopedJavaLocalRef<jobject> GetMatchingTabForSuggestion(
       JNIEnv* env,
-      jint index);
+      jint match_index);
 
   // KeyedService:
   void Shutdown() override;
diff --git a/chrome/browser/android/signin/signin_manager_android_unittest.cc b/chrome/browser/android/signin/signin_manager_android_unittest.cc
index 89ab893..2628a7e 100644
--- a/chrome/browser/android/signin/signin_manager_android_unittest.cc
+++ b/chrome/browser/android/signin/signin_manager_android_unittest.cc
@@ -143,7 +143,7 @@
   for (const TestCase& test_case : kTestCases)
     helper->Add(url::Origin::Create(GURL(test_case.worker_url)));
 
-  ASSERT_EQ(base::size(kTestCases), helper->GetCount());
+  ASSERT_EQ(std::size(kTestCases), helper->GetCount());
 
   // Delete service workers and wait for completion.
   base::RunLoop run_loop;
diff --git a/chrome/browser/android/vr/gvr_graphics_delegate.cc b/chrome/browser/android/vr/gvr_graphics_delegate.cc
index 1e7dbc6d..256fc88 100644
--- a/chrome/browser/android/vr/gvr_graphics_delegate.cc
+++ b/chrome/browser/android/vr/gvr_graphics_delegate.cc
@@ -660,7 +660,7 @@
                                                    float* border_x,
                                                    float* border_y) {
   std::copy(kContentUvTransform,
-            kContentUvTransform + base::size(kContentUvTransform),
+            kContentUvTransform + std::size(kContentUvTransform),
             *uv_transform);
   DCHECK(!content_tex_buffer_size_.IsEmpty());
   *border_x = kContentBorderPixels / content_tex_buffer_size_.width();
@@ -676,14 +676,14 @@
     *texture_id = buffer->local_texture;
     // Use an identity UV transform, the image is already oriented correctly.
     std::copy(kWebVrIdentityUvTransform,
-              kWebVrIdentityUvTransform + base::size(kWebVrIdentityUvTransform),
+              kWebVrIdentityUvTransform + std::size(kWebVrIdentityUvTransform),
               *uv_transform);
   } else {
     *texture_id = webvr_texture_id_;
     // Apply the UV transform from the SurfaceTexture, that's usually a Y flip.
     std::copy(webvr_surface_texture_uv_transform_,
               webvr_surface_texture_uv_transform_ +
-                  base::size(webvr_surface_texture_uv_transform_),
+                  std::size(webvr_surface_texture_uv_transform_),
               *uv_transform);
   }
 }
diff --git a/chrome/browser/android/vr/register_gvr_jni.cc b/chrome/browser/android/vr/register_gvr_jni.cc
index bb6f90d..4666b51 100644
--- a/chrome/browser/android/vr/register_gvr_jni.cc
+++ b/chrome/browser/android/vr/register_gvr_jni.cc
@@ -7,8 +7,6 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
 #include "base/android/jni_utils.h"
-#include "base/cxx17_backports.h"
-
 #include "third_party/gvr-android-sdk/display_synchronizer_jni.h"
 #include "third_party/gvr-android-sdk/gvr_api_jni.h"
 #include "third_party/gvr-android-sdk/native_callbacks_jni.h"
@@ -27,7 +25,7 @@
 bool RegisterGvrJni(JNIEnv* env) {
   if (!base::android::IsSelectiveJniRegistrationEnabled(env) &&
       !RegisterNativeMethods(env, kGvrRegisteredMethods,
-                             base::size(kGvrRegisteredMethods))) {
+                             std::size(kGvrRegisteredMethods))) {
     return false;
   }
   return true;
diff --git a/chrome/browser/apps/app_shim/app_shim_manager_mac.cc b/chrome/browser/apps/app_shim/app_shim_manager_mac.cc
index 89c00bb..6574fced4 100644
--- a/chrome/browser/apps/app_shim/app_shim_manager_mac.cc
+++ b/chrome/browser/apps/app_shim/app_shim_manager_mac.cc
@@ -15,7 +15,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
@@ -237,7 +236,7 @@
   const void* app_shim_attribute_values[] = {app_shim_pid_cf};
   base::ScopedCFTypeRef<CFDictionaryRef> app_shim_attributes(CFDictionaryCreate(
       nullptr, app_shim_attribute_keys, app_shim_attribute_values,
-      base::size(app_shim_attribute_keys), &kCFTypeDictionaryKeyCallBacks,
+      std::size(app_shim_attribute_keys), &kCFTypeDictionaryKeyCallBacks,
       &kCFTypeDictionaryValueCallBacks));
   base::ScopedCFTypeRef<SecCodeRef> app_shim_code;
   OSStatus status = SecCodeCopyGuestWithAttributes(
diff --git a/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc b/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc
index 13b61dd..4df84a27 100644
--- a/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc
+++ b/chrome/browser/apps/app_shim/app_shim_manager_mac_unittest.cc
@@ -1401,13 +1401,13 @@
       {u"dock_menu_item_a_2", GURL("/settings")},
       {u"dock_menu_item_a_3", GURL("https://anothersite.com")},
   };
-  const size_t kNumMenuItemsForProfileA = base::size(menu_items_profile_a);
+  const size_t kNumMenuItemsForProfileA = std::size(menu_items_profile_a);
 
   DockMenuItems menu_items_profile_b[] = {
       {u"dock_menu_item_b_1", GURL("/about")},
       {u"dock_menu_item_b_2", GURL("/another-link")},
   };
-  const size_t kNumMenuItemsForProfileB = base::size(menu_items_profile_b);
+  const size_t kNumMenuItemsForProfileB = std::size(menu_items_profile_b);
 
   // Lambda to help with creation of application dock menu items.
   auto MakeDockMenuItems = [](DockMenuItems* menu_items,
diff --git a/chrome/browser/apps/platform_apps/api/music_manager_private/device_id.cc b/chrome/browser/apps/platform_apps/api/music_manager_private/device_id.cc
index 353b0e0..06d5c507 100644
--- a/chrome/browser/apps/platform_apps/api/music_manager_private/device_id.cc
+++ b/chrome/browser/apps/platform_apps/api/music_manager_private/device_id.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/apps/platform_apps/api/music_manager_private/device_id.h"
 
 #include <stdint.h>
+
 #include <utility>
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -166,7 +166,7 @@
     return false;
   }
 
-  for (size_t i = 0; i < base::size(invalidAddresses); ++i) {
+  for (size_t i = 0; i < std::size(invalidAddresses); ++i) {
     size_t count = invalidAddresses[i].size;
     if (memcmp(invalidAddresses[i].address, bytes, count) == 0) {
       return false;
diff --git a/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc b/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc
index 1959fd8f..e48d747 100644
--- a/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc
+++ b/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc
@@ -14,7 +14,6 @@
 #include <map>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -72,7 +71,7 @@
 
   // Look for first device name matching an entry of |kDeviceNames|.
   std::string result;
-  for (size_t i = 0; i < base::size(kDeviceNames); i++) {
+  for (size_t i = 0; i < std::size(kDeviceNames); i++) {
     DiskEntries::iterator it = disk_uuids.find(base::FilePath(kDeviceNames[i]));
     if (it != disk_uuids.end()) {
       DVLOG(1) << "Returning uuid: \"" << it->second.value()
@@ -163,7 +162,7 @@
   MacAddressProcessor processor(std::move(is_valid_mac_address));
   for (struct ifaddrs* ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
     bool keep_going = processor.ProcessInterface(
-        ifa, kNetDeviceNamePrefixes, base::size(kNetDeviceNamePrefixes));
+        ifa, kNetDeviceNamePrefixes, std::size(kNetDeviceNamePrefixes));
     if (!keep_going)
       break;
   }
diff --git a/chrome/browser/ash/DEPS b/chrome/browser/ash/DEPS
index 5036510..48f7b00 100644
--- a/chrome/browser/ash/DEPS
+++ b/chrome/browser/ash/DEPS
@@ -31,6 +31,7 @@
   "+services/network",
   "+services/tracing/public",
   "+services/viz/public/mojom",
+  "+third_party/securemessage",
 ]
 
 specific_include_rules = {
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc
index 41565507..4eee6f32 100644
--- a/chrome/browser/ash/accessibility/dictation_browsertest.cc
+++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -516,7 +516,8 @@
 #define MAYBE_UserEndsDictationWhenChromeVoxEnabled \
   DISABLED_UserEndsDictationWhenChromeVoxEnabled
 #endif
-IN_PROC_BROWSER_TEST_P(DictationTest, UserEndsDictationWhenChromeVoxEnabled) {
+IN_PROC_BROWSER_TEST_P(DictationTest,
+                       MAYBE_UserEndsDictationWhenChromeVoxEnabled) {
   AccessibilityManager* manager = GetManager();
 
   EnableChromeVox();
diff --git a/chrome/browser/ash/app_mode/app_launch_utils.cc b/chrome/browser/ash/app_mode/app_launch_utils.cc
index f90e29d..ecba29e 100644
--- a/chrome/browser/ash/app_mode/app_launch_utils.cc
+++ b/chrome/browser/ash/app_mode/app_launch_utils.cc
@@ -101,7 +101,7 @@
         user_manager::UserManager::Get()->IsLoggedInAsAnyKioskApp());
   for (size_t pref_id = 0;
        pref_id < (test_prefs_to_reset ? test_prefs_to_reset->size()
-                                      : base::size(kPrefsToReset));
+                                      : std::size(kPrefsToReset));
        pref_id++) {
     const std::string branch_path = test_prefs_to_reset
                                         ? (*test_prefs_to_reset)[pref_id]
diff --git a/chrome/browser/ash/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_app_manager_browsertest.cc
index 5294e12..73b89bf 100644
--- a/chrome/browser/ash/app_mode/kiosk_app_manager_browsertest.cc
+++ b/chrome/browser/ash/app_mode/kiosk_app_manager_browsertest.cc
@@ -13,7 +13,6 @@
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -1028,7 +1027,7 @@
       {"1234.1.1", false}, {"1234.1.3", false},
   };
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     scoped_refptr<extensions::Extension> app = MakeKioskApp(
         "App Name", "1.0", kAppId, kTestCases[i].required_platform_version);
     EXPECT_EQ(kTestCases[i].expected_compliant,
@@ -1039,7 +1038,7 @@
 
   // If an app is not auto launched with zero delay, it is always compliant.
   const char kNoneAutoLaucnhedAppId[] = "none_auto_launch_app_id";
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     scoped_refptr<extensions::Extension> app =
         MakeKioskApp("App Name", "1.0", kNoneAutoLaucnhedAppId,
                      kTestCases[i].required_platform_version);
diff --git a/chrome/browser/ash/app_restore/arc_window_handler.cc b/chrome/browser/ash/app_restore/arc_window_handler.cc
index b52ed2e4..fb0ad82 100644
--- a/chrome/browser/ash/app_restore/arc_window_handler.cc
+++ b/chrome/browser/ash/app_restore/arc_window_handler.cc
@@ -57,13 +57,7 @@
     lifetime_manager->AddObserver(this);
 }
 
-ArcWindowHandler::~ArcWindowHandler() {
-  if (exo::WMHelper::HasInstance()) {
-    auto* lifetime_manager = exo::WMHelper::GetInstance()->GetLifetimeManager();
-    if (lifetime_manager)
-      lifetime_manager->RemoveObserver(this);
-  }
-}
+ArcWindowHandler::~ArcWindowHandler() = default;
 
 void ArcWindowHandler::OnDestroyed() {
   // Destroy all ARC ghost window when Wayland server shutdown.
@@ -75,6 +69,9 @@
     CloseWindow(session_id);
 
   session_id_to_pending_window_info_.clear();
+
+  auto* lifetime_manager = exo::WMHelper::GetInstance()->GetLifetimeManager();
+  lifetime_manager->RemoveObserver(this);
 }
 
 bool ArcWindowHandler::LaunchArcGhostWindow(
diff --git a/chrome/browser/ash/arc/file_system_watcher/arc_file_system_watcher_util.cc b/chrome/browser/ash/arc/file_system_watcher/arc_file_system_watcher_util.cc
index 68bc533..f55dc18b 100644
--- a/chrome/browser/ash/arc/file_system_watcher/arc_file_system_watcher_util.cc
+++ b/chrome/browser/ash/arc/file_system_watcher/arc_file_system_watcher_util.cc
@@ -77,7 +77,7 @@
     ".xmf",    // FILE_TYPE_MID, audio/midi
 };
 const int kAndroidSupportedMediaExtensionsSize =
-    base::size(kAndroidSupportedMediaExtensions);
+    std::size(kAndroidSupportedMediaExtensions);
 
 bool AppendRelativePathForRemovableMedia(const base::FilePath& cros_path,
                                          base::FilePath* android_path) {
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.cc b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
index 01d07ea5e..6e96037 100644
--- a/chrome/browser/ash/arc/input_overlay/touch_injector.cc
+++ b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/arc/input_overlay/touch_injector.h"
 
 #include <list>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/task/thread_pool.h"
@@ -12,7 +13,9 @@
 #include "chrome/browser/ash/arc/input_overlay/actions/action_move_mouse.h"
 #include "chrome/browser/ash/arc/input_overlay/actions/action_tap_key.h"
 #include "chrome/browser/ash/arc/input_overlay/actions/action_tap_mouse.h"
+#include "chrome/browser/ash/arc/input_overlay/touch_id_manager.h"
 #include "ui/aura/window.h"
+#include "ui/events/base_event_utils.h"
 #include "ui/events/event_constants.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/widget/widget.h"
@@ -177,6 +180,26 @@
                  "touch event.";
     }
   }
+
+  // Cancel active touch-to-touch events.
+  for (auto& touch_info : rewritten_touch_infos_) {
+    auto touch_point_info = touch_info.second;
+    auto managed_touch_id = touch_point_info.rewritten_touch_id;
+    auto root_location = touch_point_info.touch_root_location;
+
+    auto touch_to_release = std::make_unique<ui::TouchEvent>(ui::TouchEvent(
+        ui::EventType::ET_TOUCH_CANCELLED, root_location, root_location,
+        ui::EventTimeForNow(),
+        ui::PointerDetails(ui::EventPointerType::kTouch, managed_touch_id)));
+    if (SendEventFinally(continuation_, &*touch_to_release)
+            .dispatcher_destroyed) {
+      VLOG(0) << "Undispatched event due to destroyed dispatcher for canceling "
+                 "stored touch event.";
+    }
+    arc::TouchIdManager::GetInstance()->ReleaseTouchID(
+        touch_info.second.rewritten_touch_id);
+  }
+  rewritten_touch_infos_.clear();
 }
 
 void TouchInjector::DispatchTouchReleaseEventOnMouseUnLock() {
@@ -204,6 +227,26 @@
                  "touch event when unlocking mouse.";
     }
   }
+
+  // Release active touch-to-touch events.
+  for (auto& touch_info : rewritten_touch_infos_) {
+    auto touch_point_info = touch_info.second;
+    auto managed_touch_id = touch_point_info.rewritten_touch_id;
+    auto root_location = touch_point_info.touch_root_location;
+
+    auto touch_to_release = std::make_unique<ui::TouchEvent>(ui::TouchEvent(
+        ui::EventType::ET_TOUCH_RELEASED, root_location, root_location,
+        ui::EventTimeForNow(),
+        ui::PointerDetails(ui::EventPointerType::kTouch, managed_touch_id)));
+    if (SendEventFinally(continuation_, &*touch_to_release)
+            .dispatcher_destroyed) {
+      VLOG(0) << "Undispatched event due to destroyed dispatcher for releasing "
+                 "stored touch event.";
+    }
+    arc::TouchIdManager::GetInstance()->ReleaseTouchID(
+        touch_info.second.rewritten_touch_id);
+  }
+  rewritten_touch_infos_.clear();
 }
 
 void TouchInjector::SendExtraEvent(
@@ -298,6 +341,24 @@
   if (!touch_injector_enable_)
     return SendEvent(continuation, &event);
 
+  if (event.IsTouchEvent()) {
+    auto* touch_event = event.AsTouchEvent();
+    auto location = touch_event->root_location();
+    target_window_->GetHost()->ConvertPixelsToDIP(&location);
+    auto location_f = gfx::PointF(location);
+    // Send touch event as it is if the event is outside of the content bounds.
+    if (!bounds.Contains(location_f))
+      return SendEvent(continuation, &event);
+
+    std::unique_ptr<ui::TouchEvent> new_touch_event =
+        RewriteOriginalTouch(touch_event);
+
+    if (new_touch_event)
+      return SendEventFinally(continuation, new_touch_event.get());
+
+    return DiscardEvent(continuation);
+  }
+
   if (mouse_lock_ && mouse_lock_->Process(event))
     return DiscardEvent(continuation);
 
@@ -340,5 +401,82 @@
   return SendEvent(continuation, &event);
 }
 
+std::unique_ptr<ui::TouchEvent> TouchInjector::RewriteOriginalTouch(
+    const ui::TouchEvent* touch_event) {
+  ui::PointerId original_id = touch_event->pointer_details().id;
+  auto it = rewritten_touch_infos_.find(original_id);
+
+  if (it == rewritten_touch_infos_.end()) {
+    DCHECK(touch_event->type() == ui::ET_TOUCH_PRESSED);
+    if (touch_event->type() != ui::ET_TOUCH_PRESSED)
+      return nullptr;
+  } else {
+    DCHECK(touch_event->type() != ui::ET_TOUCH_PRESSED);
+    if (touch_event->type() == ui::ET_TOUCH_PRESSED)
+      return nullptr;
+  }
+
+  // Confirmed the input is valid.
+  gfx::PointF root_location_f = touch_event->root_location_f();
+
+  if (touch_event->type() == ui::ET_TOUCH_PRESSED) {
+    // Generate new touch id that we can manage and add to map.
+    absl::optional<int> managed_touch_id =
+        arc::TouchIdManager::GetInstance()->ObtainTouchID();
+    DCHECK(managed_touch_id);
+    TouchPointInfo touch_point = {
+        .rewritten_touch_id = *managed_touch_id,
+        .touch_root_location = root_location_f,
+    };
+    rewritten_touch_infos_.emplace(original_id, touch_point);
+    return CreateTouchEvent(touch_event, original_id, *managed_touch_id,
+                            root_location_f);
+  } else if (touch_event->type() == ui::ET_TOUCH_RELEASED) {
+    absl::optional<int> managed_touch_id = it->second.rewritten_touch_id;
+    DCHECK(managed_touch_id);
+    rewritten_touch_infos_.erase(original_id);
+    arc::TouchIdManager::GetInstance()->ReleaseTouchID(*managed_touch_id);
+    return CreateTouchEvent(touch_event, original_id, *managed_touch_id,
+                            root_location_f);
+  }
+
+  // Update this id's stored location to this newest location.
+  it->second.touch_root_location = root_location_f;
+  absl::optional<int> managed_touch_id = it->second.rewritten_touch_id;
+  DCHECK(managed_touch_id);
+  return CreateTouchEvent(touch_event, original_id, *managed_touch_id,
+                          root_location_f);
+}
+
+std::unique_ptr<ui::TouchEvent> TouchInjector::CreateTouchEvent(
+    const ui::TouchEvent* touch_event,
+    ui::PointerId original_id,
+    int managed_touch_id,
+    gfx::PointF root_location_f) {
+  return std::make_unique<ui::TouchEvent>(ui::TouchEvent(
+      touch_event->type(), root_location_f, root_location_f,
+      touch_event->time_stamp(),
+      ui::PointerDetails(ui::EventPointerType::kTouch, managed_touch_id)));
+}
+
+int TouchInjector::GetRewrittenTouchIdForTesting(ui::PointerId original_id) {
+  auto it = rewritten_touch_infos_.find(original_id);
+  DCHECK(it != rewritten_touch_infos_.end());
+
+  return it->second.rewritten_touch_id;
+}
+
+gfx::PointF TouchInjector::GetRewrittenRootLocationForTesting(
+    ui::PointerId original_id) {
+  auto it = rewritten_touch_infos_.find(original_id);
+  DCHECK(it != rewritten_touch_infos_.end());
+
+  return it->second.touch_root_location;
+}
+
+int TouchInjector::GetRewrittenTouchInfoSizeForTesting() {
+  return rewritten_touch_infos_.size();
+}
+
 }  // namespace input_overlay
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h
index 8b5bbf3e..9e6e942 100644
--- a/chrome/browser/ash/arc/input_overlay/touch_injector.h
+++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h
@@ -86,6 +86,16 @@
       const Continuation continuation) override;
 
  private:
+  friend class TouchInjectorTest;
+
+  struct TouchPointInfo {
+    // ID managed by input overlay.
+    int rewritten_touch_id;
+
+    // The latest root location of this given touch event.
+    gfx::PointF touch_root_location;
+  };
+
   class KeyCommand;
 
   // If the window is destroying or focusing out, releasing the active touch
@@ -107,6 +117,23 @@
   bool MenuAnchorPressed(const ui::Event& event,
                          const gfx::RectF& content_bounds);
 
+  // Takes valid touch events and overrides their ids with an id managed by the
+  // TouchIdManager.
+  std::unique_ptr<ui::TouchEvent> RewriteOriginalTouch(
+      const ui::TouchEvent* touch_event);
+
+  // This method will generate a new touch event with a managed touch id.
+  std::unique_ptr<ui::TouchEvent> CreateTouchEvent(
+      const ui::TouchEvent* touch_event,
+      ui::PointerId original_id,
+      int managed_touch_id,
+      gfx::PointF root_location_f);
+
+  // For test.
+  int GetRewrittenTouchIdForTesting(ui::PointerId original_id);
+  gfx::PointF GetRewrittenRootLocationForTesting(ui::PointerId original_id);
+  int GetRewrittenTouchInfoSizeForTesting();
+
   aura::Window* target_window_;
   base::WeakPtr<ui::EventRewriterContinuation> continuation_;
   std::vector<std::unique_ptr<Action>> actions_;
@@ -129,6 +156,10 @@
   // is to save status if display overlay is destroyed during window operations.
   bool input_mapping_visible_ = true;
 
+  // Key is the original touch id.
+  // Value is a struct containing required info for this touch event.
+  base::flat_map<ui::PointerId, TouchPointInfo> rewritten_touch_infos_;
+
   base::WeakPtrFactory<TouchInjector> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector_unittest.cc b/chrome/browser/ash/arc/input_overlay/touch_injector_unittest.cc
index 7cd54872..de9089e2 100644
--- a/chrome/browser/ash/arc/input_overlay/touch_injector_unittest.cc
+++ b/chrome/browser/ash/arc/input_overlay/touch_injector_unittest.cc
@@ -214,6 +214,18 @@
     return false;
   }
 
+  int GetRewrittenTouchIdForTesting(ui::PointerId original_id) {
+    return injector_->GetRewrittenTouchIdForTesting(original_id);
+  }
+
+  gfx::PointF GetRewrittenRootLocationForTesting(ui::PointerId original_id) {
+    return injector_->GetRewrittenRootLocationForTesting(original_id);
+  }
+
+  int GetRewrittenTouchInfoSizeForTesting() {
+    return injector_->GetRewrittenTouchInfoSizeForTesting();
+  }
+
   aura::TestScreen* test_screen() {
     return aura::test::AuraTestHelper::GetInstance()->GetTestScreen();
   }
@@ -643,5 +655,132 @@
   event_capturer_.Clear();
 }
 
+TEST_F(TouchInjectorTest, TestEventRewriterTouchToTouch) {
+  // Setup.
+  base::JSONReader::ValueWithError json_value =
+      base::JSONReader::ReadAndReturnValueWithError(kValidJsonActionTapKey);
+  injector_->ParseActions(json_value.value.value());
+  injector_->RegisterEventRewriter();
+
+  // Verify initial states.
+  EXPECT_TRUE(event_capturer_.key_events().empty());
+  EXPECT_TRUE(event_capturer_.touch_events().empty());
+  EXPECT_EQ(0, (int)event_capturer_.touch_events().size());
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  // Case 1: Verify key event and touch event with matching ids will be handled
+  // correctly. Press down a keyboard key (A key) that will be converted to a
+  // touch event, then a physical touch on the screen. Both initial inputs will
+  // have the same id of 0. Then release the ids.
+
+  // First, press key A with id 0.
+  event_generator_->PressKey(ui::VKEY_A, ui::EF_NONE, 0 /* keyboard id */);
+  EXPECT_TRUE(event_capturer_.key_events().empty());
+  EXPECT_EQ(1, (int)event_capturer_.touch_events().size());
+  auto* keyEvent = event_capturer_.touch_events()[0].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_PRESSED, keyEvent->type());
+  EXPECT_EQ(0, keyEvent->pointer_details().id);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  // Second, press touch event with same id as A key.
+  event_generator_->PressTouchId(0, gfx::Point(360, 420));
+  EXPECT_EQ(2, (int)event_capturer_.touch_events().size());
+  EXPECT_EQ(1, GetRewrittenTouchInfoSizeForTesting());
+
+  // Verify id has been updated to not match the A key.
+  auto* touchEvent = event_capturer_.touch_events()[1].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_PRESSED, touchEvent->type());
+  EXPECT_NE(touchEvent->pointer_details().id, keyEvent->pointer_details().id);
+  EXPECT_EQ(1, touchEvent->pointer_details().id);
+
+  // Send release event for A key. Verify the touch id is still in our map.
+  event_generator_->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 0);
+  EXPECT_EQ(1, GetRewrittenTouchInfoSizeForTesting());
+
+  // Send release event for touch event. Verify touch id is removed from map.
+  event_generator_->ReleaseTouchId(0);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  event_capturer_.Clear();
+
+  // Case 2: Similar to Test 2, but the order of the inputs pressed are
+  // reversed. Press down a physical touch on the screen, then a a keyboard key
+  // (A key) that will be converted to a touch event. Both initial inputs will
+  // have the id of 0. Then release the ids.
+
+  // First, press touch event with id 0.
+  event_generator_->PressTouchId(0, gfx::Point(360, 420));
+  EXPECT_EQ(1, (int)event_capturer_.touch_events().size());
+  touchEvent = event_capturer_.touch_events()[0].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_PRESSED, touchEvent->type());
+  EXPECT_EQ(0, touchEvent->pointer_details().id);
+  EXPECT_EQ(1, GetRewrittenTouchInfoSizeForTesting());
+
+  // Second, press key A with same id as the physical touch event.
+  event_generator_->PressKey(ui::VKEY_A, ui::EF_NONE, 0 /* keyboard id */);
+  EXPECT_EQ(2, (int)event_capturer_.touch_events().size());
+  EXPECT_EQ(1, GetRewrittenTouchInfoSizeForTesting());
+
+  // Verify ids do not match.
+  keyEvent = event_capturer_.touch_events()[1].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_PRESSED, keyEvent->type());
+  EXPECT_EQ(1, keyEvent->pointer_details().id);
+  EXPECT_NE(touchEvent->pointer_details().id, keyEvent->pointer_details().id);
+
+  // Send release event for touch event. Verify touch id is removed from map.
+  event_generator_->ReleaseTouchId(0);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  // Send release event for A key. Verify our map is still empty.
+  event_generator_->ReleaseKey(ui::VKEY_A, ui::EF_NONE, 0);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  event_capturer_.Clear();
+
+  // Case 3: Send a touch event in a location outside of the window content
+  // bounds. This test will verify that we do not override the id that this
+  // touch event was originally assigned, which is 10 for this test.
+  event_generator_->PressTouchId(10, gfx::Point(5, 5));
+  EXPECT_EQ(1, (int)event_capturer_.touch_events().size());
+  touchEvent = event_capturer_.touch_events()[0].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_PRESSED, touchEvent->type());
+
+  // Verify the event still has id value 10 and wasn't added to our map.
+  EXPECT_EQ(10, touchEvent->pointer_details().id);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  // Send release event for touch event. Verify map still is empty.
+  event_generator_->ReleaseTouchId(10);
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  event_capturer_.Clear();
+
+  // Case 4: Verify the logic in DispatchTouchCancelEvent is correct by
+  // creating a touch and key press, then unregistering the event rewriter.
+  // This should result in touch cancel events occurring for the events.
+
+  // First, press key A.
+  event_generator_->PressKey(ui::VKEY_A, ui::EF_NONE, 0 /* keyboard id */);
+  EXPECT_TRUE(event_capturer_.key_events().empty());
+  EXPECT_EQ(1, (int)event_capturer_.touch_events().size());
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+
+  // Second, press touch event.
+  event_generator_->PressTouchId(0, gfx::Point(360, 420));
+  EXPECT_EQ(2, (int)event_capturer_.touch_events().size());
+  EXPECT_EQ(1, GetRewrittenTouchInfoSizeForTesting());
+
+  // Verify DispatchTouchCancelEvent logic through UnRegisterEventRewriter.
+  injector_->UnRegisterEventRewriter();
+
+  // Verify the existing events have generated a canceled event.
+  EXPECT_EQ(4, (int)event_capturer_.touch_events().size());
+  touchEvent = event_capturer_.touch_events()[2].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_CANCELLED, touchEvent->type());
+  touchEvent = event_capturer_.touch_events()[3].get();
+  EXPECT_EQ(ui::EventType::ET_TOUCH_CANCELLED, touchEvent->type());
+  EXPECT_EQ(0, GetRewrittenTouchInfoSizeForTesting());
+}
+
 }  // namespace input_overlay
 }  // namespace arc
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 d8a1c12..7929e0b 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
@@ -354,6 +354,12 @@
 
   // Ghost window should not trigger tracing sessions.
   DCHECK(!tracing_helper().GetTracingSession());
+
+  // ArcWindowHandler depends on WMHelper, which is supposed to be destroyed
+  // before handler is destroyed. It is deleted in
+  // ArcAppPerformanceTracingTesthelper, which happens later, so just call
+  // OnDestroyed() here.
+  handler.OnDestroyed();
 }
 
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/tracing/arc_system_stat_collector.cc b/chrome/browser/ash/arc/tracing/arc_system_stat_collector.cc
index 8e9055e..433e20f 100644
--- a/chrome/browser/ash/arc/tracing/arc_system_stat_collector.cc
+++ b/chrome/browser/ash/arc/tracing/arc_system_stat_collector.cc
@@ -669,7 +669,7 @@
        false},
   };
 
-  for (size_t i = 0; i < base::size(one_value_readers); ++i) {
+  for (size_t i = 0; i < std::size(one_value_readers); ++i) {
     if (!context->system_readers[one_value_readers[i].reader].is_valid() ||
         !ParseStatFile(
             context->system_readers[one_value_readers[i].reader].get(),
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 a31326e..97f98d7 100644
--- a/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h
+++ b/chrome/browser/ash/arc/tracing/arc_system_stat_collector.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/timer/timer.h"
@@ -107,11 +106,11 @@
 
     base::TimeTicks timestamp;
     // read, written sectors and total time in milliseconds.
-    int64_t zram_stat[base::size(kZramStatColumns) - 1] = {0};
+    int64_t zram_stat[std::size(kZramStatColumns) - 1] = {0};
     // total, available.
-    int64_t mem_info[base::size(kMemInfoColumns) - 1] = {0};
+    int64_t mem_info[std::size(kMemInfoColumns) - 1] = {0};
     // objects, used bytes.
-    int64_t gem_info[base::size(kGemInfoColumns) - 1] = {0};
+    int64_t gem_info[std::size(kGemInfoColumns) - 1] = {0};
     // Temperature of CPU, Core 0.
     int64_t cpu_temperature = std::numeric_limits<int>::min();
     // CPU Frequency.
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
index fb1d3ce..979e5d8d 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
@@ -532,7 +532,7 @@
     // Has following structure
     // InputEvent: source timestamps sequence_id|0|
     const std::string body =
-        event->GetName().substr(base::size(kInputEventPrefix) - 1);
+        event->GetName().substr(std::size(kInputEventPrefix) - 1);
     base::StringTokenizer tokenizer(body, " ");
     std::vector<std::string> tokens;
     while (tokenizer.GetNext())
@@ -1118,7 +1118,7 @@
     out_custom_events->emplace_back(
         ArcTracingGraphicsModel::BufferEventType::kCustomEvent,
         event->GetTimestamp(),
-        event->GetName().substr(base::size(kCustomTracePrefix) - 1));
+        event->GetName().substr(std::size(kCustomTracePrefix) - 1));
   }
   for (const auto& child : event->children())
     ScanForCustomEvents(child.get(), out_custom_events);
diff --git a/chrome/browser/ash/attestation/fake_certificate.cc b/chrome/browser/ash/attestation/fake_certificate.cc
index fd92b61e..df65349d 100644
--- a/chrome/browser/ash/attestation/fake_certificate.cc
+++ b/chrome/browser/ash/attestation/fake_certificate.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
 #include "base/time/time.h"
 #include "crypto/rsa_private_key.h"
 #include "net/cert/x509_certificate.h"
@@ -61,7 +60,7 @@
   }
   std::unique_ptr<crypto::RSAPrivateKey> test_key(
       crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(std::vector<uint8_t>(
-          &kTestKeyData[0], &kTestKeyData[base::size(kTestKeyData)])));
+          &kTestKeyData[0], &kTestKeyData[std::size(kTestKeyData)])));
   if (!test_key.get()) {
     return false;
   }
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
new file mode 100644
index 0000000..53e70db
--- /dev/null
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.cc
@@ -0,0 +1,470 @@
+// 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/ash/attestation/soft_bind_attestation_flow.h"
+
+#include "ash/components/cryptohome/cryptohome_parameters.h"
+#include "base/bind.h"
+#include "base/containers/span.h"
+#include "base/logging.h"
+#include "base/timer/timer.h"
+#include "chrome/browser/ash/attestation/attestation_ca_client.h"
+#include "chrome/browser/ash/settings/cros_settings.h"
+#include "chromeos/dbus/attestation/attestation_client.h"
+#include "chromeos/dbus/constants/attestation_constants.h"
+#include "content/public/browser/browser_thread.h"
+#include "crypto/openssl_util.h"
+#include "crypto/random.h"
+#include "crypto/rsa_private_key.h"
+#include "net/cert/asn1_util.h"
+#include "net/cert/pem.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
+#include "net/der/tag.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
+#include "third_party/securemessage/proto/securemessage.pb.h"
+
+namespace ash {
+namespace attestation {
+
+namespace {
+
+//  Adds a critical extension following the specification described at
+//  https://datatracker.ietf.org/doc/html/rfc5280#section-4.2 and
+//  the ASN.1 encoding defined at
+//  https://datatracker.ietf.org/doc/html/rfc5280#section-4.1:
+//  Extension  ::=  SEQUENCE  {
+//        extnID      OBJECT IDENTIFIER,
+//        critical    BOOLEAN DEFAULT FALSE,
+//        extnValue   OCTET STRING
+//                    -- contains the DER encoding of an ASN.1 value
+//                    -- corresponding to the extension type identified
+//                    -- by extnID
+//        }
+bool AddCriticalExtension(CBB* extensions,
+                          const uint8_t* ext_oid,
+                          size_t ext_oid_len,
+                          const uint8_t* ext_value,
+                          size_t ext_value_len) {
+  CBB extension, oid, value;
+  if (!CBB_add_asn1(extensions, &extension, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&oid, ext_oid, ext_oid_len) ||
+      !CBB_add_asn1_bool(&extension, 1) ||
+      !CBB_add_asn1(&extension, &value, CBS_ASN1_OCTETSTRING) ||
+      !CBB_add_bytes(&value, ext_value, ext_value_len) ||
+      !CBB_flush(extensions)) {
+    return false;
+  }
+  return true;
+}
+
+// The validity time of the leaf cert
+constexpr base::TimeDelta kLeafCertValidityWindow = base::Hours(72);
+
+// Trigger a new certificate if current certificate is nearing expiration.
+constexpr base::TimeDelta kExpiryThresholdDays = base::Days(30);
+
+// ECDSA p256 oid
+const uint8_t kEcdsa256Oid[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02};
+
+const uint8_t kBasicConstraintsOid[] = {0x55, 0x1d, 0x13};
+const uint8_t kKeyUsageOid[] = {0x55, 0x1d, 0x0f};
+// cA = FALSE
+const uint8_t kBasicConstraintsContents[] = {0x30, 0x00};
+// Tag 3 (bit string), length 2, 0 unused of 0x80 (0b10000000)
+// Bit 0 specifies the digitalSignature usage.
+const uint8_t kKeyUsageContents[] = {0x03, 0x02, 0x00, 0x80};
+
+const char kLeafCertIssuerName[] =
+    "O=Chrome Device Soft Bind,CN=Local Authority";
+const char kLeafCertSubjectName[] =
+    "O=Chrome Device Soft Bind,CN=Cryptauth User Key";
+
+// If it takes more than 30 seconds to receive a response, it's not likely
+// ever going to succeed.
+constexpr base::TimeDelta kTimeout = base::Seconds(30);
+
+}  // namespace
+
+SoftBindAttestationFlow::Session::Session(Callback callback,
+                                          AccountId account_id,
+                                          const std::string& user_key)
+    : callback_(std::move(callback)),
+      account_id_(account_id),
+      user_key_(user_key) {
+  base::RepeatingClosure timeout_callback = base::BindRepeating(
+      &SoftBindAttestationFlow::Session::OnTimeout, base::Unretained(this));
+  timer_.Start(FROM_HERE, kTimeout, std::move(timeout_callback));
+}
+
+SoftBindAttestationFlow::Session::~Session() = default;
+
+void SoftBindAttestationFlow::Session::OnTimeout() {
+  LOG(WARNING) << "Timeout exceeded";
+  ReportFailure("timeout");
+}
+
+bool SoftBindAttestationFlow::Session::IsTimerRunning() const {
+  return timer_.IsRunning();
+}
+
+void SoftBindAttestationFlow::Session::StopTimer() {
+  timer_.Stop();
+}
+
+bool SoftBindAttestationFlow::Session::ResetTimer() {
+  if (max_retries_-- > 0) {
+    timer_.Reset();
+    return true;
+  }
+  return false;
+}
+
+const AccountId& SoftBindAttestationFlow::Session::GetAccountId() const {
+  return account_id_;
+}
+
+const std::string& SoftBindAttestationFlow::Session::GetUserKey() const {
+  return user_key_;
+}
+
+void SoftBindAttestationFlow::Session::ReportFailure(
+    const std::string& error_message) {
+  std::move(callback_).Run(
+      std::vector<std::string>{"INVALID:" + error_message});
+}
+
+void SoftBindAttestationFlow::Session::ReportSuccess(
+    const std::vector<std::string>& certificate_chain) {
+  std::move(callback_).Run(certificate_chain);
+}
+
+SoftBindAttestationFlow::SoftBindAttestationFlow()
+    : attestation_client_(AttestationClient::Get()) {
+  std::unique_ptr<ServerProxy> attestation_ca_client(new AttestationCAClient());
+  attestation_flow_ = std::make_unique<AttestationFlow>(
+      std::move(attestation_ca_client), ::attestation::KEY_TYPE_ECC);
+}
+
+SoftBindAttestationFlow::~SoftBindAttestationFlow() = default;
+
+void SoftBindAttestationFlow::SetAttestationFlowForTesting(
+    std::unique_ptr<AttestationFlow> attestation_flow) {
+  attestation_flow_ = std::move(attestation_flow);
+}
+
+void SoftBindAttestationFlow::GetCertificate(Callback callback,
+                                             const AccountId& account_id,
+                                             const std::string& user_key) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!IsAttestationAllowedByPolicy()) {
+    LOG(ERROR) << "Attestation not allowed by device policy";
+    std::move(callback).Run(
+        std::vector<std::string>{"INVALID:attestationNotAllowed"});
+    return;
+  }
+  GetCertificateInternal(
+      /*force_new_key=*/false,
+      std::make_unique<Session>(std::move(callback), account_id, user_key));
+}
+
+void SoftBindAttestationFlow::GetCertificateInternal(
+    bool force_new_key,
+    std::unique_ptr<Session> session) {
+  AccountId account_id(session->GetAccountId());
+  std::string key_name(kSoftBindKey);
+  AttestationFlow::CertificateCallback certificate_callback =
+      base::BindOnce(&SoftBindAttestationFlow::OnCertificateReady,
+                     base::Unretained(this), std::move(session));
+  attestation_flow_->GetCertificate(PROFILE_SOFT_BIND_CERTIFICATE, account_id,
+                                    /*request_origin=*/std::string(),
+                                    force_new_key, key_name,
+                                    std::move(certificate_callback));
+}
+
+void SoftBindAttestationFlow::OnCertificateReady(
+    std::unique_ptr<Session> session,
+    AttestationStatus operation_status,
+    const std::string& certificate_chain) {
+  if (!session->IsTimerRunning()) {
+    LOG(WARNING) << "Certificate ready but already timed out";
+    return;
+  }
+  session->StopTimer();
+  if (operation_status != ATTESTATION_SUCCESS) {
+    LOG(ERROR) << "Attestation unsuccessful, not verified";
+    session->ReportFailure("notVerified");
+    return;
+  }
+  CertificateExpiryStatus expiry_status = CheckExpiry(certificate_chain);
+  if (expiry_status == CertificateExpiryStatus::kExpired) {
+    if (session->ResetTimer())
+      GetCertificateInternal(/*force_new_key=*/true, std::move(session));
+    else
+      session->ReportFailure("tooManyRetries");
+    return;
+  }
+  VLOG(1) << "Intermediate certificate obtained successfully";
+
+  // Construct a short-lived leaf certificate for the given user key and
+  // sign with the intermediate soft-bind attestation key. This binding of
+  // a hardware-backed attestation key (the intermediate) to a software key
+  // (the user key), is the fundamental operation of the soft-bind
+  // attestation scheme.
+
+  std::string user_key(session->GetUserKey());
+  securemessage::GenericPublicKey generic_public_key;
+  generic_public_key.ParseFromString(user_key);
+  std::string raw_x(generic_public_key.ec_p256_public_key().x());
+  bssl::UniquePtr<BIGNUM> x(BN_new());
+  BN_bin2bn(reinterpret_cast<const uint8_t*>(raw_x.data()), raw_x.size(),
+            x.get());
+  std::string raw_y(generic_public_key.ec_p256_public_key().y());
+  bssl::UniquePtr<BIGNUM> y(BN_new());
+  BN_bin2bn(reinterpret_cast<const uint8_t*>(raw_y.data()), raw_y.size(),
+            y.get());
+
+  bssl::UniquePtr<EC_GROUP> ec_group(
+      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+  bssl::UniquePtr<EC_POINT> ec_point(EC_POINT_new(ec_group.get()));
+  if (!EC_POINT_set_affine_coordinates(ec_group.get(), ec_point.get(), x.get(),
+                                       y.get(), /* ctx= */ nullptr)) {
+    LOG(ERROR) << "SoftBindAttestation: Could not set user key coordinates: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    session->ReportFailure("couldNotSetUserKeyCoordsNotOnCurve");
+    return;
+  }
+  bssl::UniquePtr<EC_KEY> ec_key(
+      EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  if (!EC_KEY_set_public_key(ec_key.get(), ec_point.get())) {
+    LOG(ERROR) << "SoftBindAttestation: Could not set user key public key: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    session->ReportFailure("couldNotSetUserKeyPublicKey");
+    return;
+  }
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
+  if (!EVP_PKEY_assign_EC_KEY(pkey.get(), ec_key.release())) {
+    LOG(ERROR) << "SoftBindAttestation: Could not assign user key pkey: "
+               << ERR_error_string(ERR_get_error(), nullptr);
+    session->ReportFailure("couldNotAssignUserKeyPkey");
+    return;
+  }
+
+  base::Time now = base::Time::Now();
+  std::string leaf_cert;
+  GenerateLeafCert(pkey.get(), now, now + kLeafCertValidityWindow, &leaf_cert);
+
+  std::string tbs_cert(leaf_cert);
+
+  ::attestation::SignRequest request;
+  request.set_username(
+      cryptohome::Identification(session->GetAccountId()).id());
+  std::string key_name(kSoftBindKey);
+  request.set_key_label(std::move(key_name));
+  request.set_data_to_sign(std::move(leaf_cert));
+  AttestationClient::Get()->Sign(
+      request,
+      base::BindOnce(&SoftBindAttestationFlow::OnCertificateSigned,
+                     base::Unretained(this), std::move(session), tbs_cert,
+                     certificate_chain,
+                     expiry_status == CertificateExpiryStatus::kExpiringSoon));
+}
+
+void SoftBindAttestationFlow::OnCertificateSigned(
+    std::unique_ptr<Session> session,
+    const std::string& tbs_cert,
+    const std::string& certificate_chain,
+    bool should_renew,
+    const ::attestation::SignReply& reply) {
+  if (reply.status() != ::attestation::STATUS_SUCCESS) {
+    LOG(ERROR) << "Could not sign attestation certificate: " << reply.status();
+    session->ReportFailure("couldNotSignCert");
+    return;
+  }
+
+  bssl::ScopedCBB cbb;
+  CBB signed_cert, signature, alg, alg_oid, alg_null;
+  uint8_t* signed_cert_bytes;
+  size_t signed_cert_len;
+  if (!CBB_init(cbb.get(), 64) ||
+      !CBB_add_asn1(cbb.get(), &signed_cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_bytes(&signed_cert,
+                     reinterpret_cast<const uint8_t*>(tbs_cert.data()),
+                     tbs_cert.size()) ||
+      !CBB_add_asn1(&signed_cert, &alg, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&alg, &alg_oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&alg_oid, kEcdsa256Oid, 8) ||
+      !CBB_add_asn1(&alg, &alg_null, CBS_ASN1_NULL) ||
+      !CBB_add_asn1(&signed_cert, &signature, CBS_ASN1_BITSTRING) ||
+      !CBB_add_u8(&signature, 0) ||
+      !CBB_add_bytes(&signature,
+                     reinterpret_cast<const uint8_t*>(reply.signature().data()),
+                     reply.signature().size()) ||
+      !CBB_flush(&signature) || !CBB_flush(&signed_cert) ||
+      !CBB_finish(cbb.get(), &signed_cert_bytes, &signed_cert_len)) {
+    LOG(ERROR) << "Could not sign attestation certificate";
+    session->ReportFailure("couldNotSignCertCbb");
+    return;
+  }
+  std::string der_encoded_cert;
+  der_encoded_cert.assign(reinterpret_cast<char*>(signed_cert_bytes),
+                          signed_cert_len);
+  bssl::UniquePtr<uint8_t> delete_signed_cert_bytes(signed_cert_bytes);
+  std::string pem_encoded_cert;
+  net::X509Certificate::GetPEMEncodedFromDER(der_encoded_cert,
+                                             &pem_encoded_cert);
+
+  std::vector<std::string> cert_chain_with_leaf = {pem_encoded_cert};
+
+  net::PEMTokenizer pem_tokenizer(certificate_chain, {"CERTIFICATE"});
+  while (pem_tokenizer.GetNext()) {
+    std::string pem_encoded_intermediate_cert;
+    net::X509Certificate::GetPEMEncodedFromDER(pem_tokenizer.data(),
+                                               &pem_encoded_intermediate_cert);
+    cert_chain_with_leaf.push_back(pem_encoded_intermediate_cert);
+  }
+
+  session->ReportSuccess(cert_chain_with_leaf);
+
+  // If certificate is close to expiry, send a new request to ensure
+  // uninterrupted continuity.
+  if (should_renew && renewals_in_progress_.count(certificate_chain) == 0) {
+    renewals_in_progress_.insert(certificate_chain);
+    AttestationFlow::CertificateCallback renew_callback = base::BindOnce(
+        &SoftBindAttestationFlow::RenewCertificateCallback,
+        weak_ptr_factory_.GetWeakPtr(), std::move(certificate_chain));
+    attestation_flow_->GetCertificate(
+        PROFILE_SOFT_BIND_CERTIFICATE, session->GetAccountId(),
+        /*request_origin=*/std::string(), /*force_new_key=*/true, kSoftBindKey,
+        std::move(renew_callback));
+  }
+}
+
+bool SoftBindAttestationFlow::IsAttestationAllowedByPolicy() const {
+  bool enabled_for_device = false;
+  if (!CrosSettings::Get()->GetBoolean(kAttestationForContentProtectionEnabled,
+                                       &enabled_for_device)) {
+    LOG(ERROR) << "Failed to get device attestation policy setting.";
+    return false;
+  }
+  if (!enabled_for_device) {
+    LOG(ERROR) << "Soft key bind attestation denied because Verified Access is "
+               << "disabled for the device.";
+    return false;
+  }
+  return true;
+}
+
+// TODO(b/185520169): create utility method for both this and content protection
+CertificateExpiryStatus SoftBindAttestationFlow::CheckExpiry(
+    const std::string& certificate_chain) {
+  int num_certificates = 0;
+  net::PEMTokenizer pem_tokenizer(certificate_chain, {"CERTIFICATE"});
+  while (pem_tokenizer.GetNext()) {
+    ++num_certificates;
+    scoped_refptr<net::X509Certificate> x509 =
+        net::X509Certificate::CreateFromBytes(
+            base::as_bytes(base::make_span(pem_tokenizer.data())));
+    if (!x509.get() || x509->valid_expiry().is_null()) {
+      // This logic intentionally fails open. In theory this should not happen
+      // but in practice parsing X.509 can be brittle and there are a lot of
+      // factors including which underlying module is parsing the certificate,
+      // whether that module performs more checks than just ASN.1/DER format,
+      // and the server module that generated the certificate(s). Renewal is
+      // expensive so we only renew certificates with good evidence that they
+      // have expired or will soon expire; if we don't know, we don't renew.
+      LOG(WARNING) << "Failed to parse certificate, cannot check expiry";
+      return CertificateExpiryStatus::kInvalidX509;
+    }
+    if (base::Time::Now() > x509->valid_expiry()) {
+      return CertificateExpiryStatus::kExpired;
+    }
+    if ((x509->valid_expiry() - base::Time::Now()) < kExpiryThresholdDays) {
+      return CertificateExpiryStatus::kExpiringSoon;
+    }
+  }
+  if (num_certificates == 0) {
+    LOG(WARNING) << "Failed to parse certificate chain, cannot check expiry";
+    return CertificateExpiryStatus::kInvalidPemChain;
+  }
+  return CertificateExpiryStatus::kValid;
+}
+
+void SoftBindAttestationFlow::RenewCertificateCallback(
+    const std::string& old_certificate_chain,
+    AttestationStatus operation_status,
+    const std::string& certificate_chain) {
+  renewals_in_progress_.erase(old_certificate_chain);
+  if (operation_status != ATTESTATION_SUCCESS) {
+    LOG(WARNING) << "Failed to renew certificate";
+    return;
+  }
+  VLOG(1) << "Certificate successfully renewed";
+}
+
+bool SoftBindAttestationFlow::GenerateLeafCert(EVP_PKEY* key,
+                                               base::Time not_valid_before,
+                                               base::Time not_valid_after,
+                                               std::string* der_encoded_cert) {
+  crypto::EnsureOpenSSLInit();
+  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+  bssl::ScopedCBB cbb;
+  CBB cert, version, validity, alg, alg_oid, alg_null;
+  uint8_t* cert_bytes;
+  size_t cert_len;
+  uint64_t serial_number;
+  crypto::RandBytes(&serial_number, sizeof(serial_number));
+  if (!CBB_init(cbb.get(), 64) ||
+      !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&cert, &version,
+                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
+      !CBB_add_asn1_uint64(&version, 2) ||
+      !CBB_add_asn1_uint64(&cert, serial_number) ||
+      !CBB_add_asn1(&cert, &alg, CBS_ASN1_SEQUENCE) ||
+      !CBB_add_asn1(&alg, &alg_oid, CBS_ASN1_OBJECT) ||
+      !CBB_add_bytes(&alg_oid, kEcdsa256Oid, 8) ||
+      !CBB_add_asn1(&alg, &alg_null, CBS_ASN1_NULL) ||
+      !net::x509_util::AddName(&cert, kLeafCertIssuerName) ||
+      !CBB_add_asn1(&cert, &validity, CBS_ASN1_SEQUENCE) ||
+      !net::x509_util::CBBAddTime(&validity, not_valid_before) ||
+      !net::x509_util::CBBAddTime(&validity, not_valid_after) ||
+      !net::x509_util::AddName(&cert, kLeafCertSubjectName) ||
+      !EVP_marshal_public_key(&cert, key)) {  // subjectPublicKeyInfo
+    return false;
+  }
+
+  CBB outer_extensions, extensions;
+  if (!CBB_add_asn1(&cert, &outer_extensions,
+                    3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
+      !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
+    return false;
+  }
+
+  if (!AddCriticalExtension(&extensions, kBasicConstraintsOid, 3,
+                            kBasicConstraintsContents, 2) ||
+      !AddCriticalExtension(&extensions, kKeyUsageOid, 3, kKeyUsageContents,
+                            4)) {
+    return false;
+  }
+
+  if (!CBB_flush(&cert)) {
+    return false;
+  }
+
+  if (!CBB_finish(cbb.get(), &cert_bytes, &cert_len))
+    return false;
+
+  der_encoded_cert->assign(reinterpret_cast<char*>(cert_bytes), cert_len);
+  bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
+
+  return true;
+}
+
+}  // namespace attestation
+}  // namespace ash
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow.h b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
new file mode 100644
index 0000000..69930cb9
--- /dev/null
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow.h
@@ -0,0 +1,110 @@
+// 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_ASH_ATTESTATION_SOFT_BIND_ATTESTATION_FLOW_H_
+#define CHROME_BROWSER_ASH_ATTESTATION_SOFT_BIND_ATTESTATION_FLOW_H_
+
+#include <string>
+
+#include "ash/components/attestation/attestation_flow.h"
+#include "base/callback.h"
+#include "base/timer/timer.h"
+#include "chrome/browser/ash/attestation/certificate_util.h"
+#include "chromeos/dbus/attestation/attestation_client.h"
+#include "components/account_id/account_id.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+namespace ash {
+namespace attestation {
+
+// Generates certificates asynchronously for soft key binding.
+class SoftBindAttestationFlow {
+ public:
+  using Callback =
+      base::OnceCallback<void(const std::vector<std::string>& cert)>;
+
+  SoftBindAttestationFlow();
+  ~SoftBindAttestationFlow();
+
+  SoftBindAttestationFlow(const SoftBindAttestationFlow&) = delete;
+  SoftBindAttestationFlow(SoftBindAttestationFlow&&) = delete;
+  SoftBindAttestationFlow& operator=(const SoftBindAttestationFlow&) = delete;
+  SoftBindAttestationFlow& operator=(SoftBindAttestationFlow&&) = delete;
+
+  // !!! WARNING !!! This API should only be called by the browser itself.
+  // Any new usage of this API should undergo security review.
+  // Must be invoked on the UI thread due to AttestationClient requirements.
+  // If the call times out before request completion, the request will
+  // continue in the background so long as this object is not freed.
+  void GetCertificate(Callback callback,
+                      const AccountId& account_id,
+                      const std::string& user_key);
+
+  void SetAttestationFlowForTesting(
+      std::unique_ptr<AttestationFlow> attestation_flow);
+
+ private:
+  // Encapsulates data necessary to construct the certificate chain. This data
+  // holder is passed along through the entire callback flow, ultimately
+  // returning the completed cert chain via its own callback.
+  class Session {
+   public:
+    Session(Callback callback,
+            AccountId account_id,
+            const std::string& user_key);
+    ~Session();
+    bool IsTimerRunning() const;
+    void StopTimer();
+    // Returns false if the maximum number of certificate fetch retries (timer
+    // resets) has been reached.
+    bool ResetTimer();
+    const AccountId& GetAccountId() const;
+    const std::string& GetUserKey() const;
+    void ReportFailure(const std::string& error_message);
+    void ReportSuccess(const std::vector<std::string>& certificate_chain);
+
+   private:
+    void OnTimeout();
+
+    Callback callback_;
+    base::RepeatingTimer timer_;
+    const AccountId account_id_;
+    std::string user_key_;
+    int max_retries_ = 3;
+  };
+
+  void GetCertificateInternal(bool force_new_key,
+                              std::unique_ptr<Session> session);
+  void OnCertificateReady(std::unique_ptr<Session> session,
+                          AttestationStatus operation_status,
+                          const std::string& certificate_chain);
+  EVP_PKEY* GetLeafCertSpki(const std::string& certificate_chain);
+  void OnCertificateSigned(std::unique_ptr<Session> session,
+                           const std::string& tbs_cert,
+                           const std::string& certificate_chain,
+                           bool should_renew,
+                           const ::attestation::SignReply& reply);
+  bool IsAttestationAllowedByPolicy() const;
+  CertificateExpiryStatus CheckExpiry(const std::string& certificate_chain);
+  EVP_PKEY* GetLeafSubjectPublicKeyInfo(const std::string& certificate_chain);
+  void RenewCertificateCallback(const std::string& old_certificate_chain,
+                                AttestationStatus operation_status,
+                                const std::string& certificate_chain);
+  // Returns true if the cert was successfully generated, and false otherwise
+  bool GenerateLeafCert(EVP_PKEY* key,
+                        base::Time not_valid_before,
+                        base::Time not_valid_after,
+                        std::string* pem_encoded_cert);
+
+  AttestationClient* const attestation_client_;
+  std::unique_ptr<AttestationFlow> attestation_flow_;
+  std::set<std::string> renewals_in_progress_;
+
+  base::WeakPtrFactory<SoftBindAttestationFlow> weak_ptr_factory_{this};
+};
+
+}  // namespace attestation
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_ATTESTATION_SOFT_BIND_ATTESTATION_FLOW_H_
diff --git a/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
new file mode 100644
index 0000000..e4a1c43e
--- /dev/null
+++ b/chrome/browser/ash/attestation/soft_bind_attestation_flow_unittest.cc
@@ -0,0 +1,267 @@
+// 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 <stddef.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "ash/components/attestation/mock_attestation_flow.h"
+#include "ash/components/settings/cros_settings_names.h"
+#include "base/bind.h"
+#include "chrome/browser/ash/attestation/fake_certificate.h"
+#include "chrome/browser/ash/attestation/soft_bind_attestation_flow.h"
+#include "chrome/browser/ash/login/users/mock_user_manager.h"
+#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
+#include "chrome/browser/profiles/profile_impl.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/dbus/attestation/attestation.pb.h"
+#include "chromeos/dbus/attestation/fake_attestation_client.h"
+#include "chromeos/dbus/attestation/interface.pb.h"
+#include "content/public/test/browser_task_environment.h"
+#include "crypto/rsa_private_key.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/boringssl/src/include/openssl/ec.h"
+#include "third_party/securemessage/proto/securemessage.pb.h"
+#include "third_party/securemessage/src/cpp/include/securemessage/crypto_ops.h"
+#include "third_party/securemessage/src/cpp/include/securemessage/public_key_proto_util.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Invoke;
+using testing::Return;
+using testing::SetArgPointee;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace ash {
+namespace attestation {
+
+namespace {
+
+const AccountId& kTestAccountId =
+    AccountId::FromUserEmail("test_email@chromium.org");
+
+}  // namespace
+
+class SoftBindAttestationFlowTest : public ::testing::Test {
+ public:
+  SoftBindAttestationFlowTest()
+      : fake_certificate_status_(ATTESTATION_SUCCESS),
+        fake_cert_chains_({}),
+        fake_cert_chain_read_index_(0),
+        result_cert_chain_({}) {
+    ::chromeos::AttestationClient::InitializeFake();
+  }
+
+  ~SoftBindAttestationFlowTest() override {
+    ::chromeos::AttestationClient::Shutdown();
+  }
+
+  void SetUp() override {
+    auto mock_attestation_flow =
+        std::make_unique<StrictMock<MockAttestationFlow>>();
+    mock_attestation_flow_ = mock_attestation_flow.get();
+    soft_bind_attestation_flow_ =
+        std::make_unique<ash::attestation::SoftBindAttestationFlow>();
+    soft_bind_attestation_flow_->SetAttestationFlowForTesting(
+        std::move(mock_attestation_flow));
+    settings_helper_.ReplaceDeviceSettingsProviderWithStub();
+    settings_helper_.SetBoolean(kAttestationForContentProtectionEnabled, true);
+  }
+
+  SoftBindAttestationFlow::Callback CreateCallback() {
+    return base::BindOnce(
+        &SoftBindAttestationFlowTest::OnAttestationCertificates,
+        base::Unretained(this));
+  }
+
+  std::string CreateUserKey() {
+    std::unique_ptr<securemessage::CryptoOps::KeyPair> key_pair =
+        securemessage::CryptoOps::GenerateEcP256KeyPair();
+    std::unique_ptr<securemessage::GenericPublicKey> generic_public_key =
+        securemessage::PublicKeyProtoUtil::EncodePublicKey(
+            *((key_pair->public_key).get()));
+    return generic_public_key->SerializeAsString();
+  }
+
+  void OnAttestationCertificates(const std::vector<std::string>& cert_chain) {
+    result_cert_chain_ = cert_chain;
+  }
+
+  void ExpectMockAttestationFlowGetCertificate() {
+    EXPECT_CALL(*mock_attestation_flow_,
+                GetCertificate(PROFILE_SOFT_BIND_CERTIFICATE, _, _, _, _, _))
+        .WillRepeatedly(WithArgs<5>(
+            Invoke(this, &SoftBindAttestationFlowTest::FakeGetCertificate)));
+  }
+
+  void ExpectMockAttestationFlowGetCertificateTimeout() {
+    EXPECT_CALL(*mock_attestation_flow_,
+                GetCertificate(PROFILE_SOFT_BIND_CERTIFICATE, _, _, _, _, _))
+        .WillRepeatedly(WithArgs<5>(Invoke(
+            this, &SoftBindAttestationFlowTest::FakeGetCertificateTimeout)));
+  }
+
+  void FakeGetCertificate(AttestationFlow::CertificateCallback callback) {
+    std::string cert = fake_cert_chain_read_index_ < fake_cert_chains_.size()
+                           ? fake_cert_chains_[fake_cert_chain_read_index_]
+                           : "";
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(std::move(callback), fake_certificate_status_, cert));
+    fake_cert_chain_read_index_++;
+  }
+
+  void FakeGetCertificateTimeout(
+      AttestationFlow::CertificateCallback callback) {
+    task_environment_.FastForwardBy(base::Seconds(35));
+  }
+
+  void SetFakeCertChain(int start_time_offset_days, int end_time_offset_days) {
+    base::Time now = base::Time::Now();
+    std::string der_encoded_cert;
+    std::string fake_cert_chain;
+    net::x509_util::CreateSelfSignedCert(
+        crypto::RSAPrivateKey::Create(1024)->key(),
+        net::x509_util::DIGEST_SHA256, "CN=test",
+        /* serial_number=*/1, now + base::Days(start_time_offset_days),
+        now + base::Days(end_time_offset_days),
+        /* extension_specs */ {}, &der_encoded_cert);
+    net::X509Certificate::GetPEMEncodedFromDER(der_encoded_cert,
+                                               &fake_cert_chain);
+    fake_cert_chains_.push_back(fake_cert_chain);
+  }
+
+ protected:
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  StrictMock<MockAttestationFlow>* mock_attestation_flow_;
+  ScopedCrosSettingsTestHelper settings_helper_;
+  std::unique_ptr<ash::attestation::SoftBindAttestationFlow>
+      soft_bind_attestation_flow_;
+
+  AttestationStatus fake_certificate_status_;
+  std::vector<std::string> fake_cert_chains_;
+  int fake_cert_chain_read_index_;
+
+  std::vector<std::string> result_cert_chain_;
+};
+
+TEST_F(SoftBindAttestationFlowTest, Success) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(0, 90);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, result_cert_chain_.size());
+}
+
+TEST_F(SoftBindAttestationFlowTest, FeatureDisabledByPolicy) {
+  settings_helper_.SetBoolean(kAttestationForContentProtectionEnabled, false);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, result_cert_chain_.size());
+  EXPECT_EQ("INVALID:attestationNotAllowed", result_cert_chain_[0]);
+}
+
+TEST_F(SoftBindAttestationFlowTest, NotVerifiedDueToUnspecifiedFailure) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(0, 90);
+  fake_certificate_status_ = ATTESTATION_UNSPECIFIED_FAILURE;
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, result_cert_chain_.size());
+  EXPECT_EQ("INVALID:notVerified", result_cert_chain_[0]);
+}
+
+TEST_F(SoftBindAttestationFlowTest, NotVerifiedDueToBadRequestFailure) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(0, 90);
+  fake_certificate_status_ = ATTESTATION_SERVER_BAD_REQUEST_FAILURE;
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, result_cert_chain_.size());
+  EXPECT_EQ("INVALID:notVerified", result_cert_chain_[0]);
+}
+
+TEST_F(SoftBindAttestationFlowTest, Timeout) {
+  ExpectMockAttestationFlowGetCertificateTimeout();
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, result_cert_chain_.size());
+  EXPECT_EQ("INVALID:timeout", result_cert_chain_[0]);
+}
+
+TEST_F(SoftBindAttestationFlowTest, NearlyExpiredCert) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(-89, 1);
+  SetFakeCertChain(0, 90);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_EQ(2, fake_cert_chain_read_index_);
+}
+
+TEST_F(SoftBindAttestationFlowTest, ExpiredCertRenewed) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(-90, 0);
+  SetFakeCertChain(0, 90);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_EQ(2, fake_cert_chain_read_index_);
+}
+
+TEST_F(SoftBindAttestationFlowTest, MultipleRenewalsExceedsMaxRetries) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(-90, 0);
+  SetFakeCertChain(-90, 0);
+  SetFakeCertChain(-90, 0);
+  SetFakeCertChain(-90, 0);
+  SetFakeCertChain(-90, 0);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, result_cert_chain_.size());
+  EXPECT_EQ("INVALID:tooManyRetries", result_cert_chain_[0]);
+  EXPECT_EQ(4, fake_cert_chain_read_index_);
+}
+
+TEST_F(SoftBindAttestationFlowTest, MultipleSuccessesSimultaneously) {
+  ExpectMockAttestationFlowGetCertificate();
+  SetFakeCertChain(0, 90);
+  SetFakeCertChain(0, 90);
+  SetFakeCertChain(0, 90);
+  const std::string user_key = CreateUserKey();
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  soft_bind_attestation_flow_->GetCertificate(CreateCallback(), kTestAccountId,
+                                              user_key);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, result_cert_chain_.size());
+  EXPECT_EQ(3, fake_cert_chain_read_index_);
+}
+
+}  // namespace attestation
+}  // namespace ash
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
index a58aaab..feb24740 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -1293,20 +1293,18 @@
     firmware_update_manager_->RequestAllUpdates();
   }
 
-  if (features::IsPciguardUiEnabled()) {
-    // The local_state pref may not be available at this stage of Chrome's
-    // lifecycle, default to false for now. The actual state will be set in a
-    // later initializer.
-    PeripheralNotificationManager::Initialize(
-        user_manager::UserManager::Get()->IsLoggedInAsGuest(),
-        /*initial_state=*/false);
-    Shell::Get()
-        ->pcie_peripheral_notification_controller()
-        ->OnPeripheralNotificationManagerInitialized();
-    Shell::Get()
-        ->usb_peripheral_notification_controller()
-        ->OnPeripheralNotificationManagerInitialized();
-  }
+  // The local_state pref may not be available at this stage of Chrome's
+  // lifecycle, default to false for now. The actual state will be set in a
+  // later initializer.
+  PeripheralNotificationManager::Initialize(
+      user_manager::UserManager::Get()->IsLoggedInAsGuest(),
+      /*initial_state=*/false);
+  Shell::Get()
+      ->pcie_peripheral_notification_controller()
+      ->OnPeripheralNotificationManagerInitialized();
+  Shell::Get()
+      ->usb_peripheral_notification_controller()
+      ->OnPeripheralNotificationManagerInitialized();
 
   crostini_unsupported_action_notifier_ =
       std::make_unique<crostini::CrostiniUnsupportedActionNotifier>();
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index 140d325..0f518de2 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -380,6 +380,10 @@
          state_ == State::CREATING_LOG_FILE || state_ == State::TERMINATING;
 }
 
+void BrowserManager::DisableAutoLaunchForTesting() {
+  disable_autolaunch_for_testing_ = true;
+}
+
 void BrowserManager::NewWindow(bool incognito,
                                bool should_trigger_session_restore) {
   if (incognito) {
@@ -709,6 +713,9 @@
   if (!browser_util::IsLacrosEnabled())
     return MaybeStartResult::kNotStarted;
 
+  if (disable_autolaunch_for_testing_)
+    return MaybeStartResult::kNotStarted;
+
   if (!browser_util::IsLacrosAllowedToLaunch()) {
     std::unique_ptr<message_center::Notification> notification =
         ash::CreateSystemNotification(
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h
index 0f6f6e8..241adcee 100644
--- a/chrome/browser/ash/crosapi/browser_manager.h
+++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -87,6 +87,10 @@
   // Returns true if Lacros is terminated.
   bool IsTerminated() const { return is_terminated_; }
 
+  // Tests will typically manually launch Lacros. As such it should not be
+  // automatically launched.
+  void DisableAutoLaunchForTesting();
+
   // Opens the browser window in lacros-chrome.
   // If lacros-chrome is not yet launched, it triggers to launch. If this is
   // called again during the setup phase of the launch process, it will be
@@ -486,6 +490,8 @@
 
   base::ObserverList<BrowserManagerObserver> observers_;
 
+  bool disable_autolaunch_for_testing_ = false;
+
   base::WeakPtrFactory<BrowserManager> weak_factory_{this};
 };
 
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index 52db3da6..2ef28ae9 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -227,7 +227,7 @@
 constexpr bool HasDuplicatedUuid() {
   // We assume the number of entries are small enough so that simple
   // O(N^2) check works.
-  const size_t size = base::size(kInterfaceVersionEntries);
+  const size_t size = std::size(kInterfaceVersionEntries);
   for (size_t i = 0; i < size; ++i) {
     for (size_t j = i + 1; j < size; ++j) {
       if (kInterfaceVersionEntries[i].uuid == kInterfaceVersionEntries[j].uuid)
diff --git a/chrome/browser/ash/crostini/crostini_terminal.cc b/chrome/browser/ash/crostini/crostini_terminal.cc
index a8276127..874d825 100644
--- a/chrome/browser/ash/crostini/crostini_terminal.cc
+++ b/chrome/browser/ash/crostini/crostini_terminal.cc
@@ -57,7 +57,7 @@
 
 namespace {
 constexpr char kSettingPrefix[] = "/hterm/profiles/default/";
-const size_t kSettingPrefixSize = base::size(kSettingPrefix) - 1;
+const size_t kSettingPrefixSize = std::size(kSettingPrefix) - 1;
 
 constexpr char kSettingBackgroundColor[] =
     "/hterm/profiles/default/background-color";
diff --git a/chrome/browser/ash/customization/customization_document_browsertest.cc b/chrome/browser/ash/customization/customization_document_browsertest.cc
index 552cd0f..2ccac9d 100644
--- a/chrome/browser/ash/customization/customization_document_browsertest.cc
+++ b/chrome/browser/ash/customization/customization_document_browsertest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ash/customization/customization_document.h"
+
 #include <stddef.h>
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/ash/base/locale_util.h"
-#include "chrome/browser/ash/customization/customization_document.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -78,7 +78,7 @@
 std::string GetExpectedLanguage(const std::string& required) {
   std::string expected = required;
 
-  for (size_t i = 0; i < base::size(locale_aliases); ++i) {
+  for (size_t i = 0; i < std::size(locale_aliases); ++i) {
     if (required != locale_aliases[i].locale_alias)
       continue;
 
diff --git a/chrome/browser/ash/drive/drivefs_native_message_host.cc b/chrome/browser/ash/drive/drivefs_native_message_host.cc
index 12bf3ad..0910091 100644
--- a/chrome/browser/ash/drive/drivefs_native_message_host.cc
+++ b/chrome/browser/ash/drive/drivefs_native_message_host.cc
@@ -6,7 +6,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -35,7 +34,7 @@
 };
 
 constexpr size_t kDriveFsNativeMessageHostOriginsSize =
-    base::size(kDriveFsNativeMessageHostOrigins);
+    std::size(kDriveFsNativeMessageHostOrigins);
 
 class DriveFsNativeMessageHost : public extensions::NativeMessageHost,
                                  public drivefs::mojom::NativeMessagingPort {
diff --git a/chrome/browser/ash/drive/file_system_util.cc b/chrome/browser/ash/drive/file_system_util.cc
index 82d7352..9465faf 100644
--- a/chrome/browser/ash/drive/file_system_util.cc
+++ b/chrome/browser/ash/drive/file_system_util.cc
@@ -55,7 +55,7 @@
     return false;
   static const base::FilePath::CharType kPrefix[] =
       FILE_PATH_LITERAL("drivefs");
-  if (components[3].compare(0, base::size(kPrefix) - 1, kPrefix) != 0)
+  if (components[3].compare(0, std::size(kPrefix) - 1, kPrefix) != 0)
     return false;
 
   return true;
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest_base.cc b/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
index 72ab5ba..c45c1a7 100644
--- a/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_jstest_base.cc
@@ -89,7 +89,7 @@
     if (url_pos != std::string::npos) {
       std::string new_path =
           "ui/webui/resources" +
-          path.substr(url_pos + base::size(kResourcesUrl) - 1);
+          path.substr(url_pos + std::size(kResourcesUrl) - 1);
       src_file_path =
           source_root_.Append(base::FilePath::FromUTF8Unsafe(new_path));
       gen_file_path =
diff --git a/chrome/browser/ash/file_manager/open_with_browser.cc b/chrome/browser/ash/file_manager/open_with_browser.cc
index eb51fd3..fe03662 100644
--- a/chrome/browser/ash/file_manager/open_with_browser.cc
+++ b/chrome/browser/ash/file_manager/open_with_browser.cc
@@ -11,7 +11,6 @@
 #include "ash/public/cpp/new_window_delegate.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/path_service.h"
 #include "base/task/post_task.h"
@@ -54,7 +53,7 @@
 
 // Returns true if |file_path| is viewable in the browser (ex. HTML file).
 bool IsViewableInBrowser(const base::FilePath& file_path) {
-  for (size_t i = 0; i < base::size(kFileExtensionsViewableInBrowser); i++) {
+  for (size_t i = 0; i < std::size(kFileExtensionsViewableInBrowser); i++) {
     if (file_path.MatchesExtension(kFileExtensionsViewableInBrowser[i]))
       return true;
   }
diff --git a/chrome/browser/ash/file_manager/path_util.cc b/chrome/browser/ash/file_manager/path_util.cc
index c2cedc3..8a07389 100644
--- a/chrome/browser/ash/file_manager/path_util.cc
+++ b/chrome/browser/ash/file_manager/path_util.cc
@@ -140,7 +140,7 @@
   if (components[1] != FILE_PATH_LITERAL("special"))
     return base::FilePath();
   static const base::FilePath::CharType kPrefix[] = FILE_PATH_LITERAL("drive");
-  if (components[2].compare(0, base::size(kPrefix) - 1, kPrefix) != 0)
+  if (components[2].compare(0, std::size(kPrefix) - 1, kPrefix) != 0)
     return base::FilePath();
 
   base::FilePath drive_path = drive::util::GetDriveGrandRootPath();
diff --git a/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc b/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc
index 8db91a8..ab69d2e9 100644
--- a/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc
+++ b/chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.cc
@@ -48,7 +48,7 @@
 
 // static
 const size_t VmSKForwardingNativeMessageHost::kOriginCount =
-    base::size(kOrigins);
+    std::size(kOrigins);
 
 // static
 std::unique_ptr<extensions::NativeMessageHost>
diff --git a/chrome/browser/ash/input_method/input_method_engine_browsertests.cc b/chrome/browser/ash/input_method/input_method_engine_browsertests.cc
index 4f8be8b5..cdce47d 100644
--- a/chrome/browser/ash/input_method/input_method_engine_browsertests.cc
+++ b/chrome/browser/ash/input_method/input_method_engine_browsertests.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -475,7 +474,7 @@
       {ui::VKEY_F10, "F10", "AudioVolumeUp"},
   };
 
-  for (size_t i = 0; i < base::size(kMediaKeyCases); ++i) {
+  for (size_t i = 0; i < std::size(kMediaKeyCases); ++i) {
     SCOPED_TRACE(std::string("KeyDown, ") + kMediaKeyCases[i].code);
     KeyEventDoneCallback callback(false);
     const std::string expected_value = base::StringPrintf(
diff --git a/chrome/browser/ash/input_method/input_method_manager_impl.cc b/chrome/browser/ash/input_method/input_method_manager_impl.cc
index 89495f6..c52f2ea2 100644
--- a/chrome/browser/ash/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/ash/input_method/input_method_manager_impl.cc
@@ -69,7 +69,7 @@
     "us(dvorak)", "us(dvp)",    "us(workman)", "us(workman-intl)",
 };
 
-const size_t kNonPositionalLayoutsLength = base::size(kNonPositionalLayouts);
+const size_t kNonPositionalLayoutsLength = std::size(kNonPositionalLayouts);
 
 enum InputMethodCategory {
   INPUT_METHOD_CATEGORY_UNKNOWN = 0,
diff --git a/chrome/browser/ash/input_method/ui/candidate_view_unittest.cc b/chrome/browser/ash/input_method/ui/candidate_view_unittest.cc
index c53ae39..85f8518b 100644
--- a/chrome/browser/ash/input_method/ui/candidate_view_unittest.cc
+++ b/chrome/browser/ash/input_method/ui/candidate_view_unittest.cc
@@ -7,7 +7,6 @@
 #include <stddef.h>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node_data.h"
@@ -53,7 +52,7 @@
     container_ = init_params.delegate->GetContentsView();
     container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
         views::BoxLayout::Orientation::kVertical));
-    for (size_t i = 0; i < base::size(kDummyCandidates); ++i) {
+    for (size_t i = 0; i < std::size(kDummyCandidates); ++i) {
       CandidateView* candidate = new CandidateView(
           views::Button::PressedCallback(), ui::CandidateWindow::VERTICAL);
       ui::CandidateWindow::Entry entry;
diff --git a/chrome/browser/ash/locale_change_guard.cc b/chrome/browser/ash/locale_change_guard.cc
index d368960..76e1fc6 100644
--- a/chrome/browser/ash/locale_change_guard.cc
+++ b/chrome/browser/ash/locale_change_guard.cc
@@ -249,7 +249,7 @@
 
 // static
 size_t LocaleChangeGuard::GetSkipShowNotificationLanguagesSizeForTesting() {
-  return base::size(kSkipShowNotificationLanguages);
+  return std::size(kSkipShowNotificationLanguages);
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc b/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc
index 69aca65..9746facc 100644
--- a/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc
+++ b/chrome/browser/ash/login/auth/cryptohome_authenticator_unittest.cc
@@ -20,7 +20,6 @@
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
@@ -114,12 +113,12 @@
 
 std::vector<uint8_t> GetOwnerPublicKey() {
   return std::vector<uint8_t>(kOwnerPublicKey,
-                              kOwnerPublicKey + base::size(kOwnerPublicKey));
+                              kOwnerPublicKey + std::size(kOwnerPublicKey));
 }
 
 bool CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
   const std::vector<uint8_t> key(
-      kOwnerPrivateKey, kOwnerPrivateKey + base::size(kOwnerPrivateKey));
+      kOwnerPrivateKey, kOwnerPrivateKey + std::size(kOwnerPrivateKey));
   return crypto::ImportNSSKeyFromPrivateKeyInfo(
              slot, key, true /* permanent */) != nullptr;
 }
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc
index f07c8b8..1e8bc0db 100644
--- a/chrome/browser/ash/login/chrome_restart_request.cc
+++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -16,7 +16,6 @@
 #include "base/base_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/memory/weak_ptr.h"
 #include "base/process/launch.h"
@@ -230,7 +229,7 @@
     wm::switches::kWindowAnimationsDisabled,
   };
   command_line->CopySwitchesFrom(base_command_line, kForwardSwitches,
-                                 base::size(kForwardSwitches));
+                                 std::size(kForwardSwitches));
 
   if (start_url.is_valid())
     command_line->AppendArg(start_url.spec());
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc
index d768a7f..7bc61dce 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_auth_attempt_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "ash/components/proximity_auth/screenlock_bridge.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "build/build_config.h"
 #include "chrome/browser/ash/login/easy_unlock/easy_unlock_key_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -37,17 +36,17 @@
 
 std::string GetSecret() {
   return std::string(reinterpret_cast<const char*>(kSecret),
-                     base::size(kSecret));
+                     std::size(kSecret));
 }
 
 std::string GetWrappedSecret() {
   return std::string(reinterpret_cast<const char*>(kWrappedSecret),
-                     base::size(kWrappedSecret));
+                     std::size(kWrappedSecret));
 }
 
 std::string GetSessionKey() {
   return std::string(reinterpret_cast<const char*>(kSessionKey),
-                     base::size(kSessionKey));
+                     std::size(kSessionKey));
 }
 
 // Fake lock handler to be used in these tests.
diff --git a/chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc b/chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
index 457a953..66044d9 100644
--- a/chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
+++ b/chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager_unittest.cc
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager.h"
+
 #include <cryptohi.h>
 
 #include <memory>
 
 #include "base/base64.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager.h"
 #include "chrome/browser/ash/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/prefs/browser_prefs.h"
@@ -423,7 +423,7 @@
   SetLocalStatePublicKey(
       test_account_id_,
       std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                  base::size(kTestPublicKey)));
+                  std::size(kTestPublicKey)));
 
   EXPECT_TRUE(user_key_manager()->PrepareTpmKey(
       /*check_private_key=*/false, base::BindOnce(&ExpectNotCalledCallback)));
@@ -431,7 +431,7 @@
   EXPECT_FALSE(user_key_manager()->GetPublicTpmKey(test_account_id_).empty());
   EXPECT_EQ(user_key_manager()->GetPublicTpmKey(test_account_id_),
             std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                        base::size(kTestPublicKey)));
+                        std::size(kTestPublicKey)));
   EXPECT_EQ(user_key_manager()->GetPublicTpmKey(test_account_id_),
             signin_key_manager()->GetPublicTpmKey(test_account_id_));
 }
@@ -442,7 +442,7 @@
   SetLocalStatePublicKey(
       test_account_id_,
       std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                  base::size(kTestPublicKey)));
+                  std::size(kTestPublicKey)));
 
   base::RunLoop run_loop;
   ASSERT_FALSE(user_key_manager()->PrepareTpmKey(true /* check_private_key */,
@@ -454,7 +454,7 @@
   EXPECT_FALSE(user_key_manager()->GetPublicTpmKey(test_account_id_).empty());
   EXPECT_NE(user_key_manager()->GetPublicTpmKey(test_account_id_),
             std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                        base::size(kTestPublicKey)));
+                        std::size(kTestPublicKey)));
   EXPECT_EQ(user_key_manager()->GetPublicTpmKey(test_account_id_),
             signin_key_manager()->GetPublicTpmKey(test_account_id_));
 }
@@ -462,11 +462,11 @@
 TEST_F(EasyUnlockTpmKeyManagerTest, PublicKeySetInPrefsCheckPrivateKey_OK) {
   ASSERT_TRUE(InitTestNssUser());
   VerifyKeyGenerationNotStartedAndFinalizeTestNssUser();
-  ASSERT_TRUE(ImportPrivateKey(kTestPrivateKey, base::size(kTestPrivateKey)));
+  ASSERT_TRUE(ImportPrivateKey(kTestPrivateKey, std::size(kTestPrivateKey)));
   SetLocalStatePublicKey(
       test_account_id_,
       std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                  base::size(kTestPublicKey)));
+                  std::size(kTestPublicKey)));
 
   int callback_count = 0;
   base::RunLoop run_loop;
@@ -483,7 +483,7 @@
   EXPECT_FALSE(user_key_manager()->GetPublicTpmKey(test_account_id_).empty());
   EXPECT_EQ(user_key_manager()->GetPublicTpmKey(test_account_id_),
             std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                        base::size(kTestPublicKey)));
+                        std::size(kTestPublicKey)));
   EXPECT_EQ(user_key_manager()->GetPublicTpmKey(test_account_id_),
             signin_key_manager()->GetPublicTpmKey(test_account_id_));
 
@@ -555,11 +555,11 @@
 TEST_F(EasyUnlockTpmKeyManagerTest, SignData) {
   ASSERT_TRUE(InitTestNssUser());
 
-  ASSERT_TRUE(ImportPrivateKey(kTestPrivateKey, base::size(kTestPrivateKey)));
+  ASSERT_TRUE(ImportPrivateKey(kTestPrivateKey, std::size(kTestPrivateKey)));
   SetLocalStatePublicKey(
       test_account_id_,
       std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                  base::size(kTestPublicKey)));
+                  std::size(kTestPublicKey)));
 
   base::RunLoop loop;
   std::string signed_data;
@@ -590,7 +590,7 @@
   SetLocalStatePublicKey(
       test_account_id_,
       std::string(reinterpret_cast<const char*>(kTestPublicKey),
-                  base::size(kTestPublicKey)));
+                  std::size(kTestPublicKey)));
 
   base::RunLoop loop;
   std::string signed_data;
diff --git a/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc b/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc
index 0d84e9bd..af67237 100644
--- a/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc
+++ b/chrome/browser/ash/login/enterprise_enrollment_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include "base/base64.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/json/string_escape.h"
 #include "base/strings/string_number_conversions.h"
@@ -560,7 +559,7 @@
       authpolicy::KerberosEncryptionTypes::ENC_TYPES_STRONG,
       std::vector<std::string>(
           kAdOrganizationalUnit,
-          kAdOrganizationalUnit + base::size(kAdOrganizationalUnit)),
+          kAdOrganizationalUnit + std::size(kAdOrganizationalUnit)),
       kAdTestUser, kDMToken);
   SubmitActiveDirectoryCredentials("machine_name", kAdMachineDomainDN,
                                    "" /* encryption_types */, kAdTestUser,
diff --git a/chrome/browser/ash/login/oobe_localization_browsertest.cc b/chrome/browser/ash/login/oobe_localization_browsertest.cc
index 7a46f03d..e9940ca 100644
--- a/chrome/browser/ash/login/oobe_localization_browsertest.cc
+++ b/chrome/browser/ash/login/oobe_localization_browsertest.cc
@@ -5,7 +5,6 @@
 #include <stddef.h>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/task/task_runner.h"
@@ -384,6 +383,6 @@
     All,
     OobeLocalizationTest,
     testing::Range(&oobe_localization_test_parameters[0],
-                   &oobe_localization_test_parameters[base::size(
+                   &oobe_localization_test_parameters[std::size(
                        oobe_localization_test_parameters)]));
 }  // namespace ash
diff --git a/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc b/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
index 6b37518..311ac9a9 100644
--- a/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
+++ b/chrome/browser/ash/login/saml/fake_saml_idp_mixin.cc
@@ -53,7 +53,7 @@
                                   'a', 'l', '\xFD', '\xFE', '\xFF'};
 
 std::string GetTpmChallenge() {
-  return std::string(kTpmChallenge, base::size(kTpmChallenge));
+  return std::string(kTpmChallenge, std::size(kTpmChallenge));
 }
 
 std::string GetTpmChallengeBase64() {
diff --git a/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc b/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
index b5f4b8f..7c55f90 100644
--- a/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
+++ b/chrome/browser/ash/login/signin/signin_error_notifier_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "build/build_config.h"
 #include "chrome/browser/ash/login/signin/signin_error_notifier_factory.h"
@@ -230,15 +229,15 @@
       {GoogleServiceAuthError::SERVICE_ERROR, true},
   };
   static_assert(
-      base::size(table) == GoogleServiceAuthError::NUM_STATES -
-                               GoogleServiceAuthError::kDeprecatedStateCount,
+      std::size(table) == GoogleServiceAuthError::NUM_STATES -
+                              GoogleServiceAuthError::kDeprecatedStateCount,
       "table size should match number of auth error types");
   CoreAccountId account_id =
       identity_test_env()
           ->MakePrimaryAccountAvailable(kTestEmail, signin::ConsentLevel::kSync)
           .account_id;
 
-  for (size_t i = 0; i < base::size(table); ++i) {
+  for (size_t i = 0; i < std::size(table); ++i) {
     SetAuthError(account_id, GoogleServiceAuthError(table[i].error_state));
     absl::optional<message_center::Notification> notification =
         display_service_->GetNotification(kPrimaryAccountErrorNotificationId);
diff --git a/chrome/browser/ash/login/users/default_user_image/default_user_images.cc b/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
index e65359d..b748f79 100644
--- a/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
+++ b/chrome/browser/ash/login/users/default_user_image/default_user_images.cc
@@ -11,7 +11,6 @@
 
 #include "ash/public/cpp/default_user_image.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -218,7 +217,7 @@
     if (info.eligibility == Eligibility::kEligible)
       num_eligible_images++;
   }
-  if (num_eligible_images != base::size(kCurrentImageIndexes))
+  if (num_eligible_images != std::size(kCurrentImageIndexes))
     return false;
 
   for (const int index : kCurrentImageIndexes) {
@@ -298,7 +297,7 @@
 
 }  // namespace
 
-const int kDefaultImagesCount = base::size(kDefaultImageInfo);
+const int kDefaultImagesCount = std::size(kDefaultImageInfo);
 
 const int kFirstDefaultImageIndex = 48;
 
@@ -385,7 +384,7 @@
 }
 
 absl::optional<DefaultImageSourceInfo> GetDefaultImageSourceInfo(size_t index) {
-  if (index >= base::size(kDefaultImageSourceInfo))
+  if (index >= std::size(kDefaultImageSourceInfo))
     return absl::nullopt;
 
   return kDefaultImageSourceInfo[index];
diff --git a/chrome/browser/ash/login/users/multi_profile_user_controller_unittest.cc b/chrome/browser/ash/login/users/multi_profile_user_controller_unittest.cc
index 7260f1f9..1805d5c 100644
--- a/chrome/browser/ash/login/users/multi_profile_user_controller_unittest.cc
+++ b/chrome/browser/ash/login/users/multi_profile_user_controller_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
@@ -122,7 +121,7 @@
       : fake_user_manager_(new FakeChromeUserManager),
         user_manager_enabler_(base::WrapUnique(fake_user_manager_)),
         user_not_allowed_count_(0) {
-    for (size_t i = 0; i < base::size(kUsers); ++i) {
+    for (size_t i = 0; i < std::size(kUsers); ++i) {
       test_users_.push_back(AccountId::FromUserEmail(kUsers[i]));
     }
   }
@@ -230,7 +229,7 @@
       MultiProfileUserController::kBehaviorPrimaryOnly,
       MultiProfileUserController::kBehaviorNotAllowed,
   };
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     SetCachedBehavior(0, kTestCases[i]);
     MultiProfileUserController::UserAllowedInSessionReason reason;
     EXPECT_TRUE(controller()->IsUserAllowedInSession(
@@ -261,7 +260,7 @@
       MultiProfileUserController::kBehaviorNotAllowed,
       MultiProfileUserController::kBehaviorUnrestricted,
   };
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     SetPrefBehavior(0, kTestCases[i]);
     EXPECT_EQ(kTestCases[i], GetCachedBehavior(0));
   }
@@ -293,7 +292,7 @@
 TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) {
   LoginUser(0);
 
-  for (size_t i = 0; i < base::size(kBehaviorTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kBehaviorTestCases); ++i) {
     SetPrefBehavior(0, kBehaviorTestCases[i].primary);
     SetCachedBehavior(1, kBehaviorTestCases[i].secondary);
     EXPECT_EQ(kBehaviorTestCases[i].expected_primary_policy,
@@ -312,7 +311,7 @@
   LoginUser(0);
   LoginUser(1);
 
-  for (size_t i = 0; i < base::size(kBehaviorTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kBehaviorTestCases); ++i) {
     SetPrefBehavior(0, MultiProfileUserController::kBehaviorUnrestricted);
     SetPrefBehavior(1, MultiProfileUserController::kBehaviorUnrestricted);
     ResetCounts();
diff --git a/chrome/browser/ash/login/version_info_updater.cc b/chrome/browser/ash/login/version_info_updater.cc
index 2d2b6ba..7e5220c 100644
--- a/chrome/browser/ash/login/version_info_updater.cc
+++ b/chrome/browser/ash/login/version_info_updater.cc
@@ -10,7 +10,6 @@
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -96,7 +95,7 @@
   // Watch for changes to the reporting flags.
   auto callback = base::BindRepeating(&VersionInfoUpdater::UpdateEnterpriseInfo,
                                       base::Unretained(this));
-  for (unsigned int i = 0; i < base::size(kReportingFlags); ++i) {
+  for (unsigned int i = 0; i < std::size(kReportingFlags); ++i) {
     subscriptions_.push_back(
         cros_settings_->AddSettingsObserver(kReportingFlags[i], callback));
   }
diff --git a/chrome/browser/ash/network_change_manager_client_unittest.cc b/chrome/browser/ash/network_change_manager_client_unittest.cc
index 50d652a..8d49723 100644
--- a/chrome/browser/ash/network_change_manager_client_unittest.cc
+++ b/chrome/browser/ash/network_change_manager_client_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_split.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/network/network_handler_test_helper.h"
@@ -96,7 +95,7 @@
       {shill::kTypeCellular, "unknown technology",
        NetworkChangeNotifier::CONNECTION_2G}};
 
-  for (size_t i = 0; i < base::size(type_mappings); ++i) {
+  for (size_t i = 0; i < std::size(type_mappings); ++i) {
     NetworkChangeNotifier::ConnectionType type =
         NetworkChangeManagerClient::ConnectionTypeFromShill(
             type_mappings[i].shill_type, type_mappings[i].technology);
@@ -393,7 +392,7 @@
      false}};
 
 TEST_F(NetworkChangeManagerClientUpdateTest, UpdateDefaultNetwork) {
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(test_cases[i].test_description);
     SetNotifierState(test_cases[i].initial_state);
     SetDefaultNetworkState(test_cases[i].default_network_state);
diff --git a/chrome/browser/ash/note_taking_helper.cc b/chrome/browser/ash/note_taking_helper.cc
index bb58307..c74a192 100644
--- a/chrome/browser/ash/note_taking_helper.cc
+++ b/chrome/browser/ash/note_taking_helper.cc
@@ -23,7 +23,6 @@
 #include "base/check.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_base.h"
@@ -528,7 +527,7 @@
   }
   allowed_app_ids_.insert(
       allowed_app_ids_.end(), kDefaultAllowedAppIds,
-      kDefaultAllowedAppIds + base::size(kDefaultAllowedAppIds));
+      kDefaultAllowedAppIds + std::size(kDefaultAllowedAppIds));
 
   // Track profiles so we can observe their app registries.
   g_browser_process->profile_manager()->AddObserver(this);
diff --git a/chrome/browser/ash/platform_keys/chaps_util_impl.cc b/chrome/browser/ash/platform_keys/chaps_util_impl.cc
index 8a01410..3cdf8b66 100644
--- a/chrome/browser/ash/platform_keys/chaps_util_impl.cc
+++ b/chrome/browser/ash/platform_keys/chaps_util_impl.cc
@@ -17,7 +17,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
 #include "chrome/browser/ash/platform_keys/chaps_slot_session.h"
@@ -109,8 +108,8 @@
           chaps_session, "GenerateKeyPair",
           base::BindRepeating(&ChapsSlotSession::GenerateKeyPair,
                               base::Unretained(chaps_session), &mechanism,
-                              pub_attributes, base::size(pub_attributes),
-                              priv_attributes, base::size(priv_attributes),
+                              pub_attributes, std::size(pub_attributes),
+                              priv_attributes, std::size(priv_attributes),
                               &(key_pair.public_key),
                               &(key_pair.private_key)))) {
     return {};
@@ -131,7 +130,7 @@
           base::BindRepeating(&ChapsSlotSession::GetAttributeValue,
                               base::Unretained(chaps_session), pub_key_handle,
                               attrs_get_modulus,
-                              base::size(attrs_get_modulus)))) {
+                              std::size(attrs_get_modulus)))) {
     return {};
   }
   return modulus;
@@ -149,7 +148,7 @@
           base::BindRepeating(&ChapsSlotSession::GetAttributeValue,
                               base::Unretained(chaps_session),
                               private_key_handle, attrs_get_key_in_software,
-                              base::size(attrs_get_key_in_software)))) {
+                              std::size(attrs_get_key_in_software)))) {
     return {};
   }
   return key_in_software;
@@ -179,7 +178,7 @@
           base::BindRepeating(&ChapsSlotSession::SetAttributeValue,
                               base::Unretained(chaps_session),
                               key_pair.private_key, attrs_set_id,
-                              base::size(attrs_set_id)))) {
+                              std::size(attrs_set_id)))) {
     return false;
   }
   if (!PerformWithRetries(
@@ -187,7 +186,7 @@
           base::BindRepeating(&ChapsSlotSession::SetAttributeValue,
                               base::Unretained(chaps_session),
                               key_pair.public_key, attrs_set_id,
-                              base::size(attrs_set_id)))) {
+                              std::size(attrs_set_id)))) {
     return false;
   }
   return true;
diff --git a/chrome/browser/ash/platform_keys/platform_keys_service_browsertest.cc b/chrome/browser/ash/platform_keys/platform_keys_service_browsertest.cc
index 165a6cc..b9527b37 100644
--- a/chrome/browser/ash/platform_keys/platform_keys_service_browsertest.cc
+++ b/chrome/browser/ash/platform_keys/platform_keys_service_browsertest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ash/platform_keys/platform_keys_service.h"
+
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -13,7 +15,6 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/containers/span.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
@@ -27,7 +28,6 @@
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/scoped_policy_update.h"
 #include "chrome/browser/ash/login/test/user_policy_mixin.h"
-#include "chrome/browser/ash/platform_keys/platform_keys_service.h"
 #include "chrome/browser/ash/platform_keys/platform_keys_service_factory.h"
 #include "chrome/browser/ash/platform_keys/platform_keys_service_test_util.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
@@ -116,7 +116,7 @@
       0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
   const base::StringPiece kDigestInfoSha256Der(
       reinterpret_cast<const char*>(kDigestInfoSha256DerData),
-      base::size(kDigestInfoSha256DerData));
+      std::size(kDigestInfoSha256DerData));
 
   return base::StrCat({kDigestInfoSha256Der, hash});
 }
diff --git a/chrome/browser/ash/policy/core/device_local_account.cc b/chrome/browser/ash/policy/core/device_local_account.cc
index 2c26b40..4aee729 100644
--- a/chrome/browser/ash/policy/core/device_local_account.cc
+++ b/chrome/browser/ash/policy/core/device_local_account.cc
@@ -11,7 +11,6 @@
 #include <utility>
 
 #include "ash/components/settings/cros_settings_names.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -149,7 +148,7 @@
     return false;
 
   const std::string domain_prefix = domain.substr(
-      0, domain.size() - base::size(kDeviceLocalAccountDomainSuffix) + 1);
+      0, domain.size() - std::size(kDeviceLocalAccountDomainSuffix) + 1);
 
   if (domain_prefix == kPublicAccountDomainPrefix) {
     if (type)
diff --git a/chrome/browser/ash/policy/core/device_local_account_browsertest.cc b/chrome/browser/ash/policy/core/device_local_account_browsertest.cc
index 33ec96b..7fbbf2c6 100644
--- a/chrome/browser/ash/policy/core/device_local_account_browsertest.cc
+++ b/chrome/browser/ash/policy/core/device_local_account_browsertest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ash/policy/core/device_local_account.h"
+
 #include <stddef.h>
 
 #include <map>
@@ -23,7 +25,6 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
@@ -71,7 +72,6 @@
 #include "chrome/browser/ash/login/users/chrome_user_manager_impl.h"
 #include "chrome/browser/ash/login/wizard_controller.h"
 #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.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/core/device_policy_cros_browser_test.h"
 #include "chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h"
@@ -977,7 +977,7 @@
       SessionStartupPref::kPrefValueURLs);
   em::StringListPolicyProto* startup_urls_proto =
       device_local_account_policy_.payload().mutable_restoreonstartupurls();
-  for (size_t i = 0; i < base::size(kStartupURLs); ++i)
+  for (size_t i = 0; i < std::size(kStartupURLs); ++i)
     startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]);
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
@@ -995,7 +995,7 @@
 
   TabStripModel* tabs = browser->tab_strip_model();
   ASSERT_TRUE(tabs);
-  int expected_tab_count = static_cast<int>(base::size(kStartupURLs));
+  int expected_tab_count = static_cast<int>(std::size(kStartupURLs));
   EXPECT_EQ(expected_tab_count, tabs->count());
   for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) {
     EXPECT_EQ(GURL(kStartupURLs[i]),
@@ -1769,7 +1769,7 @@
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, OneRecommendedLocale) {
   // Specify a recommended locale.
   SetRecommendedLocales(kSingleRecommendedLocale,
-                        base::size(kSingleRecommendedLocale));
+                        std::size(kSingleRecommendedLocale));
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
 
@@ -1795,7 +1795,7 @@
 
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MultipleRecommendedLocales) {
   // Specify recommended locales.
-  SetRecommendedLocales(kRecommendedLocales1, base::size(kRecommendedLocales1));
+  SetRecommendedLocales(kRecommendedLocales1, std::size(kRecommendedLocales1));
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
   AddPublicSessionToDevicePolicy(kAccountId2);
@@ -1808,19 +1808,19 @@
   // ones, followed by others.
   std::vector<ash::LocaleItem> locales =
       ash::LoginScreenTestApi::GetExpandedPublicSessionLocales();
-  EXPECT_LT(base::size(kRecommendedLocales1), locales.size());
+  EXPECT_LT(std::size(kRecommendedLocales1), locales.size());
 
   // Verify that the list starts with the recommended locales, in correct order.
-  for (size_t i = 0; i < base::size(kRecommendedLocales1); ++i) {
+  for (size_t i = 0; i < std::size(kRecommendedLocales1); ++i) {
     EXPECT_EQ(kRecommendedLocales1[i], locales[i].language_code);
   }
 
   // Verify that the recommended locales do not appear again in the remainder of
   // the list.
   std::set<std::string> recommended_locales;
-  for (size_t i = 0; i < base::size(kRecommendedLocales1); ++i)
+  for (size_t i = 0; i < std::size(kRecommendedLocales1); ++i)
     recommended_locales.insert(kRecommendedLocales1[i]);
-  for (size_t i = base::size(kRecommendedLocales1); i < locales.size(); ++i) {
+  for (size_t i = std::size(kRecommendedLocales1); i < locales.size(); ++i) {
     const std::string& locale = locales[i].language_code;
     EXPECT_EQ(recommended_locales.end(), recommended_locales.find(locale));
   }
@@ -1832,7 +1832,7 @@
   EXPECT_EQ(kRecommendedLocales1[0], selected_locale);
 
   // Change the list of recommended locales.
-  SetRecommendedLocales(kRecommendedLocales2, base::size(kRecommendedLocales2));
+  SetRecommendedLocales(kRecommendedLocales2, std::size(kRecommendedLocales2));
 
   UploadAndInstallDeviceLocalAccountPolicy();
   policy::BrowserPolicyConnectorAsh* connector =
@@ -1846,8 +1846,8 @@
 
   // Verify that the new list of locales is shown in the UI.
   locales = ash::LoginScreenTestApi::GetExpandedPublicSessionLocales();
-  EXPECT_LT(base::size(kRecommendedLocales2), locales.size());
-  for (size_t i = 0; i < base::size(kRecommendedLocales2); ++i) {
+  EXPECT_LT(std::size(kRecommendedLocales2), locales.size());
+  for (size_t i = 0; i < std::size(kRecommendedLocales2); ++i) {
     const std::string& locale = locales[i].language_code;
     EXPECT_EQ(kRecommendedLocales2[i], locale);
   }
@@ -1861,7 +1861,7 @@
   ash::LoginScreenTestApi::SetPublicSessionLocale(kPublicSessionLocale);
 
   // Change the list of recommended locales.
-  SetRecommendedLocales(kRecommendedLocales1, base::size(kRecommendedLocales1));
+  SetRecommendedLocales(kRecommendedLocales1, std::size(kRecommendedLocales1));
 
   UploadAndInstallDeviceLocalAccountPolicy();
   broker->core()->client()->FetchPolicy();
@@ -1925,7 +1925,7 @@
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, InvalidRecommendedLocale) {
   // Specify an invalid recommended locale.
   SetRecommendedLocales(kInvalidRecommendedLocale,
-                        base::size(kInvalidRecommendedLocale));
+                        std::size(kInvalidRecommendedLocale));
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
 
@@ -1950,7 +1950,7 @@
   // Specify a locale that has real IMEs in addition to a keyboard layout one.
   const char* const kSingleLocaleWithIME[] = {"ja"};
   RunWithRecommendedLocale(kSingleLocaleWithIME,
-                           base::size(kSingleLocaleWithIME));
+                           std::size(kSingleLocaleWithIME));
 
   EXPECT_GT(ash::input_method::InputMethodManager::Get()
                 ->GetActiveIMEState()
@@ -1962,7 +1962,7 @@
   // Specify a locale that has only keyboard layout.
   const char* const kSingleLocaleWithNoIME[] = {"de"};
   RunWithRecommendedLocale(kSingleLocaleWithNoIME,
-                           base::size(kSingleLocaleWithNoIME));
+                           std::size(kSingleLocaleWithNoIME));
 
   EXPECT_EQ(1u, ash::input_method::InputMethodManager::Get()
                     ->GetActiveIMEState()
@@ -1989,7 +1989,7 @@
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest,
                        AutoLoginWithRecommendedLocales) {
   // Specify recommended locales.
-  SetRecommendedLocales(kRecommendedLocales1, base::size(kRecommendedLocales1));
+  SetRecommendedLocales(kRecommendedLocales1, std::size(kRecommendedLocales1));
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
   EnableAutoLogin();
diff --git a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_browsertest.cc b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_browsertest.cc
index 17c276a..f54b4ef 100644
--- a/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/core/user_cloud_policy_manager_ash_browsertest.cc
@@ -9,7 +9,6 @@
 
 #include "ash/components/arc/arc_features.h"
 #include "ash/components/arc/arc_prefs.h"
-#include "base/cxx17_backports.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/test/logged_in_user_mixin.h"
@@ -120,7 +119,7 @@
 
   TabStripModel* tabs = browser->tab_strip_model();
   ASSERT_TRUE(tabs);
-  const int expected_tab_count = static_cast<int>(base::size(kStartupURLs));
+  const int expected_tab_count = static_cast<int>(std::size(kStartupURLs));
   EXPECT_EQ(expected_tab_count, tabs->count());
   for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) {
     EXPECT_EQ(GURL(kStartupURLs[i]),
diff --git a/chrome/browser/ash/policy/reporting/arc_app_install_event_log_manager_unittest.cc b/chrome/browser/ash/policy/reporting/arc_app_install_event_log_manager_unittest.cc
index 44927d97..1825bf7 100644
--- a/chrome/browser/ash/policy/reporting/arc_app_install_event_log_manager_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/arc_app_install_event_log_manager_unittest.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "ash/components/arc/arc_prefs.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_string_value_serializer.h"
@@ -202,7 +201,7 @@
 
   void AddLogEntry(int app_index) {
     ASSERT_GE(app_index, 0);
-    ASSERT_LT(app_index, static_cast<int>(base::size(kPackageNames)));
+    ASSERT_LT(app_index, static_cast<int>(std::size(kPackageNames)));
     const std::string package_name = kPackageNames[app_index];
     events_[package_name].push_back(event_);
     manager_->Add({kPackageNames[app_index]}, event_);
@@ -512,7 +511,7 @@
   FastForwardTo(offset);
   int i = 0;
   while (i <= kTotalSizeExpeditedUploadThreshold) {
-    for (int j = 0; j < static_cast<int>(base::size(kPackageNames)); ++i, ++j) {
+    for (int j = 0; j < static_cast<int>(std::size(kPackageNames)); ++i, ++j) {
       AddLogEntry(j /* app_index */);
     }
   }
@@ -548,7 +547,7 @@
   const base::TimeDelta offset = base::Minutes(20);
   FastForwardTo(offset);
   for (int i = 0; i <= kTotalSizeExpeditedUploadThreshold;
-       i += base::size(kPackageNames)) {
+       i += std::size(kPackageNames)) {
     AddLogEntryForAllApps();
   }
 
diff --git a/chrome/browser/ash/policy/reporting/extension_install_event_log_manager_unittest.cc b/chrome/browser/ash/policy/reporting/extension_install_event_log_manager_unittest.cc
index dafc8bc5..a8af25f9 100644
--- a/chrome/browser/ash/policy/reporting/extension_install_event_log_manager_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/extension_install_event_log_manager_unittest.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "ash/components/arc/arc_prefs.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_string_value_serializer.h"
@@ -198,7 +197,7 @@
 
   void AddLogEntry(int extension_index) {
     ASSERT_GE(extension_index, 0);
-    ASSERT_LT(extension_index, static_cast<int>(base::size(kExtensionIds)));
+    ASSERT_LT(extension_index, static_cast<int>(std::size(kExtensionIds)));
     const extensions::ExtensionId extension_id = kExtensionIds[extension_index];
     events_[extension_id].push_back(event_);
     manager_->Add({kExtensionIds[extension_index]}, event_);
@@ -520,7 +519,7 @@
   FastForwardTo(offset);
   int i = 0;
   while (i <= kTotalSizeExpeditedUploadThreshold) {
-    for (int j = 0; j < static_cast<int>(base::size(kExtensionIds)); ++i, ++j) {
+    for (int j = 0; j < static_cast<int>(std::size(kExtensionIds)); ++i, ++j) {
       AddLogEntry(j /* extension_index */);
     }
   }
@@ -556,7 +555,7 @@
   const base::TimeDelta offset = base::Minutes(20);
   FastForwardTo(offset);
   for (int i = 0; i <= kTotalSizeExpeditedUploadThreshold;
-       i += base::size(kExtensionIds)) {
+       i += std::size(kExtensionIds)) {
     AddLogEntryForAllExtensions();
   }
 
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index 47e8f28..5a8c6936 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -4,11 +4,10 @@
 
 #include "chrome/browser/ash/policy/status_collector/device_status_collector.h"
 
-#include <sys/types.h>
-#include <unistd.h>
-
 #include <stddef.h>
 #include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <algorithm>
 #include <cstdio>
@@ -27,7 +26,6 @@
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -2330,14 +2328,14 @@
   for (device = device_list.begin(); device != device_list.end(); ++device) {
     // Determine the type enum constant for |device|.
     size_t type_idx = 0;
-    for (; type_idx < base::size(kDeviceTypeMap); ++type_idx) {
+    for (; type_idx < std::size(kDeviceTypeMap); ++type_idx) {
       if ((*device)->type() == kDeviceTypeMap[type_idx].type_string)
         break;
     }
 
     // If the type isn't in |kDeviceTypeMap|, the interface is not relevant for
     // reporting. This filters out VPN devices.
-    if (type_idx >= base::size(kDeviceTypeMap))
+    if (type_idx >= std::size(kDeviceTypeMap))
       continue;
 
     em::NetworkInterface* interface = status->add_network_interfaces();
@@ -2422,7 +2420,7 @@
     em::NetworkState::ConnectionState connection_state_enum =
         em::NetworkState::UNKNOWN;
     const std::string connection_state_string(state->connection_state());
-    for (size_t i = 0; i < base::size(kConnectionStateMap); ++i) {
+    for (size_t i = 0; i < std::size(kConnectionStateMap); ++i) {
       if (connection_state_string == kConnectionStateMap[i].state_string) {
         connection_state_enum = kConnectionStateMap[i].state_constant;
         break;
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
index e4db415..295eb26 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -20,7 +20,6 @@
 #include "ash/components/settings/timezone_settings.h"
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -2648,7 +2647,7 @@
 
   const char* kRequiredPlatformVersions[] = {"1234", "1234.0", "1234.0.0"};
 
-  for (size_t i = 0; i < base::size(kRequiredPlatformVersions); ++i) {
+  for (size_t i = 0; i < std::size(kRequiredPlatformVersions); ++i) {
     MockAutoLaunchKioskAppWithRequiredPlatformVersion(
         fake_kiosk_device_local_account_, kRequiredPlatformVersions[i]);
 
@@ -2700,7 +2699,7 @@
       update_engine::Operation::FINALIZING,
   };
 
-  for (size_t i = 0; i < base::size(kUpdateEngineOps); ++i) {
+  for (size_t i = 0; i < std::size(kUpdateEngineOps); ++i) {
     update_status.set_current_operation(kUpdateEngineOps[i]);
     update_status.set_new_version("1235.1.2");
     update_engine_client_->PushLastStatus(update_status);
@@ -2749,7 +2748,7 @@
       update_engine::Operation::FINALIZING,
   };
 
-  for (size_t i = 0; i < base::size(kUpdateEngineOps); ++i) {
+  for (size_t i = 0; i < std::size(kUpdateEngineOps); ++i) {
     update_status.set_current_operation(kUpdateEngineOps[i]);
     update_status.set_new_version("1235.1.2");
     update_engine_client_->PushLastStatus(update_status);
@@ -2801,7 +2800,7 @@
   // change accordingly.
   const int64 kLastCheckedTimes[] = {10, 20, 30};
 
-  for (size_t i = 0; i < base::size(kLastCheckedTimes); ++i) {
+  for (size_t i = 0; i < std::size(kLastCheckedTimes); ++i) {
     update_engine::StatusResult update_status;
     update_status.set_new_version(kDefaultPlatformVersion);
     update_status.set_last_checked_time(kLastCheckedTimes[i]);
@@ -4007,7 +4006,7 @@
         false,  // visible_only,
         0,      // no limit to number of results
         &state_list);
-    ASSERT_EQ(base::size(kFakeNetworks), state_list.size());
+    ASSERT_EQ(std::size(kFakeNetworks), state_list.size());
   }
 
   void TearDown() override { DeviceStatusCollectorTest::TearDown(); }
@@ -4058,7 +4057,7 @@
             (iface->type() != em::NetworkInterface::TYPE_CELLULAR ||
              base::ranges::equal(iface->eids().begin(), iface->eids().end(),
                                  kFakeSimSlots,
-                                 kFakeSimSlots + base::size(kFakeSimSlots),
+                                 kFakeSimSlots + std::size(kFakeSimSlots),
                                  base::ranges::equal_to(), base::identity(),
                                  &FakeSimSlotInfo::eid))) {
           found_match = true;
@@ -4200,7 +4199,7 @@
     : public DeviceStatusCollectorNetworkTest {
  protected:
   void VerifyReporting() override {
-    EXPECT_EQ(base::size(kFakeNetworks),
+    EXPECT_EQ(std::size(kFakeNetworks),
               static_cast<size_t>(device_status_.network_states_size()));
     for (const FakeNetworkState& state : kFakeNetworks) {
       bool found_match = false;
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
index 97016bf..6eb1157 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector.cc
@@ -4,11 +4,10 @@
 
 #include "chrome/browser/ash/policy/status_collector/legacy_device_status_collector.h"
 
-#include <sys/types.h>
-#include <unistd.h>
-
 #include <stddef.h>
 #include <stdint.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <algorithm>
 #include <cstdio>
@@ -26,7 +25,6 @@
 #include "ash/components/settings/timezone_settings.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -2269,14 +2267,14 @@
   for (device = device_list.begin(); device != device_list.end(); ++device) {
     // Determine the type enum constant for |device|.
     size_t type_idx = 0;
-    for (; type_idx < base::size(kDeviceTypeMap); ++type_idx) {
+    for (; type_idx < std::size(kDeviceTypeMap); ++type_idx) {
       if ((*device)->type() == kDeviceTypeMap[type_idx].type_string)
         break;
     }
 
     // If the type isn't in |kDeviceTypeMap|, the interface is not relevant for
     // reporting. This filters out VPN devices.
-    if (type_idx >= base::size(kDeviceTypeMap))
+    if (type_idx >= std::size(kDeviceTypeMap))
       continue;
 
     em::NetworkInterface* interface = status->add_network_interfaces();
@@ -2314,7 +2312,7 @@
     em::NetworkState::ConnectionState connection_state_enum =
         em::NetworkState::UNKNOWN;
     const std::string connection_state_string(state->connection_state());
-    for (size_t i = 0; i < base::size(kConnectionStateMap); ++i) {
+    for (size_t i = 0; i < std::size(kConnectionStateMap); ++i) {
       if (connection_state_string == kConnectionStateMap[i].state_string) {
         connection_state_enum = kConnectionStateMap[i].state_constant;
         break;
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
index 213a5a1..7168429 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
@@ -19,7 +19,6 @@
 #include "ash/components/settings/cros_settings_names.h"
 #include "ash/components/settings/timezone_settings.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -2671,7 +2670,7 @@
 
   const char* kRequiredPlatformVersions[] = {"1234", "1234.0", "1234.0.0"};
 
-  for (size_t i = 0; i < base::size(kRequiredPlatformVersions); ++i) {
+  for (size_t i = 0; i < std::size(kRequiredPlatformVersions); ++i) {
     MockAutoLaunchKioskAppWithRequiredPlatformVersion(
         fake_kiosk_device_local_account_, kRequiredPlatformVersions[i]);
 
@@ -2721,7 +2720,7 @@
       update_engine::Operation::FINALIZING,
   };
 
-  for (size_t i = 0; i < base::size(kUpdateEngineOps); ++i) {
+  for (size_t i = 0; i < std::size(kUpdateEngineOps); ++i) {
     update_status.set_current_operation(kUpdateEngineOps[i]);
     update_status.set_new_version("1235.1.2");
     update_engine_client_->PushLastStatus(update_status);
@@ -2769,7 +2768,7 @@
       update_engine::Operation::FINALIZING,
   };
 
-  for (size_t i = 0; i < base::size(kUpdateEngineOps); ++i) {
+  for (size_t i = 0; i < std::size(kUpdateEngineOps); ++i) {
     update_status.set_current_operation(kUpdateEngineOps[i]);
     update_status.set_new_version("1235.1.2");
     update_engine_client_->PushLastStatus(update_status);
@@ -2820,7 +2819,7 @@
   // change accordingly.
   const int64 kLastCheckedTimes[] = {10, 20, 30};
 
-  for (size_t i = 0; i < base::size(kLastCheckedTimes); ++i) {
+  for (size_t i = 0; i < std::size(kLastCheckedTimes); ++i) {
     update_engine::StatusResult update_status;
     update_status.set_new_version(kDefaultPlatformVersion);
     update_status.set_last_checked_time(kLastCheckedTimes[i]);
@@ -3977,7 +3976,7 @@
         false,  // visible_only,
         0,      // no limit to number of results
         &state_list);
-    ASSERT_EQ(base::size(kFakeNetworks), state_list.size());
+    ASSERT_EQ(std::size(kFakeNetworks), state_list.size());
   }
 
   void SetReportDeviceNetworkInterfacesPolicy(bool enable) {
@@ -4094,7 +4093,7 @@
     : public LegacyDeviceStatusCollectorNetworkTest {
  protected:
   void VerifyReporting() override {
-    EXPECT_EQ(base::size(kFakeNetworks),
+    EXPECT_EQ(std::size(kFakeNetworks),
               static_cast<size_t>(device_status_.network_states_size()));
     for (const FakeNetworkState& state : kFakeNetworks) {
       bool found_match = false;
diff --git a/chrome/browser/ash/power/auto_screen_brightness/light_samples_observer_unittest.cc b/chrome/browser/ash/power/auto_screen_brightness/light_samples_observer_unittest.cc
index 1854fc7e..d573eb5 100644
--- a/chrome/browser/ash/power/auto_screen_brightness/light_samples_observer_unittest.cc
+++ b/chrome/browser/ash/power/auto_screen_brightness/light_samples_observer_unittest.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
@@ -41,7 +40,7 @@
     channels_data.push_back(std::move(illuminance_data));
 
     if (is_color_sensor) {
-      for (size_t i = 0; i < base::size(kIlluminanceColorChannels); ++i) {
+      for (size_t i = 0; i < std::size(kIlluminanceColorChannels); ++i) {
         illuminance_data.id = kIlluminanceColorChannels[i];
         illuminance_data.sample_data = kFakeColorSampleData;
         channels_data.push_back(std::move(illuminance_data));
diff --git a/chrome/browser/ash/power/power_metrics_reporter.cc b/chrome/browser/ash/power/power_metrics_reporter.cc
index 7149d44..6ddb894 100644
--- a/chrome/browser/ash/power/power_metrics_reporter.cc
+++ b/chrome/browser/ash/power/power_metrics_reporter.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ash/power/power_metrics_reporter.h"
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -84,7 +83,7 @@
 void PowerMetricsReporter::RegisterLocalStatePrefs(
     PrefRegistrySimple* registry) {
   metrics::DailyEvent::RegisterPref(registry, prefs::kPowerMetricsDailySample);
-  for (size_t i = 0; i < base::size(kDailyCounts); ++i)
+  for (size_t i = 0; i < std::size(kDailyCounts); ++i)
     registry->RegisterIntegerPref(kDailyCounts[i].pref_name, 0);
 }
 
@@ -97,7 +96,7 @@
           std::make_unique<metrics::DailyEvent>(pref_service_,
                                                 prefs::kPowerMetricsDailySample,
                                                 kDailyEventIntervalName)) {
-  for (size_t i = 0; i < base::size(kDailyCounts); ++i) {
+  for (size_t i = 0; i < std::size(kDailyCounts); ++i) {
     daily_counts_[kDailyCounts[i].pref_name] =
         pref_service_->GetInteger(kDailyCounts[i].pref_name);
   }
@@ -145,14 +144,14 @@
     metrics::DailyEvent::IntervalType type) {
   // Don't send metrics on first run or if the clock is changed.
   if (type == metrics::DailyEvent::IntervalType::DAY_ELAPSED) {
-    for (size_t i = 0; i < base::size(kDailyCounts); ++i) {
+    for (size_t i = 0; i < std::size(kDailyCounts); ++i) {
       base::UmaHistogramCounts100(kDailyCounts[i].metric_name,
                                   daily_counts_[kDailyCounts[i].pref_name]);
     }
   }
 
   // Reset all counts now that they've been reported.
-  for (size_t i = 0; i < base::size(kDailyCounts); ++i) {
+  for (size_t i = 0; i < std::size(kDailyCounts); ++i) {
     const char* pref_name = kDailyCounts[i].pref_name;
     AddToCount(pref_name, -1 * daily_counts_[pref_name]);
   }
diff --git a/chrome/browser/ash/proxy_config_service_impl_unittest.cc b/chrome/browser/ash/proxy_config_service_impl_unittest.cc
index 387c9fa7..8372025 100644
--- a/chrome/browser/ash/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/ash/proxy_config_service_impl_unittest.cc
@@ -2,15 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/network/proxy/proxy_config_service_impl.h"
-
 #include <stddef.h>
 
 #include <memory>
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/json/json_writer.h"
 #include "base/notreached.h"
@@ -25,6 +22,7 @@
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
 #include "chromeos/network/proxy/proxy_config_handler.h"
+#include "chromeos/network/proxy/proxy_config_service_impl.h"
 #include "components/onc/onc_pref_names.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/proxy_config/proxy_config_pref_names.h"
@@ -389,7 +387,7 @@
   SetUpPrivateWiFi();
   // Create a ProxyConfigServiceImpl like for the system request context.
   SetUpProxyConfigService(nullptr /* no profile prefs */);
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
                                     tests[i].description.c_str()));
 
@@ -435,7 +433,7 @@
     { 7, 6, 8, },
       // clang-format on
   };
-  for (size_t i = 0; i < base::size(proxies); ++i) {
+  for (size_t i = 0; i < std::size(proxies); ++i) {
     const TestParams& managed_params = tests[proxies[i][0]];
     const TestParams& recommended_params = tests[proxies[i][1]];
     const TestParams& network_params = tests[proxies[i][2]];
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc
index 216e2dfc..14fb519 100644
--- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc
+++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/shared_memory_mapping.h"
 #include "base/memory/weak_ptr.h"
@@ -47,7 +46,7 @@
 
 // Size of |kWilcoDtcSupportdHostOrigins| array.
 const size_t kWilcoDtcSupportdHostOriginsSize =
-    base::size(kWilcoDtcSupportdHostOrigins);
+    std::size(kWilcoDtcSupportdHostOrigins);
 
 // Native application name that is used for passing UI messages between the
 // wilco_dtc daemon and extensions.
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
index 164b2c2..c0330069 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -9,7 +9,6 @@
 #include <algorithm>
 
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -258,7 +257,7 @@
 #if !BUILDFLAG(IS_ANDROID)
   std::u16string settings(base::ASCIIToUTF16(chrome::kChromeUISettingsHost) +
                           u"/");
-  for (size_t i = 0; i < base::size(kChromeSettingsSubPages); i++) {
+  for (size_t i = 0; i < std::size(kChromeSettingsSubPages); i++) {
     builtins.push_back(settings +
                        base::ASCIIToUTF16(kChromeSettingsSubPages[i]));
   }
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index f94257b..8010e983 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/omnibox/browser/search_provider.h"
-
 #include <stddef.h>
 
 #include <memory>
@@ -11,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
@@ -42,6 +39,7 @@
 #include "components/omnibox/browser/autocomplete_provider_listener.h"
 #include "components/omnibox/browser/history_url_provider.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
+#include "components/omnibox/browser/search_provider.h"
 #include "components/omnibox/browser/suggestion_answer.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/prefs/pref_service.h"
@@ -802,7 +800,7 @@
     { "foo https://hostname/path",          true },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE("for input=" + cases[i].input);
     QueryForInput(ASCIIToUTF16(cases[i].input), false, false);
     // Make sure the default provider's suggest service was or was not queried
@@ -1183,10 +1181,10 @@
   };
 
   // Test not in keyword mode.
-  RunTest(cases, base::size(cases), false);
+  RunTest(cases, std::size(cases), false);
 
   // Test in keyword mode.  (Both modes should give the same result.)
-  RunTest(cases, base::size(cases), true);
+  RunTest(cases, std::size(cases), true);
 }
 
 // Verifies Navsuggest results don't set a TemplateURL, which Instant relies on.
@@ -1257,7 +1255,7 @@
       { "akeyword-query", "a", "k a", "adefault.com", "k adefault-query" } }
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // Send the query twice in order to have a synchronous pass after the first
     // response is received.  This is necessary because SearchProvider doesn't
     // allow an asynchronous response to change the default match.
@@ -1272,13 +1270,13 @@
         cases[i].default_provider_json + " and keyword_provider_json=" +
         cases[i].keyword_provider_json);
     const ACMatches& matches = provider_->matches();
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
     size_t j = 0;
     // Ensure that the returned matches equal the expectations.
     for (; j < matches.size(); ++j)
       EXPECT_EQ(ASCIIToUTF16(cases[i].matches[j]), matches[j].contents);
     // Ensure that no expected matches are missing.
-    for (; j < base::size(cases[i].matches); ++j)
+    for (; j < std::size(cases[i].matches); ++j)
       EXPECT_EQ(std::string(), cases[i].matches[j]);
   }
 }
@@ -1510,7 +1508,7 @@
       std::string() },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // Send the query twice in order to have a synchronous pass after the first
     // response is received.  This is necessary because SearchProvider doesn't
     // allow an asynchronous response to change the default match.
@@ -1520,7 +1518,7 @@
     }
 
     const std::string description = "for input with json=" + cases[i].json;
-    CheckMatches(description, base::size(cases[i].matches), cases[i].matches,
+    CheckMatches(description, std::size(cases[i].matches), cases[i].matches,
                  provider_->matches());
   }
 }
@@ -1952,7 +1950,7 @@
     // clang-format on
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // Send the query twice in order to have a synchronous pass after the first
     // response is received.  This is necessary because SearchProvider doesn't
     // allow an asynchronous response to change the default match.
@@ -1984,7 +1982,7 @@
     EXPECT_EQ(ASCIIToUTF16(cases[i].inline_autocompletion),
               it->inline_autocompletion);
 
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
     size_t j = 0;
     // Ensure that the returned matches equal the expectations.
     for (; j < matches.size(); ++j) {
@@ -1995,7 +1993,7 @@
                 matches[j].allowed_to_be_default_match);
     }
     // Ensure that no expected matches are missing.
-    for (; j < base::size(cases[i].matches); ++j) {
+    for (; j < std::size(cases[i].matches); ++j) {
       SCOPED_TRACE(" Case # " + base::NumberToString(i));
       EXPECT_EQ(kNotApplicable, cases[i].matches[j].contents);
     }
@@ -2198,7 +2196,7 @@
         kEmptyExpectedMatch } },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // First, send the query "a" and receive the JSON response |first_json|.
     ClearAllResults();
     QueryForInputAndWaitForFetcherResponses(u"a", false, cases[i].first_json,
@@ -2207,14 +2205,14 @@
     // Verify that the matches after the asynchronous results are as expected.
     std::string description = "first asynchronous response for input with "
         "first_json=" + cases[i].first_json;
-    CheckMatches(description, base::size(cases[i].first_async_matches),
+    CheckMatches(description, std::size(cases[i].first_async_matches),
                  cases[i].first_async_matches, provider_->matches());
 
     // Then, send the query "ab" and check the synchronous matches.
     description = "synchronous response after the first keystroke after input "
         "with first_json=" + cases[i].first_json;
     QueryForInput(u"ab", false, false);
-    CheckMatches(description, base::size(cases[i].sync_matches),
+    CheckMatches(description, std::size(cases[i].sync_matches),
                  cases[i].sync_matches, provider_->matches());
 
     // Finally, get the provided JSON response, |second_json|, and verify the
@@ -2225,7 +2223,7 @@
     test_url_loader_factory_.AddResponse("http://defaultturl2/ab",
                                          cases[i].second_json);
     RunTillProviderDone();
-    CheckMatches(description, base::size(cases[i].second_async_matches),
+    CheckMatches(description, std::size(cases[i].second_async_matches),
                  cases[i].second_async_matches, provider_->matches());
   }
 }
@@ -2257,7 +2255,7 @@
         kEmptyExpectedMatch } },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // First, send the query "1+2" and receive the JSON response |first_json|.
     ClearAllResults();
     QueryForInputAndWaitForFetcherResponses(u"1+2", false, cases[i].json,
@@ -2266,14 +2264,14 @@
     // Verify that the matches after the asynchronous results are as expected.
     std::string description = "first asynchronous response for input with "
         "json=" + cases[i].json;
-    CheckMatches(description, base::size(cases[i].async_matches),
+    CheckMatches(description, std::size(cases[i].async_matches),
                  cases[i].async_matches, provider_->matches());
 
     // Then, send the query "1+23" and check the synchronous matches.
     description = "synchronous response after the first keystroke after input "
         "with json=" + cases[i].json;
     QueryForInput(u"1+23", false, false);
-    CheckMatches(description, base::size(cases[i].sync_matches),
+    CheckMatches(description, std::size(cases[i].sync_matches),
                  cases[i].sync_matches, provider_->matches());
   }
 }
@@ -2346,7 +2344,7 @@
       { "term", "a1", "a2", "term2", "a3", "a4" } }
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     QueryForInputAndWaitForFetcherResponses(
         cases[i].input, false, cases[i].json, std::string());
 
@@ -2354,7 +2352,7 @@
     const ACMatches& matches = provider_->matches();
 
     // Ensure no extra matches are present.
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
 
     size_t j = 0;
     // Ensure that the returned matches equal the expectations.
@@ -2362,7 +2360,7 @@
       EXPECT_EQ(ASCIIToUTF16(cases[i].matches[j]),
                 matches[j].contents) << description;
     // Ensure that no expected matches are missing.
-    for (; j < base::size(cases[i].matches); ++j)
+    for (; j < std::size(cases[i].matches); ++j)
       EXPECT_EQ(kNotApplicable, cases[i].matches[j]) <<
           "Case # " << i << " " << description;
   }
@@ -2466,7 +2464,7 @@
     // clang-format on
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // Send the query twice in order to have a synchronous pass after the first
     // response is received.  This is necessary because SearchProvider doesn't
     // allow an asynchronous response to change the default match.
@@ -2478,7 +2476,7 @@
     SCOPED_TRACE("input=" + cases[i].input + " json=" + cases[i].json);
     size_t j = 0;
     const ACMatches& matches = provider_->matches();
-    ASSERT_LE(matches.size(), base::size(cases[i].output));
+    ASSERT_LE(matches.size(), std::size(cases[i].output));
     // Ensure that the returned matches equal the expectations.
     for (; j < matches.size(); ++j) {
       EXPECT_EQ(ASCIIToUTF16(cases[i].output[j].match_contents),
@@ -2488,7 +2486,7 @@
                 matches[j].allowed_to_be_default_match);
     }
     // Ensure that no expected matches are missing.
-    for (; j < base::size(cases[i].output); ++j) {
+    for (; j < std::size(cases[i].output); ++j) {
       EXPECT_EQ(kNotApplicable, cases[i].output[j].match_contents);
       EXPECT_EQ(AutocompleteMatchType::NUM_TYPES,
                 cases[i].output[j].match_type);
@@ -2778,7 +2776,7 @@
                                "c.com/path/file.htm?q=x#foo",     true, false },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     // First test regular mode.
     QueryForInput(ASCIIToUTF16(cases[i].input), false, false);
     SearchSuggestionParser::NavigationResult result(
@@ -3028,7 +3026,7 @@
       },
     },
   };
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     QueryForInputAndWaitForFetcherResponses(
         ASCIIToUTF16(cases[i].input_text), false, cases[i].response_json,
         std::string());
@@ -3038,7 +3036,7 @@
 
     SCOPED_TRACE("for input with json = " + cases[i].response_json);
 
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
     size_t j = 0;
     // Ensure that the returned matches equal the expectations.
     for (; j < matches.size(); ++j) {
@@ -3055,7 +3053,7 @@
       EXPECT_EQ(match.type, matches[j].type);
     }
     // Ensure that no expected matches are missing.
-    for (; j < base::size(cases[i].matches); ++j) {
+    for (; j < std::size(cases[i].matches); ++j) {
       SCOPED_TRACE(" and match index: " + base::NumberToString(j));
       EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable);
       EXPECT_EQ(cases[i].matches[j].description, kNotApplicable);
@@ -3152,7 +3150,7 @@
            {"b", false, AutocompleteMatchType::SEARCH_SUGGEST, true}},
       }};
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     QueryForInputAndWaitForFetcherResponses(
         ASCIIToUTF16(cases[i].input_text),
         cases[i].prefer_keyword_provider_results,
@@ -3167,7 +3165,7 @@
     ASSERT_FALSE(matches.empty());
     EXPECT_GE(matches[0].relevance, 1300);
 
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
     // Ensure that the returned matches equal the expectations.
     for (size_t j = 0; j < matches.size(); ++j) {
       SCOPED_TRACE(description);
@@ -3249,7 +3247,7 @@
     },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     ClearAllResults();
     QueryForInputAndWaitForFetcherResponses(
         ASCIIToUTF16(cases[i].input_text), false,
@@ -3261,7 +3259,7 @@
     EXPECT_GE(matches[0].relevance, 1300);
 
     SCOPED_TRACE("for case: " + base::NumberToString(i));
-    ASSERT_LE(matches.size(), base::size(cases[i].matches));
+    ASSERT_LE(matches.size(), std::size(cases[i].matches));
     size_t j = 0;
     // Ensure that the returned matches equal the expectations.
     for (; j < matches.size(); ++j) {
@@ -3270,7 +3268,7 @@
                 base::UTF16ToUTF8(matches[j].contents));
       EXPECT_EQ(cases[i].matches[j].type, matches[j].type);
     }
-    for (; j < base::size(cases[i].matches); ++j) {
+    for (; j < std::size(cases[i].matches); ++j) {
       SCOPED_TRACE("and match: " + base::NumberToString(j));
       EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable);
       EXPECT_EQ(cases[i].matches[j].type, AutocompleteMatchType::NUM_TYPES);
@@ -3357,7 +3355,7 @@
       // clang-format on
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     QueryForInputAndWaitForFetcherResponses(ASCIIToUTF16(cases[i].input_text),
                                             false, cases[i].response_json,
                                             std::string());
@@ -3778,5 +3776,5 @@
                    u"k a")}},
   };
 
-  RunTest(cases, base::size(cases), false);
+  RunTest(cases, std::size(cases), false);
 }
diff --git a/chrome/browser/autocomplete/shortcuts_provider_extension_unittest.cc b/chrome/browser/autocomplete/shortcuts_provider_extension_unittest.cc
index a1fbe86..d117658 100644
--- a/chrome/browser/autocomplete/shortcuts_provider_extension_unittest.cc
+++ b/chrome/browser/autocomplete/shortcuts_provider_extension_unittest.cc
@@ -2,14 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/omnibox/browser/shortcuts_provider.h"
-
 #include <set>
 #include <string>
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
@@ -23,6 +20,7 @@
 #include "components/omnibox/browser/autocomplete_match.h"
 #include "components/omnibox/browser/autocomplete_result.h"
 #include "components/omnibox/browser/shortcuts_backend.h"
+#include "components/omnibox/browser/shortcuts_provider.h"
 #include "components/omnibox/browser/shortcuts_provider_test_util.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/buildflags/buildflags.h"
@@ -83,7 +81,7 @@
   provider_ = new ShortcutsProvider(client_.get());
   PopulateShortcutsBackendWithTestData(client_->GetShortcutsBackend(),
                                        shortcut_test_db,
-                                       base::size(shortcut_test_db));
+                                       std::size(shortcut_test_db));
 }
 
 void ShortcutsProviderExtensionTest::TearDown() {
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc
index 0276ce3..77f4ad3d 100644
--- a/chrome/browser/autofill/android/personal_data_manager_android.cc
+++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/autofill/android/personal_data_manager_android.h"
 
 #include <stddef.h>
+
 #include <algorithm>
 #include <memory>
 #include <utility>
@@ -13,7 +14,6 @@
 #include "base/android/jni_string.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -553,7 +553,7 @@
 
   return ConvertUTF16ToJavaString(
       env, profile.ConstructInferredLabel(
-               kLabelFields, base::size(kLabelFields), base::size(kLabelFields),
+               kLabelFields, std::size(kLabelFields), std::size(kLabelFields),
                g_browser_process->GetApplicationLocale()));
 }
 
@@ -963,7 +963,7 @@
       ADDRESS_HOME_ZIP,     ADDRESS_HOME_SORTING_CODE,
       ADDRESS_HOME_COUNTRY,
   };
-  size_t kLabelFields_size = base::size(kLabelFields);
+  size_t kLabelFields_size = std::size(kLabelFields);
   if (!include_country_in_label)
     --kLabelFields_size;
 
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc
index e8eee9d..5c0e6f0 100644
--- a/chrome/browser/browser_encoding_browsertest.cc
+++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -241,7 +240,7 @@
 
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  for (size_t i = 0; i < base::size(kTestDatas); ++i) {
+  for (size_t i = 0; i < std::size(kTestDatas); ++i) {
     base::FilePath test_file_path(test_dir_path);
     test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name);
     GURL url =
diff --git a/chrome/browser/browser_keyevents_browsertest.cc b/chrome/browser/browser_keyevents_browsertest.cc
index f1827679..a000c60 100644
--- a/chrome/browser/browser_keyevents_browsertest.cc
+++ b/chrome/browser/browser_keyevents_browsertest.cc
@@ -2,16 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "build/build_config.h"
-
 #include <stddef.h>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/ui/browser.h"
@@ -361,7 +359,7 @@
   ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
 
   int tab_index = browser()->tab_strip_model()->active_index();
-  for (size_t i = 0; i < base::size(kTestNoInput); ++i) {
+  for (size_t i = 0; i < std::size(kTestNoInput); ++i) {
     EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestNoInput[i]))
         << "kTestNoInput[" << i << "] failed:\n"
         << GetTestDataDescription(kTestNoInput[i]);
@@ -369,7 +367,7 @@
 
   // Input in normal text box.
   ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
-  for (size_t i = 0; i < base::size(kTestWithInput); ++i) {
+  for (size_t i = 0; i < std::size(kTestWithInput); ++i) {
     EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
         << "kTestWithInput[" << i << "] in text box failed:\n"
         << GetTestDataDescription(kTestWithInput[i]);
@@ -378,7 +376,7 @@
 
   // Input in password box.
   ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"B"));
-  for (size_t i = 0; i < base::size(kTestWithInput); ++i) {
+  for (size_t i = 0; i < std::size(kTestWithInput); ++i) {
     EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
         << "kTestWithInput[" << i << "] in password box failed:\n"
         << GetTestDataDescription(kTestWithInput[i]);
diff --git a/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc b/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc
index 80a142e..4527d87 100644
--- a/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc
+++ b/chrome/browser/browser_switcher/alternative_browser_driver_posix.cc
@@ -93,7 +93,7 @@
   size_t start = 0;
   bool matched = false;
   while (re->Match(*arg, start, arg->size(), re2::RE2::Anchor::UNANCHORED,
-                   submatch, base::size(submatch))) {
+                   submatch, std::size(submatch))) {
     out.append(*arg, start, submatch[0].data() - (arg->data() + start));
     if (submatch[0] == kUrlVarName) {
       // Don't treat '${url}' as an environment variable, leave it as is.
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
index 9aab27e..9d9231e7 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
@@ -10,7 +10,6 @@
 #include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
@@ -73,7 +72,7 @@
   // hosts.
   PendingHosts* pending_hosts = new PendingHosts();
   base::RepeatingClosure completion = base::BarrierClosure(
-      base::size(types),
+      std::size(types),
       base::BindOnce(&BrowsingDataQuotaHelperImpl::OnGetOriginsComplete,
                      weak_factory_.GetWeakPtr(), std::move(callback),
                      base::Owned(pending_hosts)));
diff --git a/chrome/browser/browsing_data/site_data_size_collector_unittest.cc b/chrome/browser/browsing_data/site_data_size_collector_unittest.cc
index de147ce..f518e87b 100644
--- a/chrome/browser/browsing_data/site_data_size_collector_unittest.cc
+++ b/chrome/browser/browsing_data/site_data_size_collector_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
 #include "chrome/common/chrome_constants.h"
@@ -57,7 +56,7 @@
             profile_.get());
 
     base::WriteFile(profile_->GetPath().Append(chrome::kCookieFilename),
-                    kCookieFileData, base::size(kCookieFileData));
+                    kCookieFileData, std::size(kCookieFileData));
 
     fetched_size_ = -1;
   }
@@ -116,7 +115,7 @@
   mock_browsing_data_cookie_helper_->Notify();
   // Wait until reading files on blocking pool finishes.
   run_loop.Run();
-  EXPECT_EQ(static_cast<int64_t>(base::size(kCookieFileData)), fetched_size_);
+  EXPECT_EQ(static_cast<int64_t>(std::size(kCookieFileData)), fetched_size_);
 }
 
 TEST_F(SiteDataSizeCollectorTest, FetchCookieWithoutEntry) {
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 5009b62d..c20f480 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -118,6 +118,7 @@
 #include "chrome/browser/ssl/https_defaulted_callbacks.h"
 #include "chrome/browser/ssl/https_only_mode_navigation_throttle.h"
 #include "chrome/browser/ssl/https_only_mode_upgrade_interceptor.h"
+#include "chrome/browser/ssl/sct_reporting_service.h"
 #include "chrome/browser/ssl/ssl_client_auth_metrics.h"
 #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
 #include "chrome/browser/ssl/typed_navigation_upgrade_throttle.h"
@@ -1285,6 +1286,7 @@
   registry->RegisterStringPref(prefs::kIsolateOrigins, std::string());
   registry->RegisterBooleanPref(prefs::kSitePerProcess, false);
   registry->RegisterBooleanPref(prefs::kTabFreezingEnabled, true);
+  registry->RegisterIntegerPref(prefs::kSCTAuditingHashdanceReportCount, 0);
 }
 
 // static
@@ -2230,14 +2232,14 @@
       switches::kUserDataDir,  // Make logs go to the right file.
   };
   command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames,
-                                 base::size(kCommonSwitchNames));
+                                 std::size(kCommonSwitchNames));
 
   static const char* const kDinosaurEasterEggSwitches[] = {
       error_page::switches::kDisableDinosaurEasterEgg,
   };
   command_line->CopySwitchesFrom(browser_command_line,
                                  kDinosaurEasterEggSwitches,
-                                 base::size(kDinosaurEasterEggSwitches));
+                                 std::size(kDinosaurEasterEggSwitches));
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // On Chrome OS need to pass primary user homedir (in multi-profiles session).
@@ -2424,7 +2426,7 @@
     };
 
     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
   } else if (process_type == switches::kUtilityProcess) {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     static const char* const kSwitchNames[] = {
@@ -2436,7 +2438,7 @@
     };
 
     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
 #endif
     MaybeAppendSecureOriginsAllowlistSwitch(command_line);
   } else if (process_type == switches::kZygoteProcess) {
@@ -2449,13 +2451,13 @@
     };
 
     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
 #endif
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
     // Ensure zygote loads the resource bundle for the right locale.
     static const char* const kMoreSwitchNames[] = {switches::kLang};
     command_line->CopySwitchesFrom(browser_command_line, kMoreSwitchNames,
-                                   base::size(kMoreSwitchNames));
+                                   std::size(kMoreSwitchNames));
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     // This is called before feature flags are parsed, so pass them in their raw
@@ -2463,7 +2465,7 @@
     static const char* const kMoreCrOSSwitchNames[] = {
         chromeos::switches::kFeatureFlags};
     command_line->CopySwitchesFrom(browser_command_line, kMoreCrOSSwitchNames,
-                                   base::size(kMoreCrOSSwitchNames));
+                                   std::size(kMoreCrOSSwitchNames));
 #endif
   } else if (process_type == switches::kGpuProcess) {
     // If --ignore-gpu-blocklist is passed in, don't send in crash reports
@@ -2479,7 +2481,7 @@
         crash_reporter::switches::kCrashLoopBefore,
     };
     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
   }
 #endif
 
@@ -2844,6 +2846,17 @@
 }
 #endif
 
+void ChromeContentBrowserClient::CanSendSCTAuditingReport(
+    content::BrowserContext* browser_context,
+    base::OnceCallback<void(bool)> callback) {
+  std::move(callback).Run(SCTReportingService::CanSendSCTAuditingReport());
+}
+
+void ChromeContentBrowserClient::OnNewSCTAuditingReportSent(
+    content::BrowserContext* browser_context) {
+  SCTReportingService::OnNewSCTAuditingReportSent();
+}
+
 scoped_refptr<network::SharedURLLoaderFactory>
 ChromeContentBrowserClient::GetSystemSharedURLLoaderFactory() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
@@ -4566,7 +4579,7 @@
         switches::kDisableWebRtcEncryption,
     };
     to_command_line->CopySwitchesFrom(from_command_line, kWebRtcDevSwitchNames,
-                                      base::size(kWebRtcDevSwitchNames));
+                                      std::size(kWebRtcDevSwitchNames));
   }
 }
 
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 00f0c03..e9b32f7 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -33,7 +33,6 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "ppapi/buildflags/buildflags.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
-#include "services/network/public/mojom/network_context.mojom-forward.h"
 
 class ChromeContentBrowserClientParts;
 class PrefRegistrySimple;
@@ -305,6 +304,11 @@
 #if BUILDFLAG(IS_CHROMEOS)
   void OnTrustAnchorUsed(content::BrowserContext* browser_context) override;
 #endif
+  void CanSendSCTAuditingReport(
+      content::BrowserContext* browser_context,
+      base::OnceCallback<void(bool)> callback) override;
+  void OnNewSCTAuditingReportSent(
+      content::BrowserContext* browser_context) override;
   scoped_refptr<network::SharedURLLoaderFactory>
   GetSystemSharedURLLoaderFactory() override;
   network::mojom::NetworkContext* GetSystemNetworkContext() override;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 3743c2bb..0e5e2f8 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1092,6 +1092,8 @@
     "../ash/attestation/machine_certificate_uploader_impl.h",
     "../ash/attestation/platform_verification_flow.cc",
     "../ash/attestation/platform_verification_flow.h",
+    "../ash/attestation/soft_bind_attestation_flow.cc",
+    "../ash/attestation/soft_bind_attestation_flow.h",
     "../ash/attestation/tpm_challenge_key.cc",
     "../ash/attestation/tpm_challenge_key.h",
     "../ash/attestation/tpm_challenge_key_result.cc",
@@ -4116,6 +4118,7 @@
     "../ash/attestation/fake_certificate.h",
     "../ash/attestation/machine_certificate_uploader_impl_unittest.cc",
     "../ash/attestation/platform_verification_flow_unittest.cc",
+    "../ash/attestation/soft_bind_attestation_flow_unittest.cc",
     "../ash/attestation/tpm_challenge_key_result_unittest.cc",
     "../ash/attestation/tpm_challenge_key_subtle_unittest.cc",
     "../ash/attestation/tpm_challenge_key_unittest.cc",
@@ -4969,6 +4972,9 @@
     "//third_party/icu",
     "//third_party/leveldatabase",
     "//third_party/private_membership:private_membership_proto",
+    "//third_party/securemessage",
+    "//third_party/securemessage:securemessage_cpp_protobuf",
+    "//third_party/securemessage:securemessage_openssl",
     "//third_party/zlib/google:compression_utils",
     "//ui/base:test_support",
     "//ui/base/ime/ash",
diff --git a/chrome/browser/chromeos/arc/start_smart_selection_action_menu.cc b/chrome/browser/chromeos/arc/start_smart_selection_action_menu.cc
index eb6c1b35..c85a1c6d 100644
--- a/chrome/browser/chromeos/arc/start_smart_selection_action_menu.cc
+++ b/chrome/browser/chromeos/arc/start_smart_selection_action_menu.cc
@@ -20,6 +20,7 @@
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/arc/common/intent_helper/arc_intent_helper_package.h"
 #include "components/renderer_context_menu/render_view_context_menu_proxy.h"
 #include "content/public/browser/context_menu_params.h"
 #include "ui/base/layout.h"
@@ -144,6 +145,21 @@
       display::Screen::GetScreen()->GetDisplayNearestPoint(point);
 
   Profile* profile = Profile::FromBrowserContext(context_);
+  if (actions_[index].activity.package_name ==
+      arc::kArcIntentHelperPackageName) {
+    // The intent_helper app can't be launched as a regular app that then
+    // handles this smart action intent because it is not a launcher app.
+    // Instead, directly request that the intent be handled by it without
+    // really launching the app.
+    // This is necessary for "generic" smart selection actions that aren't
+    // created for specific apps such as opening a URL or a street address.
+    delegate_->HandleIntent(std::move(actions_[index].action_intent),
+                            internal::ActivityIconLoader::ActivityName(
+                                actions_[index].activity.package_name,
+                                actions_[index].activity.activity_name));
+    return;
+  }
+  // The app that this intent points to is able to handle it, launch it.
   apps::AppServiceProxyFactory::GetForProfile(profile)->LaunchAppWithIntent(
       actions_[index].app_id, ui::EF_NONE,
       CreateIntent(std::move(actions_[index].action_intent),
diff --git a/chrome/browser/chromeos/extensions/default_app_order.cc b/chrome/browser/chromeos/extensions/default_app_order.cc
index 9e16fb6..795b73b 100644
--- a/chrome/browser/chromeos/extensions/default_app_order.cc
+++ b/chrome/browser/chromeos/extensions/default_app_order.cc
@@ -10,7 +10,6 @@
 #include "ash/public/cpp/app_list/internal_app_id_constants.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
@@ -184,13 +183,13 @@
 
 // Gets built-in default app order.
 void GetDefault(std::vector<std::string>* app_ids) {
-  for (size_t i = 0; i < base::size(kDefaultAppOrder); ++i)
+  for (size_t i = 0; i < std::size(kDefaultAppOrder); ++i)
     app_ids->push_back(std::string(kDefaultAppOrder[i]));
 }
 
 }  // namespace
 
-const size_t kDefaultAppOrderCount = base::size(kDefaultAppOrder);
+const size_t kDefaultAppOrderCount = std::size(kDefaultAppOrder);
 
 ExternalLoader::ExternalLoader(bool async)
     : loaded_(base::WaitableEvent::ResetPolicy::MANUAL,
diff --git a/chrome/browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc b/chrome/browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc
index 63ed7be..077f2b0 100644
--- a/chrome/browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc
+++ b/chrome/browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/extensions/extensions_permissions_tracker.h"
 
-#include "base/cxx17_backports.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
@@ -50,10 +49,10 @@
       : ExtensionsPermissionsTracker(registry, browser_context) {
     safe_permissions_.insert(
         kSafePermissionsSet1,
-        kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+        kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
     safe_permissions_.insert(
         kSafePermissionsSet2,
-        kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+        kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   }
 
   // ExtensionsPermissionsTracker:
@@ -144,12 +143,12 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kSafePermissionsSet2,
-      kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+      kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
@@ -162,11 +161,11 @@
 
   std::vector<std::string> v1(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
 
   std::vector<std::string> v2(
       kUnsafePermissionsSet2,
-      kUnsafePermissionsSet2 + base::size(kUnsafePermissionsSet2));
+      kUnsafePermissionsSet2 + std::size(kUnsafePermissionsSet2));
 
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
@@ -181,12 +180,12 @@
 
   std::vector<std::string> v1(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kSafePermissionsSet2,
-      kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+      kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -199,12 +198,12 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kSafePermissionsSet2,
-      kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+      kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
@@ -216,7 +215,7 @@
 
   std::vector<std::string> v3(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId3, v3);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -229,12 +228,12 @@
 
   std::vector<std::string> v1(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kSafePermissionsSet2,
-      kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+      kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -253,7 +252,7 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -261,7 +260,7 @@
 
   std::vector<std::string> v2(
       kSafePermissionsSet2,
-      kSafePermissionsSet2 + base::size(kSafePermissionsSet2));
+      kSafePermissionsSet2 + std::size(kSafePermissionsSet2));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
@@ -274,7 +273,7 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -282,7 +281,7 @@
 
   std::vector<std::string> v2(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -295,12 +294,12 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   EXPECT_TRUE(testing_local_state_.Get()->GetBoolean(
@@ -327,17 +326,17 @@
 
   std::vector<std::string> v1(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId1, v1);
 
   std::vector<std::string> v2(
       kSafePermissionsSet1,
-      kSafePermissionsSet1 + base::size(kSafePermissionsSet1));
+      kSafePermissionsSet1 + std::size(kSafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId2, v2);
 
   std::vector<std::string> v3(
       kUnsafePermissionsSet1,
-      kUnsafePermissionsSet1 + base::size(kUnsafePermissionsSet1));
+      kUnsafePermissionsSet1 + std::size(kUnsafePermissionsSet1));
   AddExtensionWithIdAndPermissions(kExtensionId3, v3);
 
   EXPECT_FALSE(testing_local_state_.Get()->GetBoolean(
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
index d3affb0..38319aaa 100644
--- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -106,7 +106,7 @@
       "jndclpdbaamdhonoechobihbbiimdgai"   // Recovery tool prod
   };
 
-  for (size_t i = 0; i < base::size(kRecoveryToolIds); ++i) {
+  for (size_t i = 0; i < std::size(kRecoveryToolIds); ++i) {
     const std::string extension_id = kRecoveryToolIds[i];
     if (extension_prefs->IsExtensionRunning(extension_id))
       return true;
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
index 1d7a8cc..7e22cff 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -12,7 +12,6 @@
 #include "ash/constants/ash_features.h"
 #include "base/base64.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -271,7 +270,7 @@
       }
     };
 
-    for (size_t i = 0; i < base::size(kTestMountPoints); i++) {
+    for (size_t i = 0; i < std::size(kTestMountPoints); i++) {
       mount_points_.insert(DiskMountManager::MountPointMap::value_type(
           kTestMountPoints[i].mount_path,
           DiskMountManager::MountPointInfo(kTestMountPoints[i].source_path,
@@ -281,8 +280,8 @@
       ));
       int disk_info_index = kTestMountPoints[i].disk_info_index;
       if (kTestMountPoints[i].disk_info_index >= 0) {
-        EXPECT_GT(base::size(kTestDisks), static_cast<size_t>(disk_info_index));
-        if (static_cast<size_t>(disk_info_index) >= base::size(kTestDisks))
+        EXPECT_GT(std::size(kTestDisks), static_cast<size_t>(disk_info_index));
+        if (static_cast<size_t>(disk_info_index) >= std::size(kTestDisks))
           return;
 
         std::unique_ptr<Disk> disk =
diff --git a/chrome/browser/chromeos/extensions/gfx_utils.cc b/chrome/browser/chromeos/extensions/gfx_utils.cc
index e141b86..8cf7c56 100644
--- a/chrome/browser/chromeos/extensions/gfx_utils.cc
+++ b/chrome/browser/chromeos/extensions/gfx_utils.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/chromeos/extensions/gfx_utils.h"
 
 #include "base/containers/cxx20_erase.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
@@ -107,7 +106,7 @@
   using ExtensionToArcAppMap = std::unordered_map<std::string, std::string>;
 
   AppDualBadgeMap() {
-    for (size_t i = 0; i < base::size(kDualBadgeMap); ++i) {
+    for (size_t i = 0; i < std::size(kDualBadgeMap); ++i) {
       arc_app_to_extensions_map_[kDualBadgeMap[i].arc_package_name].push_back(
           kDualBadgeMap[i].extension_id);
       extension_to_arc_app_map_[kDualBadgeMap[i].extension_id] =
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
index 607e63d..272c9d8 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
@@ -45,8 +45,8 @@
         /*matches_origin=*/"*://www.google.com/*"),
     ExtensionInfoTestParams(
         /*extension_id=*/"alnedpmllcfpgldkagbfbjkloonjlfjb",
-        /*pwa_page_url=*/"http://hpcs-appschr.hpcloud.hp.com",
-        /*matches_origin=*/"*://hpcs-appschr.hpcloud.hp.com/*")};
+        /*pwa_page_url=*/"https://hpcs-appschr.hpcloud.hp.com",
+        /*matches_origin=*/"https://hpcs-appschr.hpcloud.hp.com/*")};
 
 // Tests that Chrome OS System Extensions must fulfill the requirements to
 // access Telemetry Extension APIs. All tests are parameterized with the
diff --git a/chrome/browser/chromeos/extensions/wallpaper_function_base.cc b/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
index d03f671..f79d41b8 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_function_base.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/extensions/wallpaper_function_base.h"
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/synchronization/atomic_flag.h"
@@ -32,7 +31,7 @@
   "TILE"
 };
 
-const int kWallpaperLayoutCount = base::size(kWallpaperLayoutArrays);
+const int kWallpaperLayoutCount = std::size(kWallpaperLayoutArrays);
 
 base::LazyThreadPoolSequencedTaskRunner g_blocking_task_runner =
     LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
diff --git a/chrome/browser/chromeos/fileapi/file_system_backend.cc b/chrome/browser/chromeos/fileapi/file_system_backend.cc
index b110224..58438f6 100644
--- a/chrome/browser/chromeos/fileapi/file_system_backend.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend.cc
@@ -12,7 +12,6 @@
 #include "ash/webui/file_manager/url_constants.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
@@ -252,7 +251,7 @@
 
   const std::string& extension_id = origin.host();
   if (url.type() == storage::kFileSystemTypeRestrictedLocal) {
-    for (size_t i = 0; i < base::size(kOemAccessibleExtensions); ++i) {
+    for (size_t i = 0; i < std::size(kOemAccessibleExtensions); ++i) {
       if (extension_id == kOemAccessibleExtensions[i])
         return true;
     }
diff --git a/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc b/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
index 55738df..9d18a80e 100644
--- a/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/file_system_backend_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <set>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
 #include "chromeos/dbus/cros_disks/cros_disks_client.h"
@@ -230,7 +229,7 @@
     { FPL("/foo/xxx"), false, FPL("") },
   };
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     // Initialize virtual path with a value.
     base::FilePath virtual_path(FPL("/mount"));
     base::FilePath local_path(kTestCases[i].local_path);
diff --git a/chrome/browser/component_updater/crowd_deny_component_installer.cc b/chrome/browser/component_updater/crowd_deny_component_installer.cc
index 919885d..a5b2538 100644
--- a/chrome/browser/component_updater/crowd_deny_component_installer.cc
+++ b/chrome/browser/component_updater/crowd_deny_component_installer.cc
@@ -100,7 +100,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(
       kCrowdDenyPublicKeySHA256,
-      kCrowdDenyPublicKeySHA256 + base::size(kCrowdDenyPublicKeySHA256));
+      kCrowdDenyPublicKeySHA256 + std::size(kCrowdDenyPublicKeySHA256));
 }
 
 std::string CrowdDenyComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/desktop_sharing_hub_component_installer.cc b/chrome/browser/component_updater/desktop_sharing_hub_component_installer.cc
index 157eea2..32148137 100644
--- a/chrome/browser/component_updater/desktop_sharing_hub_component_installer.cc
+++ b/chrome/browser/component_updater/desktop_sharing_hub_component_installer.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -111,7 +110,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(kDesktopSharingHubPublicKeySHA256,
                kDesktopSharingHubPublicKeySHA256 +
-                   base::size(kDesktopSharingHubPublicKeySHA256));
+                   std::size(kDesktopSharingHubPublicKeySHA256));
 }
 
 std::string DesktopSharingHubComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/file_type_policies_component_installer.cc b/chrome/browser/component_updater/file_type_policies_component_installer.cc
index 0d0858a..4f8fdef 100644
--- a/chrome/browser/component_updater/file_type_policies_component_installer.cc
+++ b/chrome/browser/component_updater/file_type_policies_component_installer.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -114,7 +113,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(kFileTypePoliciesPublicKeySHA256,
                kFileTypePoliciesPublicKeySHA256 +
-                   base::size(kFileTypePoliciesPublicKeySHA256));
+                   std::size(kFileTypePoliciesPublicKeySHA256));
 }
 
 std::string FileTypePoliciesComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/first_party_sets_component_installer.cc b/chrome/browser/component_updater/first_party_sets_component_installer.cc
index cfef8cfa..09a60ed 100644
--- a/chrome/browser/component_updater/first_party_sets_component_installer.cc
+++ b/chrome/browser/component_updater/first_party_sets_component_installer.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
@@ -180,7 +179,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(kFirstPartySetsPublicKeySHA256,
                kFirstPartySetsPublicKeySHA256 +
-                   base::size(kFirstPartySetsPublicKeySHA256));
+                   std::size(kFirstPartySetsPublicKeySHA256));
 }
 
 std::string FirstPartySetsComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/hyphenation_component_installer.cc b/chrome/browser/component_updater/hyphenation_component_installer.cc
index fba994b..fe14cb5 100644
--- a/chrome/browser/component_updater/hyphenation_component_installer.cc
+++ b/chrome/browser/component_updater/hyphenation_component_installer.cc
@@ -127,7 +127,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(
       kHyphenationPublicKeySHA256,
-      kHyphenationPublicKeySHA256 + base::size(kHyphenationPublicKeySHA256));
+      kHyphenationPublicKeySHA256 + std::size(kHyphenationPublicKeySHA256));
 }
 
 std::string HyphenationComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/intervention_policy_database_component_installer.cc b/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
index d82824c45..7e149b87 100644
--- a/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
+++ b/chrome/browser/component_updater/intervention_policy_database_component_installer.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "chrome/browser/resource_coordinator/intervention_policy_database.h"
@@ -96,7 +95,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(kInterventionPolicyDatabasePublicKeySHA256,
                kInterventionPolicyDatabasePublicKeySHA256 +
-                   base::size(kInterventionPolicyDatabasePublicKeySHA256));
+                   std::size(kInterventionPolicyDatabasePublicKeySHA256));
 }
 
 std::string InterventionPolicyDatabaseComponentInstallerPolicy::GetName()
diff --git a/chrome/browser/component_updater/mei_preload_component_installer.cc b/chrome/browser/component_updater/mei_preload_component_installer.cc
index 44e5a23..e62f0e5d 100644
--- a/chrome/browser/component_updater/mei_preload_component_installer.cc
+++ b/chrome/browser/component_updater/mei_preload_component_installer.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/ref_counted.h"
@@ -115,7 +114,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(
       kMeiPreloadPublicKeySHA256,
-      kMeiPreloadPublicKeySHA256 + base::size(kMeiPreloadPublicKeySHA256));
+      kMeiPreloadPublicKeySHA256 + std::size(kMeiPreloadPublicKeySHA256));
 }
 
 std::string MediaEngagementPreloadComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/recovery_component_installer.cc b/chrome/browser/component_updater/recovery_component_installer.cc
index 478a20c..52efafe 100644
--- a/chrome/browser/component_updater/recovery_component_installer.cc
+++ b/chrome/browser/component_updater/recovery_component_installer.cc
@@ -15,7 +15,6 @@
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
@@ -64,7 +63,7 @@
     0xdf, 0x39, 0x9a, 0x9b, 0x28, 0x3a, 0x9b, 0x0c, 0xbc, 0xc3, 0x4b,
     0x29, 0x12, 0xf3, 0x9e, 0x2c, 0x19, 0x7a, 0x71, 0x4b, 0x0a, 0x7c,
     0x80, 0x1c, 0xf6, 0x29, 0x7c, 0x0a, 0x5f, 0xea, 0x67, 0xb7};
-static_assert(base::size(kRecoverySha2Hash) == crypto::kSHA256Length,
+static_assert(std::size(kRecoverySha2Hash) == crypto::kSHA256Length,
               "Wrong hash length");
 
 // File name of the recovery binary on different platforms.
diff --git a/chrome/browser/component_updater/smart_dim_component_installer.cc b/chrome/browser/component_updater/smart_dim_component_installer.cc
index 2e95c5a3..c402599 100644
--- a/chrome/browser/component_updater/smart_dim_component_installer.cc
+++ b/chrome/browser/component_updater/smart_dim_component_installer.cc
@@ -169,7 +169,7 @@
     std::vector<uint8_t>* hash) const {
   DCHECK(hash);
   hash->assign(kSmartDimPublicKeySHA256,
-               kSmartDimPublicKeySHA256 + base::size(kSmartDimPublicKeySHA256));
+               kSmartDimPublicKeySHA256 + std::size(kSmartDimPublicKeySHA256));
 }
 
 std::string SmartDimComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/soda_component_installer.cc b/chrome/browser/component_updater/soda_component_installer.cc
index 0aaa97c7..8386b8d 100644
--- a/chrome/browser/component_updater/soda_component_installer.cc
+++ b/chrome/browser/component_updater/soda_component_installer.cc
@@ -48,7 +48,7 @@
     0x8e, 0xd0, 0x0c, 0xef, 0xa5, 0xc0, 0x97, 0x00, 0x84, 0x1c, 0x21,
     0xa6, 0xae, 0xc8, 0x1b, 0x87, 0xfb, 0x12, 0x27, 0x28, 0xb1};
 
-static_assert(base::size(kSodaPublicKeySHA256) == crypto::kSHA256Length,
+static_assert(std::size(kSodaPublicKeySHA256) == crypto::kSHA256Length,
               "Wrong hash length");
 
 constexpr char kSodaManifestName[] = "SODA Library";
@@ -121,7 +121,7 @@
       reinterpret_cast<LPTSTR>(users_sid->GetPSID());
 
   PACL acl_ptr = nullptr;
-  if (::SetEntriesInAcl(base::size(explicit_access), explicit_access, nullptr,
+  if (::SetEntriesInAcl(std::size(explicit_access), explicit_access, nullptr,
                         &acl_ptr) != ERROR_SUCCESS) {
     return update_client::CrxInstaller::Result(
         update_client::InstallError::SET_PERMISSIONS_FAILED);
@@ -199,7 +199,7 @@
 
 void SodaComponentInstallerPolicy::GetHash(std::vector<uint8_t>* hash) const {
   hash->assign(kSodaPublicKeySHA256,
-               kSodaPublicKeySHA256 + base::size(kSodaPublicKeySHA256));
+               kSodaPublicKeySHA256 + std::size(kSodaPublicKeySHA256));
 }
 
 std::string SodaComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
index 887df45..2167713 100644
--- a/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
+++ b/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
@@ -121,7 +120,7 @@
     std::vector<uint8_t>* hash) const {
   hash->assign(kSslErrorAssistantPublicKeySHA256,
                kSslErrorAssistantPublicKeySHA256 +
-                   base::size(kSslErrorAssistantPublicKeySHA256));
+                   std::size(kSslErrorAssistantPublicKeySHA256));
 }
 
 std::string SSLErrorAssistantComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/vr_assets_component_installer.cc b/chrome/browser/component_updater/vr_assets_component_installer.cc
index 25ce14e..f7d96d5 100644
--- a/chrome/browser/component_updater/vr_assets_component_installer.cc
+++ b/chrome/browser/component_updater/vr_assets_component_installer.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -173,7 +172,7 @@
 void VrAssetsComponentInstallerPolicy::GetHash(
     std::vector<uint8_t>* hash) const {
   hash->assign(kVrAssetsPublicKeySHA256,
-               kVrAssetsPublicKeySHA256 + base::size(kVrAssetsPublicKeySHA256));
+               kVrAssetsPublicKeySHA256 + std::size(kVrAssetsPublicKeySHA256));
 }
 
 std::string VrAssetsComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 563b9fb1..6eb12f8 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -14,7 +14,6 @@
 
 #include "base/base_paths.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -59,7 +58,7 @@
     0xe8, 0xce, 0xcf, 0x42, 0x06, 0xd0, 0x93, 0x49, 0x6d, 0xd9, 0x89,
     0xe1, 0x41, 0x04, 0x86, 0x4a, 0x8f, 0xbd, 0x86, 0x12, 0xb9, 0x58,
     0x9b, 0xfb, 0x4f, 0xbb, 0x1b, 0xa9, 0xd3, 0x85, 0x37, 0xef};
-static_assert(base::size(kWidevineSha2Hash) == crypto::kSHA256Length,
+static_assert(std::size(kWidevineSha2Hash) == crypto::kSHA256Length,
               "Wrong hash length");
 
 // Name of the Widevine CDM OS in the component manifest.
@@ -234,7 +233,7 @@
 void WidevineCdmComponentInstallerPolicy::GetHash(
     std::vector<uint8_t>* hash) const {
   hash->assign(kWidevineSha2Hash,
-               kWidevineSha2Hash + base::size(kWidevineSha2Hash));
+               kWidevineSha2Hash + std::size(kWidevineSha2Hash));
 }
 
 std::string WidevineCdmComponentInstallerPolicy::GetName() const {
diff --git a/chrome/browser/devtools/device/android_device_info_query.cc b/chrome/browser/devtools/device/android_device_info_query.cc
index 4e43dc1c..d466bdb 100644
--- a/chrome/browser/devtools/device/android_device_info_query.cc
+++ b/chrome/browser/devtools/device/android_device_info_query.cc
@@ -5,7 +5,6 @@
 #include <stddef.h>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
@@ -93,7 +92,7 @@
 };
 
 const BrowserDescriptor* FindBrowserDescriptor(const std::string& package) {
-  size_t count = base::size(kBrowserDescriptors);
+  size_t count = std::size(kBrowserDescriptors);
   for (size_t i = 0; i < count; i++) {
     if (kBrowserDescriptors[i].package == package)
       return &kBrowserDescriptors[i];
@@ -103,7 +102,7 @@
 
 bool BrowserCompare(const AndroidDeviceManager::BrowserInfo& a,
                     const AndroidDeviceManager::BrowserInfo& b) {
-  size_t count = base::size(kBrowserDescriptors);
+  size_t count = std::size(kBrowserDescriptors);
   for (size_t i = 0; i < count; i++) {
     bool isA = kBrowserDescriptors[i].display_name == a.display_name;
     bool isB = kBrowserDescriptors[i].display_name == b.display_name;
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index 70894c2a..4c8c109 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -11,7 +11,6 @@
 #include "base/cancelable_callback.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
@@ -178,7 +177,7 @@
   const char* args_array[] = {method, args...};
   std::ostringstream script;
   script << "uiTests.dispatchOnTestSuite([";
-  for (size_t i = 0; i < base::size(args_array); ++i)
+  for (size_t i = 0; i < std::size(args_array); ++i)
     script << (i ? "," : "") << '\"' << args_array[i] << '\"';
   script << "])";
   ASSERT_TRUE(
diff --git a/chrome/browser/diagnostics/diagnostics_controller_unittest.cc b/chrome/browser/diagnostics/diagnostics_controller_unittest.cc
index 3753553..51063e17 100644
--- a/chrome/browser/diagnostics/diagnostics_controller_unittest.cc
+++ b/chrome/browser/diagnostics/diagnostics_controller_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "base/base_paths.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -78,7 +77,7 @@
     // Just write some random characters into the file tInvaludUsero "corrupt"
     // it.
     const char bogus_data[] = "wwZ2uNYNuyUVzFbDm3DL";
-    base::WriteFile(path, bogus_data, base::size(bogus_data));
+    base::WriteFile(path, bogus_data, std::size(bogus_data));
   }
 
   std::unique_ptr<DiagnosticsModel> model_;
diff --git a/chrome/browser/diagnostics/diagnostics_metrics.cc b/chrome/browser/diagnostics/diagnostics_metrics.cc
index f632bf49..7b062d51 100644
--- a/chrome/browser/diagnostics/diagnostics_metrics.cc
+++ b/chrome/browser/diagnostics/diagnostics_metrics.cc
@@ -7,7 +7,6 @@
 #include <string>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "chrome/browser/diagnostics/diagnostics_test.h"
@@ -57,7 +56,7 @@
     // Add new entries in the same order as DiagnosticsTestId.
 };
 
-static_assert(base::size(kTestNameInfo) == DIAGNOSTICS_TEST_ID_COUNT,
+static_assert(std::size(kTestNameInfo) == DIAGNOSTICS_TEST_ID_COUNT,
               "diagnostics test info mismatch");
 
 const TestNameInfo* FindTestInfo(DiagnosticsTestId id) {
diff --git a/chrome/browser/diagnostics/diagnostics_writer.cc b/chrome/browser/diagnostics/diagnostics_writer.cc
index 5031404..846511fd 100644
--- a/chrome/browser/diagnostics/diagnostics_writer.cc
+++ b/chrome/browser/diagnostics/diagnostics_writer.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
@@ -91,7 +90,7 @@
     SetColor(SimpleConsole::DEFAULT);
     Write(u"Press [enter] to continue\n");
     wchar_t buf[256];
-    DWORD read = base::size(buf);
+    DWORD read = std::size(buf);
     ::ReadConsoleW(std_in_, buf, read, &read, NULL);
   }
 
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogView.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogView.java
index af7646f..c8356204 100644
--- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogView.java
+++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogView.java
@@ -164,8 +164,8 @@
                 Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
         mEditText.setMovementMethod(LinkMovementMethod.getInstance());
-        NoUnderlineClickableSpan editSpan = new NoUnderlineClickableSpan(
-                getResources(), (view) -> { onEditLocationClicked(); });
+        NoUnderlineClickableSpan editSpan =
+                new NoUnderlineClickableSpan(getContext(), (view) -> { onEditLocationClicked(); });
         editText = SpanApplier.applySpans(
                 getResources().getString(R.string.download_later_edit_location, locationText),
                 new SpanInfo("<b>", "</b>", directorySpanBuilder),
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index c2a945c..4d1b3ab2 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -17,7 +17,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
@@ -1645,7 +1644,7 @@
     "image/jpeg",
     "image/bmp",
   };
-  for (size_t i = 0; i < base::size(mime_types); ++i) {
+  for (size_t i = 0; i < std::size(mime_types); ++i) {
     const char* mime_type = mime_types[i];
     GURL url(
         embedded_test_server()->GetURL(std::string("/").append(mime_type)));
@@ -3530,7 +3529,7 @@
        "http://doesnotexist/shouldnotdownloadsuccessfully", DOWNLOAD_DIRECT,
        download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, true, false}};
 
-  DownloadFilesCheckErrors(base::size(download_info), download_info);
+  DownloadFilesCheckErrors(std::size(download_info), download_info);
 }
 
 #if BUILDFLAG(IS_MAC)
@@ -3648,7 +3647,7 @@
            download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
        }}};
 
-  DownloadInsertFilesErrorCheckErrors(base::size(error_info), error_info);
+  DownloadInsertFilesErrorCheckErrors(std::size(error_info), error_info);
 }
 
 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadErrorReadonlyFolder) {
@@ -3660,7 +3659,7 @@
        // This passes because we switch to the My Documents folder.
        download::DOWNLOAD_INTERRUPT_REASON_NONE, true, true}};
 
-  DownloadFilesToReadonlyFolder(base::size(download_info), download_info);
+  DownloadFilesToReadonlyFolder(std::size(download_info), download_info);
 }
 
 // Test that we show a dangerous downloads warning for a dangerous file
@@ -4361,7 +4360,7 @@
       GetDownloadDirectory(browser()).Append(FILE_PATH_LITERAL("origin"));
   ASSERT_TRUE(base::CreateDirectory(origin_directory));
 
-  for (size_t index = 0; index < base::size(kCrazyFilenames); ++index) {
+  for (size_t index = 0; index < std::size(kCrazyFilenames); ++index) {
     SCOPED_TRACE(testing::Message() << "Index " << index);
     std::string crazy8;
     const wchar_t* const crazy_w = kCrazyFilenames[index];
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc
index 50fa8d5..49037fc 100644
--- a/chrome/browser/download/download_item_model_unittest.cc
+++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -45,7 +44,7 @@
 #include "components/download/public/common/download_interrupt_reason_values.h"
 #undef INTERRUPT_REASON
 };
-const size_t kInterruptReasonCount = base::size(kInterruptReasonCounter);
+const size_t kInterruptReasonCount = std::size(kInterruptReasonCounter);
 
 // Default target path for a mock download item in DownloadItemModelTest.
 const base::FilePath::CharType kDefaultTargetFilePath[] =
@@ -204,7 +203,7 @@
       {download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, "%s - Shutdown"},
       {download::DOWNLOAD_INTERRUPT_REASON_CRASH, "%s - Crash"},
   };
-  static_assert(kInterruptReasonCount == base::size(kTestCases),
+  static_assert(kInterruptReasonCount == std::size(kTestCases),
                 "interrupt reason mismatch");
 
   SetupDownloadItemDefaults();
@@ -307,7 +306,7 @@
       {download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, "foo.bar\nShutdown"},
       {download::DOWNLOAD_INTERRUPT_REASON_CRASH, "foo.bar\nCrash"},
   };
-  static_assert(kInterruptReasonCount == base::size(kTestCases),
+  static_assert(kInterruptReasonCount == std::size(kTestCases),
                 "interrupt reason mismatch");
 
   SetupDownloadItemDefaults();
diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc
index 1bd18df..6468749d 100644
--- a/chrome/browser/download/download_target_determiner_unittest.cc
+++ b/chrome/browser/download/download_target_determiner_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/download/download_target_determiner.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
@@ -9,7 +11,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/values_util.h"
 #include "base/location.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/download/download_prompt_status.h"
 #include "chrome/browser/download/download_stats.h"
-#include "chrome/browser/download/download_target_determiner.h"
 #include "chrome/browser/download/download_target_info.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/common/buildflags.h"
@@ -691,7 +691,7 @@
       DownloadFileType::ALLOW_ON_USER_GESTURE,
       safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel(
           base::FilePath(FILE_PATH_LITERAL("foo.kindabad")), GURL{}, nullptr));
-  RunTestCasesWithActiveItem(kBasicTestCases, base::size(kBasicTestCases));
+  RunTestCasesWithActiveItem(kBasicTestCases, std::size(kBasicTestCases));
 }
 
 TEST_F(DownloadTargetDeterminerTest, CancelSaveAs) {
@@ -709,7 +709,7 @@
           WithArg<3>(ScheduleCallback3(DownloadConfirmationResult::CANCELED,
                                        base::FilePath(), absl::nullopt)));
   RunTestCasesWithActiveItem(kCancelSaveAsTestCases,
-                             base::size(kCancelSaveAsTestCases));
+                             std::size(kCancelSaveAsTestCases));
 }
 
 // The SafeBrowsing check is performed early. Make sure that a download item
@@ -779,7 +779,7 @@
       .WillByDefault(WithArg<2>(
           ScheduleCallback(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL)));
   RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
-                             base::size(kSafeBrowsingTestCases));
+                             std::size(kSafeBrowsingTestCases));
 }
 
 // The SafeBrowsing check is performed early. Make sure that a download item
@@ -836,7 +836,7 @@
       .WillByDefault(WithArg<2>(ScheduleCallback(
           download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)));
   RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
-                             base::size(kSafeBrowsingTestCases));
+                             std::size(kSafeBrowsingTestCases));
 }
 
 // Test whether the last saved directory is used for 'Save As' downloads.
@@ -898,7 +898,7 @@
                 RequestConfirmation_(_, prompt_path,
                                      DownloadConfirmationReason::SAVE_AS, _));
     RunTestCasesWithActiveItem(kLastSavePathTestCasesPre,
-                               base::size(kLastSavePathTestCasesPre));
+                               std::size(kLastSavePathTestCasesPre));
   }
 
   // Try with a non-empty last save path.
@@ -912,7 +912,7 @@
                 RequestConfirmation_(_, prompt_path,
                                      DownloadConfirmationReason::SAVE_AS, _));
     RunTestCasesWithActiveItem(kLastSavePathTestCasesPost,
-                               base::size(kLastSavePathTestCasesPost));
+                               std::size(kLastSavePathTestCasesPost));
   }
 
   // And again, but this time use a virtual directory.
@@ -929,7 +929,7 @@
         .WillOnce(WithArg<2>(ScheduleCallback(
             GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")))));
     RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual,
-                               base::size(kLastSavePathTestCasesVirtual));
+                               std::size(kLastSavePathTestCasesVirtual));
   }
 }
 
@@ -1147,7 +1147,7 @@
           _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _))
       .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath())));
   RunTestCasesWithActiveItem(kLocalPathFailedCases,
-                             base::size(kLocalPathFailedCases));
+                             std::size(kLocalPathFailedCases));
 }
 
 // Downloads that have a danger level of ALLOW_ON_USER_GESTURE should be marked
@@ -1218,7 +1218,7 @@
   history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED);
 
   RunTestCasesWithActiveItem(kVisitedReferrerCases,
-                             base::size(kVisitedReferrerCases));
+                             std::size(kVisitedReferrerCases));
 }
 
 TEST_F(DownloadTargetDeterminerTest, TransitionType) {
@@ -1514,7 +1514,7 @@
 
   SetPromptForDownload(true);
   RunTestCasesWithActiveItem(kPromptingTestCases,
-                             base::size(kPromptingTestCases));
+                             std::size(kPromptingTestCases));
 }
 
 // Trusted extension download should not cause prompting.
@@ -1547,7 +1547,7 @@
       download_crx_util::OverrideOffstoreInstallAllowedForTesting(true);
   SetPromptForDownload(true);
   RunTestCasesWithActiveItem(kPromptingTestCases,
-                             base::size(kPromptingTestCases));
+                             std::size(kPromptingTestCases));
 }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
@@ -1577,7 +1577,7 @@
   SetManagedDownloadPath(test_download_dir());
   ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
   RunTestCasesWithActiveItem(kManagedPathTestCases,
-                             base::size(kManagedPathTestCases));
+                             std::size(kManagedPathTestCases));
 }
 
 // Test basic blocking functionality via GetMixedContentStatus.
@@ -1593,7 +1593,7 @@
       .WillByDefault(WithArg<2>(ScheduleCallback(
           download::DownloadItem::MixedContentStatus::SILENT_BLOCK)));
   RunTestCasesWithActiveItem(kBlockDownloadsTestCases,
-                             base::size(kBlockDownloadsTestCases));
+                             std::size(kBlockDownloadsTestCases));
 }
 
 // Test basic functionality supporting extensions that want to override download
@@ -1655,7 +1655,7 @@
   ON_CALL(*delegate(), NotifyExtensions_(_, _, _))
       .WillByDefault(Invoke(&NotifyExtensionsOverridePath));
   RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
-                             base::size(kNotifyExtensionsTestCases));
+                             std::size(kNotifyExtensionsTestCases));
 }
 
 // Test that filenames provided by extensions are passed into SafeBrowsing
@@ -1866,7 +1866,7 @@
       DownloadFileType::ALLOW_ON_USER_GESTURE,
       safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel(
           base::FilePath(FILE_PATH_LITERAL("foo.kindabad")), GURL{}, nullptr));
-  for (size_t i = 0; i < base::size(kResumedTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kResumedTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "Running test case " << i);
     const DownloadTestCase& test_case = kResumedTestCases[i];
     std::unique_ptr<download::MockDownloadItem> item =
@@ -1980,7 +1980,7 @@
       DownloadFileType::ALLOW_ON_USER_GESTURE,
       safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel(
           base::FilePath(FILE_PATH_LITERAL("foo.kindabad")), GURL{}, nullptr));
-  for (size_t i = 0; i < base::size(kResumedTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kResumedTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "Running test case " << i);
     download_prefs()->SetSaveFilePath(test_download_dir());
     const DownloadTestCase& test_case = kResumedTestCases[i];
@@ -2092,7 +2092,7 @@
       safe_browsing::FileTypePolicies::GetInstance()->GetFileDangerLevel(
           base::FilePath(FILE_PATH_LITERAL("foo.kindabad")), GURL{}, nullptr));
 
-  for (size_t i = 0; i < base::size(kIntermediateNameTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kIntermediateNameTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "Running test case " << i);
     const IntermediateNameTestCase& test_case = kIntermediateNameTestCases[i];
     std::unique_ptr<download::MockDownloadItem> item =
@@ -2199,7 +2199,7 @@
       GetFileMimeType_(GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _))
       .WillByDefault(WithArg<1>(ScheduleCallback("image/png")));
 
-  for (size_t i = 0; i < base::size(kMIMETypeTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kMIMETypeTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "Running test case " << i);
     const MIMETypeTestCase& test_case = kMIMETypeTestCases[i];
     std::unique_ptr<download::MockDownloadItem> item =
@@ -2292,7 +2292,7 @@
         DownloadItem::TARGET_DISPOSITION_OVERWRITE, EXPECT_CRDOWNLOAD},
        "foo.txt" /* suggested_file_name */}};
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     std::unique_ptr<download::MockDownloadItem> item =
         CreateActiveDownloadItem(i, kTestCases[i].general);
     ON_CALL(*item, GetSuggestedFilename())
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index f608831..5e06dc2 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
@@ -1211,7 +1210,7 @@
   // This is used for preparing all accounts in PRE_ test setup, and for testing
   // actual login behavior.
   void AddAllUsers() {
-    for (size_t i = 0; i < base::size(kTestAccounts); ++i) {
+    for (size_t i = 0; i < std::size(kTestAccounts); ++i) {
       // The primary account was already set up in SetUpOnMainThread, so skip it
       // here.
       if (i == PRIMARY_ACCOUNT_INDEX)
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/crypto_utility.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/crypto_utility.cc
index 929400a..3df856c 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/crypto_utility.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/crypto_utility.cc
@@ -34,7 +34,7 @@
 }
 
 unsigned char* StringAsOpenSSLBuffer(std::string* s) {
-  return reinterpret_cast<unsigned char*>(base::data(*s));
+  return reinterpret_cast<unsigned char*>(std::data(*s));
 }
 
 }  // namespace
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/linux_key_rotation_command_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/linux_key_rotation_command_unittest.cc
index b798071d..5d7b514 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/linux_key_rotation_command_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/browser/commands/linux_key_rotation_command_unittest.cc
@@ -9,7 +9,6 @@
 
 #include "base/base64.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/test/mock_callback.h"
@@ -64,7 +63,7 @@
   static base::CommandLine GetMojoCommandLine(base::CommandLine command_line) {
     auto test_command_line = base::GetMultiProcessTestChildBaseCommandLine();
     test_command_line.CopySwitchesFrom(command_line, kSwitches,
-                                       base::size(kSwitches));
+                                       std::size(kSwitches));
     return test_command_line;
   }
 
diff --git a/chrome/browser/enterprise/signals/context_info_fetcher.cc b/chrome/browser/enterprise/signals/context_info_fetcher.cc
index fb7a4f0d..06603d9a 100644
--- a/chrome/browser/enterprise/signals/context_info_fetcher.cc
+++ b/chrome/browser/enterprise/signals/context_info_fetcher.cc
@@ -101,7 +101,7 @@
   // The most restrictive active profile takes precedence.
   constexpr NET_FW_PROFILE_TYPE2 kProfileTypes[] = {
       NET_FW_PROFILE2_PUBLIC, NET_FW_PROFILE2_PRIVATE, NET_FW_PROFILE2_DOMAIN};
-  for (size_t i = 0; i < base::size(kProfileTypes); ++i) {
+  for (size_t i = 0; i < std::size(kProfileTypes); ++i) {
     if ((profile_types & kProfileTypes[i]) != 0) {
       VARIANT_BOOL enabled = VARIANT_TRUE;
       hr = firewall_policy->get_FirewallEnabled(kProfileTypes[i], &enabled);
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 2c629b2..bc05430 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -1351,21 +1351,68 @@
   sources = [
     "api/passwords_private/test_passwords_private_delegate.cc",
     "api/passwords_private/test_passwords_private_delegate.h",
+    "chrome_extension_test_notification_observer.cc",
+    "chrome_extension_test_notification_observer.h",
+    "chrome_test_extension_loader.cc",
+    "chrome_test_extension_loader.h",
+    "extension_action_test_util.cc",
+    "extension_action_test_util.h",
     "extension_management_test_util.cc",
     "extension_management_test_util.h",
     "external_testing_loader.cc",
     "external_testing_loader.h",
+    "load_error_waiter.cc",
+    "load_error_waiter.h",
     "menu_manager_test_observer.cc",
     "menu_manager_test_observer.h",
+    "mock_extension_special_storage_policy.cc",
+    "mock_extension_special_storage_policy.h",
+    "scoped_database_manager_for_test.cc",
+    "scoped_database_manager_for_test.h",
+    "test_blocklist.cc",
+    "test_blocklist.h",
+    "test_blocklist_state_fetcher.cc",
+    "test_blocklist_state_fetcher.h",
+    "test_extension_message_bubble_delegate.cc",
+    "test_extension_message_bubble_delegate.h",
+    "test_extension_service.cc",
+    "test_extension_service.h",
+    "test_extension_system.cc",
+    "test_extension_system.h",
   ]
 
   deps = [
     ":extensions",
     "//base",
+    "//chrome/browser",
+    "//chrome/browser:test_support",
     "//chrome/browser/profiles:profile",
-    "//components/crx_file:crx_file",
+    "//chrome/browser/ui",
+    "//components/crx_file",
     "//components/policy/core/common:test_support",
+    "//components/safe_browsing/core/browser/db:database_manager",
+    "//components/safe_browsing/core/browser/db:v4_test_util",
+    "//components/services/unzip:in_process",
+    "//components/services/unzip/content",
+    "//components/sessions",
+    "//components/value_store:test_support",
     "//content/public/browser",
-    "//extensions/browser:browser",
+    "//content/test:test_support",
+    "//extensions:test_support",
+    "//extensions/browser",
+    "//extensions/browser:test_support",
+    "//services/data_decoder/public/cpp:test_support",
   ]
+
+  if (!is_fuchsia) {
+    # Native Messaging is not available under Fuchsia.
+    sources += [
+      "api/messaging/native_messaging_test_util.cc",
+      "api/messaging/native_messaging_test_util.h",
+    ]
+  }
+
+  if (is_chromeos_ash) {
+    deps += [ "//components/user_manager:test_support" ]
+  }
 }
diff --git a/chrome/browser/extensions/activity_log/activity_database_unittest.cc b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
index 4704c9f..276e5c3 100644
--- a/chrome/browser/extensions/activity_log/activity_database_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/extensions/activity_log/activity_database.h"
+
 #include <stddef.h>
 
 #include <string>
 
 #include "base/command_line.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"
@@ -18,7 +19,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/extensions/activity_log/activity_action_constants.h"
-#include "chrome/browser/extensions/activity_log/activity_database.h"
 #include "chrome/browser/extensions/activity_log/activity_log_task_runner.h"
 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -66,7 +66,7 @@
 bool ActivityDatabaseTestPolicy::InitDatabase(sql::Database* db) {
   return ActivityDatabase::InitializeTable(db, kTableName, kTableContentFields,
                                            kTableFieldTypes,
-                                           base::size(kTableContentFields));
+                                           std::size(kTableContentFields));
 }
 
 bool ActivityDatabaseTestPolicy::FlushDatabase(sql::Database* db) {
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index ac907c20..1e09d40 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/activity_log/activity_log.h"
 
 #include <stddef.h>
+
 #include <memory>
 #include <set>
 #include <utility>
@@ -12,7 +13,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
@@ -189,7 +189,7 @@
 
  private:
   ApiInfoDatabase() {
-    for (size_t i = 0; i < base::size(kApiInfoTable); i++) {
+    for (size_t i = 0; i < std::size(kApiInfoTable); i++) {
       const ApiInfo* info = &kApiInfoTable[i];
       api_database_[info->api_name] = info;
     }
diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
index 74aabfa..1f3fd40 100644
--- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/synchronization/waitable_event.h"
@@ -262,7 +261,7 @@
 
   static void RetrieveActions_ArgUrlApiCalls(
       std::unique_ptr<std::vector<scoped_refptr<Action>>> actions) {
-    size_t api_calls_size = base::size(kUrlApiCalls);
+    size_t api_calls_size = std::size(kUrlApiCalls);
     const base::DictionaryValue* other = NULL;
 
     ASSERT_EQ(api_calls_size, actions->size());
@@ -443,7 +442,7 @@
 TEST_F(ActivityLogTest, ArgUrlApiCalls) {
   ActivityLog* activity_log = ActivityLog::GetInstance(profile());
   base::Time now = base::Time::Now();
-  int api_calls_size = base::size(kUrlApiCalls);
+  int api_calls_size = std::size(kUrlApiCalls);
   scoped_refptr<Action> action;
 
   for (int i = 0; i < api_calls_size; i++) {
diff --git a/chrome/browser/extensions/activity_log/counting_policy.cc b/chrome/browser/extensions/activity_log/counting_policy.cc
index f3445fc..3ba64e94 100644
--- a/chrome/browser/extensions/activity_log/counting_policy.cc
+++ b/chrome/browser/extensions/activity_log/counting_policy.cc
@@ -38,7 +38,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_string_value_serializer.h"
@@ -172,7 +171,7 @@
       string_table_("string_ids"),
       url_table_("url_ids"),
       retention_time_(base::Hours(60)) {
-  for (size_t i = 0; i < base::size(kAlwaysLog); i++) {
+  for (size_t i = 0; i < std::size(kAlwaysLog); i++) {
     api_arg_allowlist_.insert(
         std::make_pair(kAlwaysLog[i].type, kAlwaysLog[i].name));
   }
@@ -189,7 +188,7 @@
   // Create the unified activity log entry table.
   if (!ActivityDatabase::InitializeTable(db, kTableName, kTableContentFields,
                                          kTableFieldTypes,
-                                         base::size(kTableContentFields)))
+                                         std::size(kTableContentFields)))
     return false;
 
   // Create a view for easily accessing the uncompressed form of the data, and
@@ -271,14 +270,14 @@
       " SET count = count + ?, time = max(?, time)"
       " WHERE rowid = ?";
 
-  for (size_t i = 0; i < base::size(matched_columns); i++) {
+  for (size_t i = 0; i < std::size(matched_columns); i++) {
     locate_str = base::StringPrintf(
         "%s AND %s IS ?", locate_str.c_str(), matched_columns[i]);
     insert_str =
         base::StringPrintf("%s, %s", insert_str.c_str(), matched_columns[i]);
   }
   insert_str += ") VALUES (?, ?";
-  for (size_t i = 0; i < base::size(matched_columns); i++) {
+  for (size_t i = 0; i < std::size(matched_columns); i++) {
     insert_str += ", ?";
   }
   locate_str += " ORDER BY time DESC LIMIT 1";
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
index 1eda2d6..f5b33da 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_string_value_serializer.h"
@@ -50,7 +49,7 @@
   "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
 };
 const int FullStreamUIPolicy::kTableFieldCount =
-    base::size(FullStreamUIPolicy::kTableContentFields);
+    std::size(FullStreamUIPolicy::kTableContentFields);
 
 FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile)
     : ActivityLogDatabasePolicy(
@@ -63,7 +62,7 @@
   // Create the unified activity log entry table.
   return ActivityDatabase::InitializeTable(db, kTableName, kTableContentFields,
                                            kTableFieldTypes,
-                                           base::size(kTableContentFields));
+                                           std::size(kTableContentFields));
 }
 
 bool FullStreamUIPolicy::FlushDatabase(sql::Database* db) {
diff --git a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
index 0237186..01059f9 100644
--- a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
+++ b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_descriptor_watcher_posix.h"
 #include "base/logging.h"
 #include "base/memory/free_deleter.h"
@@ -118,7 +117,7 @@
   };
   if (libbrlapi_loader_->brlapi__acceptKeys(handle_.get(),
                                             brlapi_rangeType_command, extraKeys,
-                                            base::size(extraKeys)) < 0) {
+                                            std::size(extraKeys)) < 0) {
     LOG(ERROR) << "Couldn't acceptKeys: " << BrlapiStrError();
     Disconnect();
     return CONNECT_ERROR_RETRY;
diff --git a/chrome/browser/extensions/api/cookies/cookies_unittest.cc b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
index ff2856a8e3..a318fb16 100644
--- a/chrome/browser/extensions/api/cookies/cookies_unittest.cc
+++ b/chrome/browser/extensions/api/cookies/cookies_unittest.cc
@@ -11,7 +11,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h"
 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
@@ -172,7 +171,7 @@
       {".bar.com", ".foo.bar.com", true}, {".bar.com", "baz.foo.bar.com", true},
       {"foo.bar.com", ".bar.com", false}};
 
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     // Build up the Params struct.
     std::vector<base::Value> args;
     base::Value dict(base::Value::Type::DICTIONARY);
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 e950417..241c28e 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
@@ -3446,7 +3446,7 @@
       {third_tab_id, "rule3.com"},
   };
 
-  for (size_t i = 0; i < base::size(cases); i++) {
+  for (size_t i = 0; i < std::size(cases); i++) {
     SCOPED_TRACE(base::StringPrintf("Testing case %zu", i));
     // Navigate the i'th tab to `new_url`.
     tab_strip_model->ActivateTabAt(static_cast<int>(i));
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
index d7aa7a2..7e11204 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
@@ -2,13 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/declarative_webrequest/webrequest_action.h"
-
 #include <stddef.h>
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/memory/ref_counted.h"
@@ -21,6 +18,7 @@
 #include "chrome/common/extensions/extension_test_util.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/browser/api/declarative_webrequest/request_stage.h"
+#include "extensions/browser/api/declarative_webrequest/webrequest_action.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
 #include "extensions/browser/api/web_request/permission_helper.h"
@@ -563,7 +561,7 @@
     "declarativeWebRequest.IgnoreRules",
   };
   std::unique_ptr<WebRequestActionSet> action_set(CreateSetOfActions(kActions));
-  ASSERT_EQ(base::size(kExpectedNames), action_set->actions().size());
+  ASSERT_EQ(std::size(kExpectedNames), action_set->actions().size());
   size_t index = 0;
   for (auto it = action_set->actions().cbegin();
        it != action_set->actions().cend(); ++it) {
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
index d1fd301b..994fcfe 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
@@ -657,11 +657,11 @@
   };
   // Which rules should match in subsequent test iterations.
   const char* const matchingRuleIds[] = { kRuleId1, kRuleId2 };
-  static_assert(base::size(urls) == base::size(matchingRuleIds),
+  static_assert(std::size(urls) == std::size(matchingRuleIds),
                 "urls and matchingRuleIds must have the same number "
                 "of elements");
 
-  for (size_t i = 0; i < base::size(matchingRuleIds); ++i) {
+  for (size_t i = 0; i < std::size(matchingRuleIds); ++i) {
     // Construct the inputs.
     WebRequestInfoInitParams params = CreateRequestParams(urls[i]);
     WebRequestInfo http_request_info(std::move(params));
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
index bf8bba30..50f36b6c 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_apitest.cc
@@ -5,7 +5,6 @@
 #include <array>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "build/build_config.h"
@@ -169,7 +168,7 @@
      .selected_source = DesktopMediaID(DesktopMediaID::TYPE_SCREEN,
                                        webrtc::kFullDesktopScreenId)},
   };
-  picker_factory_.SetTestFlags(test_flags, base::size(test_flags));
+  picker_factory_.SetTestFlags(test_flags, std::size(test_flags));
   ASSERT_TRUE(RunExtensionTest("desktop_capture")) << message_;
 }
 
@@ -214,7 +213,7 @@
            DesktopMediaID(DesktopMediaID::TYPE_SCREEN, DesktopMediaID::kNullId),
        .cancelled = true},
   };
-  picker_factory_.SetTestFlags(test_flags, base::size(test_flags));
+  picker_factory_.SetTestFlags(test_flags, std::size(test_flags));
 
   bool result;
 
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc
index b50c80a..4126629f 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+
 #include <memory>
 #include <set>
 #include <string>
@@ -15,7 +16,6 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_writer.h"
@@ -204,7 +204,7 @@
                                       kDangerPromptForScanning,
                                       kDangerUnsupportedFileType,
                                       kDangerousAccountCompromise};
-static_assert(base::size(kDangerStrings) == download::DOWNLOAD_DANGER_TYPE_MAX,
+static_assert(std::size(kDangerStrings) == download::DOWNLOAD_DANGER_TYPE_MAX,
               "kDangerStrings should have DOWNLOAD_DANGER_TYPE_MAX elements");
 
 const char* const kStateStrings[] = {
@@ -213,22 +213,22 @@
     kStateInterrupted,
     kStateInterrupted,
 };
-static_assert(base::size(kStateStrings) ==
+static_assert(std::size(kStateStrings) ==
                   download::DownloadItem::MAX_DOWNLOAD_STATE,
               "kStateStrings should have MAX_DOWNLOAD_STATE elements");
 
 const char* DangerString(download::DownloadDangerType danger) {
   DCHECK(danger >= 0);
   DCHECK(danger <
-         static_cast<download::DownloadDangerType>(base::size(kDangerStrings)));
+         static_cast<download::DownloadDangerType>(std::size(kDangerStrings)));
   if (danger < 0 || danger >= static_cast<download::DownloadDangerType>(
-                                  base::size(kDangerStrings)))
+                                  std::size(kDangerStrings)))
     return "";
   return kDangerStrings[danger];
 }
 
 download::DownloadDangerType DangerEnumFromString(const std::string& danger) {
-  for (size_t i = 0; i < base::size(kDangerStrings); ++i) {
+  for (size_t i = 0; i < std::size(kDangerStrings); ++i) {
     if (danger == kDangerStrings[i])
       return static_cast<download::DownloadDangerType>(i);
   }
@@ -238,16 +238,16 @@
 const char* StateString(download::DownloadItem::DownloadState state) {
   DCHECK(state >= 0);
   DCHECK(state < static_cast<download::DownloadItem::DownloadState>(
-                     base::size(kStateStrings)));
+                     std::size(kStateStrings)));
   if (state < 0 || state >= static_cast<download::DownloadItem::DownloadState>(
-                                base::size(kStateStrings)))
+                                std::size(kStateStrings)))
     return "";
   return kStateStrings[state];
 }
 
 download::DownloadItem::DownloadState StateEnumFromString(
     const std::string& state) {
-  for (size_t i = 0; i < base::size(kStateStrings); ++i) {
+  for (size_t i = 0; i < std::size(kStateStrings); ++i) {
     if ((kStateStrings[i] != NULL) && (state == kStateStrings[i]))
       return static_cast<DownloadItem::DownloadState>(i);
   }
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index 2d3a187..b32aea4 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 // Disable everything on windows only. http://crbug.com/306144
+#include "chrome/browser/extensions/api/downloads/downloads_api.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
@@ -12,7 +14,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/containers/circular_deque.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/guid.h"
 #include "base/json/json_reader.h"
@@ -32,7 +33,6 @@
 #include "chrome/browser/download/download_open_prompt.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/download/download_test_file_activity_observer.h"
-#include "chrome/browser/extensions/api/downloads/downloads_api.h"
 #include "chrome/browser/extensions/api/downloads_internal/downloads_internal_api.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_function_test_utils.h"
@@ -1174,7 +1174,7 @@
       {FILE_PATH_LITERAL("fake.txt"), DownloadItem::COMPLETE,
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS}};
   DownloadManager::DownloadVector all_downloads;
-  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo),
+  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo),
                                      &all_downloads));
 
   base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
@@ -1268,7 +1268,7 @@
       {FILE_PATH_LITERAL("baz"), DownloadItem::COMPLETE,
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS}};
   DownloadManager::DownloadVector all_downloads;
-  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo),
+  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo),
                                      &all_downloads));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
@@ -1329,7 +1329,7 @@
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS}};
   DownloadManager::DownloadVector items;
   ASSERT_TRUE(
-      CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo), &items));
+      CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
       new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
@@ -1359,7 +1359,7 @@
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS}};
   DownloadManager::DownloadVector items;
   ASSERT_TRUE(
-      CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo), &items));
+      CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
       new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
@@ -1393,7 +1393,7 @@
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS}};
   DownloadManager::DownloadVector items;
   ASSERT_TRUE(
-      CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo), &items));
+      CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(RunFunctionAndReturnResult(
       new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
@@ -1462,7 +1462,7 @@
   };
   DownloadManager::DownloadVector items;
   ASSERT_TRUE(
-      CreateHistoryDownloads(kHistoryInfo, base::size(kHistoryInfo), &items));
+      CreateHistoryDownloads(kHistoryInfo, std::size(kHistoryInfo), &items));
 
   std::unique_ptr<base::Value> result(
       RunFunctionAndReturnResult(new DownloadsSearchFunction(),
@@ -1950,7 +1950,7 @@
       "Access-Control-Request-Method",
   };
 
-  for (size_t index = 0; index < base::size(kUnsafeHeaders); ++index) {
+  for (size_t index = 0; index < std::size(kUnsafeHeaders); ++index) {
     std::string download_url = embedded_test_server()->GetURL("/slow?0").spec();
     EXPECT_STREQ(errors::kInvalidHeaderUnsafe,
                   RunFunctionAndReturnError(new DownloadsDownloadFunction(),
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
index 4de60d8..3dc23ce8 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc
@@ -10,7 +10,6 @@
 
 #include "ash/constants/ash_switches.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_writer.h"
 #include "base/path_service.h"
@@ -235,7 +234,7 @@
     // In order to use a prepared certificate, import a private key to the
     // user's token for which the Javscript test will import the certificate.
     ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8User,
-                                base::size(privateKeyPkcs8User),
+                                std::size(privateKeyPkcs8User),
                                 cert_db->GetPrivateSlot().get());
     std::move(done_callback).Run();
   }
@@ -255,7 +254,7 @@
     // Import a private key to the system slot.  The Javascript part of this
     // test has a prepared certificate for this key.
     ImportPrivateKeyPKCS8ToSlot(privateKeyPkcs8System,
-                                base::size(privateKeyPkcs8System),
+                                std::size(privateKeyPkcs8System),
                                 system_slot->slot());
   }
 
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
index d8013de..5d42a54 100644
--- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
+++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -891,7 +891,7 @@
     const NET_FW_PROFILE_TYPE2 kProfileTypes[] = {NET_FW_PROFILE2_PUBLIC,
                                                   NET_FW_PROFILE2_PRIVATE,
                                                   NET_FW_PROFILE2_DOMAIN};
-    for (size_t i = 0; i < base::size(kProfileTypes); ++i) {
+    for (size_t i = 0; i < std::size(kProfileTypes); ++i) {
       if ((profile_types & kProfileTypes[i]) != 0) {
         hr = firewall_policy_->get_FirewallEnabled(kProfileTypes[i], &enabled_);
         EXPECT_FALSE(FAILED(hr));
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 05d7e46a..14a8465 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,7 +7,6 @@
 #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"
@@ -68,8 +67,7 @@
        const_cast<char*>(service_name.data())},
       {kSecAccountItemAttr, static_cast<UInt32>(account_name.length()),
        const_cast<char*>(account_name.data())}};
-  SecKeychainAttributeList attribute_list = {base::size(attributes),
-                                             attributes};
+  SecKeychainAttributeList attribute_list = {std::size(attributes), attributes};
 
   base::ScopedCFTypeRef<SecAccessRef> access_ref;
   OSStatus status = CreateTargetAccess(base::SysUTF8ToNSString(service_name),
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
index cca0067..a6a6ca8 100644
--- a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
+++ b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
@@ -628,7 +628,7 @@
   // from setting and storing the size for the next iteration, resulting in test
   // flakiness.
   const gfx::Size kExpectedSizes[] = {maxSize, middleSize, minSize};
-  for (size_t i = 0; i < base::size(kExpectedSizes); i++) {
+  for (size_t i = 0; i < std::size(kExpectedSizes); i++) {
     content::WebContentsAddedObserver popup_observer;
     actions_bar->Press(extension->id());
     content::WebContents* popup = popup_observer.GetWebContents();
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index 181a5ac..84929283 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
 
 #include <stddef.h>
+
 #include <memory>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/metrics/histogram_functions.h"
@@ -533,7 +533,7 @@
     EXTENSION_FUNCTION_VALIDATE(list.size() == 4);
 
     int color_array[4] = {0};
-    for (size_t i = 0; i < base::size(color_array); ++i) {
+    for (size_t i = 0; i < std::size(color_array); ++i) {
       EXTENSION_FUNCTION_VALIDATE(list[i].is_int());
       color_array[i] = list[i].GetInt();
     }
diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc
index 029031ad..90caede2 100644
--- a/chrome/browser/extensions/api/gcm/gcm_api.cc
+++ b/chrome/browser/extensions/api/gcm/gcm_api.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/extensions/api/gcm/gcm_api.h"
 
 #include <stddef.h>
+
 #include <algorithm>
 #include <map>
 #include <memory>
@@ -12,7 +13,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/gcm/gcm_profile_service_factory.h"
@@ -72,10 +72,10 @@
 bool IsMessageKeyValid(const std::string& key) {
   std::string lower = base::ToLowerASCII(key);
   return !key.empty() &&
-         key.compare(0, base::size(kCollapseKey) - 1, kCollapseKey) != 0 &&
-         lower.compare(0, base::size(kGoogleRestrictedPrefix) - 1,
+         key.compare(0, std::size(kCollapseKey) - 1, kCollapseKey) != 0 &&
+         lower.compare(0, std::size(kGoogleRestrictedPrefix) - 1,
                        kGoogleRestrictedPrefix) != 0 &&
-         lower.compare(0, base::size(kGoogDotRestrictedPrefix),
+         lower.compare(0, std::size(kGoogDotRestrictedPrefix),
                        kGoogDotRestrictedPrefix) != 0;
 }
 
diff --git a/chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.cc b/chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.cc
index 78ca6fa..efd0baa9 100644
--- a/chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/extensions/api/identity/identity_clear_all_cached_auth_tokens_function.h"
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/extensions/api/identity/identity_api.h"
@@ -60,7 +59,7 @@
     uint32_t num_deleted) {
   ++cleaned_partitions_;
 
-  if (cleaned_partitions_ < base::size(kPartitionsToClean))
+  if (cleaned_partitions_ < std::size(kPartitionsToClean))
     return;
 
   // Post a task to ensure Respond() is not synchronously called from Run(). The
diff --git a/chrome/browser/extensions/api/messaging/messaging_apitest.cc b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
index eccf33db..0c59753 100644
--- a/chrome/browser/extensions/api/messaging/messaging_apitest.cc
+++ b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
@@ -10,7 +10,6 @@
 
 #include "base/base64.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
@@ -319,7 +318,7 @@
 
     // Turn the array into a JS array, which effectively gets eval()ed.
     std::string as_js_array;
-    for (size_t i = 0; i < base::size(non_messaging_apis); ++i) {
+    for (size_t i = 0; i < std::size(non_messaging_apis); ++i) {
       as_js_array += as_js_array.empty() ? "[" : ",";
       as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]);
     }
diff --git a/chrome/browser/extensions/api/messaging/native_message_echo_host.cc b/chrome/browser/extensions/api/messaging/native_message_echo_host.cc
index 7d8c359..6b4a0ed 100644
--- a/chrome/browser/extensions/api/messaging/native_message_echo_host.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_echo_host.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/task/single_thread_task_runner.h"
@@ -28,7 +27,7 @@
     "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"};
 
 // static
-const size_t NativeMessageEchoHost::kOriginCount = base::size(kOrigins);
+const size_t NativeMessageEchoHost::kOriginCount = std::size(kOrigins);
 
 // static
 std::unique_ptr<NativeMessageHost> NativeMessageEchoHost::Create(
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
index 3ea7845f..9ed2ea9a 100644
--- a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
@@ -2,13 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/messaging/native_message_host.h"
-
 #include <memory>
 #include <string>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "chrome/browser/ash/arc/extensions/arc_support_message_host.h"
 #include "chrome/browser/ash/drive/drivefs_native_message_host.h"
 #include "chrome/browser/ash/guest_os/vm_sk_forwarding_native_message_host.h"
@@ -19,6 +16,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "extensions/browser/api/messaging/native_message_host.h"
 #include "remoting/host/it2me/it2me_native_messaging_host_allowed_origins.h"
 #include "remoting/host/it2me/it2me_native_messaging_host_chromeos.h"
 
@@ -56,6 +54,6 @@
      &ash::guest_os::VmSKForwardingNativeMessageHost::CreateFromExtension},
 };
 
-const size_t kBuiltInHostsCount = base::size(kBuiltInHosts);
+const size_t kBuiltInHostsCount = std::size(kBuiltInHosts);
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_lacros.cc b/chrome/browser/extensions/api/messaging/native_message_host_lacros.cc
index 27daafc..ac3eebc 100644
--- a/chrome/browser/extensions/api/messaging/native_message_host_lacros.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_host_lacros.cc
@@ -2,17 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/messaging/native_message_host.h"
-
 #include <memory>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "chrome/browser/extensions/api/messaging/native_message_built_in_host.h"
 #include "chrome/browser/extensions/api/messaging/native_message_echo_host.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "extensions/browser/api/messaging/native_message_host.h"
 #include "remoting/host/it2me/it2me_native_messaging_host_allowed_origins.h"
 #include "remoting/host/it2me/it2me_native_messaging_host_lacros.h"
 
@@ -35,6 +33,6 @@
      remoting::kIt2MeOriginsSize, &CreateIt2MeHost},
 };
 
-const size_t kBuiltInHostsCount = base::size(kBuiltInHosts);
+const size_t kBuiltInHostsCount = std::size(kBuiltInHosts);
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
index 9937f4f..6a2b3a1 100644
--- a/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
+++ b/chrome/browser/extensions/api/metrics_private/metrics_apitest.cc
@@ -6,7 +6,6 @@
 
 #include <map>
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/statistics_recorder.h"
@@ -84,7 +83,7 @@
 void ValidateSparseHistogramSamples(
     const std::string& name,
     const base::HistogramSamples& samples) {
-  for (unsigned int i = 0; i < base::size(g_sparse_histograms); ++i) {
+  for (unsigned int i = 0; i < std::size(g_sparse_histograms); ++i) {
     const SparseHistogram& sparse_histogram = g_sparse_histograms[i];
     if (std::string(name) == sparse_histogram.name) {
       for (int j = 0; j < sparse_histogram.bucket_count; ++j) {
@@ -163,8 +162,8 @@
       << message_;
 
   ValidateUserActions(user_action_tester, g_user_actions,
-                      base::size(g_user_actions));
-  ValidateHistograms(g_histograms, base::size(g_histograms));
+                      std::size(g_user_actions));
+  ValidateHistograms(g_histograms, std::size(g_histograms));
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
index fbfea73..78ac860b 100644
--- a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
+++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
@@ -503,7 +503,7 @@
   if (net::IsCertificateError(verify_result)) {
     // Only report errors, not internal informational statuses.
     const int masked_cert_status = cert_status & net::CERT_STATUS_ALL_ERRORS;
-    for (size_t i = 0; i < base::size(kCertStatusErrors); ++i) {
+    for (size_t i = 0; i < std::size(kCertStatusErrors); ++i) {
       if ((masked_cert_status & kCertStatusErrors[i].value) ==
           kCertStatusErrors[i].value) {
         result.debug_errors.push_back(kCertStatusErrors[i].name);
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc
index 2717d52..a743bc5 100644
--- a/chrome/browser/extensions/api/preference/preference_api.cc
+++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -339,8 +339,8 @@
       event_mapping_[pref.browser_pref] =
           PrefMapData(event_name, pref.read_permission, pref.write_permission);
     }
-    DCHECK_EQ(base::size(kPrefMapping), mapping_.size());
-    DCHECK_EQ(base::size(kPrefMapping), event_mapping_.size());
+    DCHECK_EQ(std::size(kPrefMapping), mapping_.size());
+    DCHECK_EQ(std::size(kPrefMapping), event_mapping_.size());
     RegisterPrefTransformer(proxy_config::prefs::kProxy,
                             std::make_unique<ProxyPrefTransformer>());
     RegisterPrefTransformer(prefs::kCookieControlsMode,
diff --git a/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc b/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
index d3f220d..ad7f053 100644
--- a/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
+++ b/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
@@ -135,7 +134,7 @@
     job.content_type = "application/pdf";
     const unsigned char kDocumentBytes[] = {'b', 'y', 't', 'e', 's'};
     job.document_bytes =
-        new base::RefCountedBytes(kDocumentBytes, base::size(kDocumentBytes));
+        new base::RefCountedBytes(kDocumentBytes, std::size(kDocumentBytes));
 
     PrinterProviderAPIFactory::GetInstance()
         ->GetForBrowserContext(profile())
diff --git a/chrome/browser/extensions/api/printing/print_job_controller.cc b/chrome/browser/extensions/api/printing/print_job_controller.cc
index 8e83b6cf..c73312e7 100644
--- a/chrome/browser/extensions/api/printing/print_job_controller.cc
+++ b/chrome/browser/extensions/api/printing/print_job_controller.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/printing/printer_query.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/common/child_process_host.h"
 #include "printing/metafile_skia.h"
 #include "printing/print_settings.h"
@@ -40,8 +41,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   auto query = std::make_unique<printing::PrinterQuery>(
-      content::ChildProcessHost::kInvalidUniqueID,
-      content::ChildProcessHost::kInvalidUniqueID);
+      content::GlobalRenderFrameHostId());
   auto* query_ptr = query.get();
   query_ptr->SetSettingsFromPOD(
       std::move(settings),
diff --git a/chrome/browser/extensions/api/proxy/proxy_api_constants.cc b/chrome/browser/extensions/api/proxy/proxy_api_constants.cc
index 443160ab..6a50852 100644
--- a/chrome/browser/extensions/api/proxy/proxy_api_constants.cc
+++ b/chrome/browser/extensions/api/proxy/proxy_api_constants.cc
@@ -5,7 +5,8 @@
 // Constants for the Chrome Extensions Proxy Settings API.
 
 #include "chrome/browser/extensions/api/proxy/proxy_api_constants.h"
-#include "base/cxx17_backports.h"
+
+#include <iterator>
 
 namespace extensions {
 namespace proxy_api_constants {
@@ -43,9 +44,9 @@
 
 static_assert(SCHEME_MAX == SCHEME_FALLBACK,
               "SCHEME_MAX is incorrect");
-static_assert(base::size(field_name) == SCHEME_MAX + 1,
+static_assert(std::size(field_name) == SCHEME_MAX + 1,
               "field_name array size is incorrect");
-static_assert(base::size(scheme_name) == SCHEME_MAX + 1,
+static_assert(std::size(scheme_name) == SCHEME_MAX + 1,
               "scheme_name array size is incorrect");
 static_assert(SCHEME_ALL == 0, "SCHEME_ALL must be the first value");
 
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
index 853fc2d..6531d77 100644
--- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -10,7 +10,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/strings/pattern.h"
@@ -129,7 +128,7 @@
       return testing::AssertionFailure()
              << "window dictionary does not contain a tabs list entry";
     }
-    EXPECT_EQ(base::size(kTabIDs), tabs->GetListDeprecated().size());
+    EXPECT_EQ(std::size(kTabIDs), tabs->GetListDeprecated().size());
     for (size_t j = 0; j < tabs->GetListDeprecated().size(); ++j) {
       const base::Value::DictStorage tab =
           utils::ToDictionary(tabs->GetListDeprecated()[j]);
@@ -228,12 +227,12 @@
 
   const base::Time time_now = base::Time::Now();
   syncer::SyncDataList initial_data;
-  for (size_t index = 0; index < base::size(kSessionTags); ++index) {
+  for (size_t index = 0; index < std::size(kSessionTags); ++index) {
     // Fill an instance of session specifics with a foreign session's data.
     sync_pb::EntitySpecifics header_entity;
     BuildSessionSpecifics(kSessionTags[index], header_entity.mutable_session());
     std::vector<SessionID::id_type> tab_list(kTabIDs,
-                                             kTabIDs + base::size(kTabIDs));
+                                             kTabIDs + std::size(kTabIDs));
     BuildWindowSpecifics(index, tab_list, header_entity.mutable_session());
     std::vector<sync_pb::SessionSpecifics> tabs(tab_list.size());
     for (size_t i = 0; i < tab_list.size(); ++i) {
diff --git a/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc b/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc
index e6b21d8..5495c70 100644
--- a/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc
+++ b/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -97,7 +96,7 @@
   ASSERT_TRUE(prefs);
   const GURL urls[] = {GURL("http://foo"), GURL("http://bar")};
   SessionStartupPref startup_pref(SessionStartupPref::LAST);
-  startup_pref.urls.assign(urls, urls + base::size(urls));
+  startup_pref.urls.assign(urls, urls + std::size(urls));
   SessionStartupPref::SetStartupPref(prefs, startup_pref);
 
   const extensions::Extension* extension = LoadExtension(
@@ -110,8 +109,7 @@
   UnloadExtension(extension->id());
   startup_pref = SessionStartupPref::GetStartupPref(prefs);
   EXPECT_EQ(SessionStartupPref::LAST, startup_pref.type);
-  EXPECT_EQ(std::vector<GURL>(urls, urls + base::size(urls)),
-            startup_pref.urls);
+  EXPECT_EQ(std::vector<GURL>(urls, urls + std::size(urls)), startup_pref.urls);
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OverrideDSE) {
diff --git a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
index 3fe70ff..499e747 100644
--- a/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/udp_socket_unittest.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
@@ -64,7 +63,7 @@
 }
 
 static const char kTestMessage[] = "$$TESTMESSAGETESTMESSAGETESTMESSAGETEST$$";
-static const int kTestMessageLength = base::size(kTestMessage);
+static const int kTestMessageLength = std::size(kTestMessage);
 
 net::AddressList CreateAddressList(const char* address_string, int port) {
   net::IPAddress ip;
diff --git a/chrome/browser/extensions/api/system_private/system_private_api.cc b/chrome/browser/extensions/api/system_private/system_private_api.cc
index 512f9df9..abd18e42 100644
--- a/chrome/browser/extensions/api/system_private/system_private_api.cc
+++ b/chrome/browser/extensions/api/system_private/system_private_api.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -61,7 +60,7 @@
   int value = prefs->GetInteger(prefs::kIncognitoModeAvailability);
   EXTENSION_FUNCTION_VALIDATE(
       value >= 0 &&
-      value < static_cast<int>(base::size(kIncognitoModeAvailabilityStrings)));
+      value < static_cast<int>(std::size(kIncognitoModeAvailabilityStrings)));
   return RespondNow(
       OneArgument(base::Value(kIncognitoModeAvailabilityStrings[value])));
 }
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
index 82f50d22..005577b 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -284,8 +284,8 @@
   std::string tab_titles[] = {"", "Sample title", "Sample title"};
 
   // Add 3 web contentses to the browser.
-  content::WebContents* web_contentses[base::size(tab_urls)];
-  for (size_t i = 0; i < base::size(tab_urls); ++i) {
+  content::WebContents* web_contentses[std::size(tab_urls)];
+  for (size_t i = 0; i < std::size(tab_urls); ++i) {
     std::unique_ptr<content::WebContents> web_contents =
         content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
     content::WebContents* raw_web_contents = web_contents.get();
@@ -345,8 +345,8 @@
   std::string tab_titles[] = {"", "Sample title", "Sample title"};
 
   // Add 3 web contentses to the browser.
-  content::WebContents* web_contentses[base::size(tab_urls)];
-  for (size_t i = 0; i < base::size(tab_urls); ++i) {
+  content::WebContents* web_contentses[std::size(tab_urls)];
+  for (size_t i = 0; i < std::size(tab_urls); ++i) {
     std::unique_ptr<content::WebContents> web_contents =
         content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
     content::WebContents* raw_web_contents = web_contents.get();
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index 32f7b1aa..f7917c18 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -2136,7 +2136,7 @@
         new_contents->GetMainFrame()->GetLastCommittedOrigin().opaque();
     EXPECT_EQ(test_case.expected_origin_str == "null", is_opaque_origin);
   };
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     const auto& test_case = test_cases[i];
     SCOPED_TRACE(
         base::StringPrintf("#%" PRIuS " %s", i, test_case.url.c_str()));
diff --git a/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc b/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
index dff0963d..672728ad 100644
--- a/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
+++ b/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
@@ -7,7 +7,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
@@ -285,7 +284,7 @@
   EXPECT_EQ(1, test_client_->send_packet_counter_);
   EXPECT_EQ(api_vpn::VPN_CONNECTION_STATE_CONNECTED,
             test_client_->update_connection_state_counter_);
-  for (size_t i = 0; i < base::size(kParameterValues); ++i) {
+  for (size_t i = 0; i < std::size(kParameterValues); ++i) {
     const std::string* value =
         test_client_->parameters_.FindStringKey(kParameterKeys[i]);
     ASSERT_TRUE(value);
diff --git a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
index 6d181e98..975a828 100644
--- a/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
+++ b/chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "chrome/common/url_constants.h"
 #include "content/public/browser/render_frame_host.h"
@@ -40,7 +39,7 @@
 
 // static
 bool FrameNavigationState::IsValidUrl(const GURL& url) {
-  for (unsigned i = 0; i < base::size(kValidSchemes); ++i) {
+  for (unsigned i = 0; i < std::size(kValidSchemes); ++i) {
     if (url.scheme() == kValidSchemes[i])
       return true;
   }
diff --git a/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc
index e2db12d..6563545 100644
--- a/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/web_request/web_request_event_details.h"
-
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "extensions/browser/api/web_request/web_request_api_constants.h"
 #include "extensions/browser/api/web_request/web_request_api_helpers.h"
+#include "extensions/browser/api/web_request/web_request_event_details.h"
 #include "extensions/browser/api/web_request/web_request_info.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/http/http_response_headers.h"
@@ -68,7 +66,7 @@
   EXPECT_EQ("http://www.foo.bar/", url);
 
   // Extras are filtered out (+1 for url).
-  EXPECT_EQ(base::size(safe_attributes) + 1, copy->dict_.DictSize());
+  EXPECT_EQ(std::size(safe_attributes) + 1, copy->dict_.DictSize());
 }
 
 TEST(WebRequestEventDetailsTest, SetResponseHeaders) {
diff --git a/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc b/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
index ef61190..235ae45 100644
--- a/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
+++ b/chrome/browser/extensions/api/webstore_private/webstore_private_unittest.cc
@@ -18,6 +18,7 @@
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/web_contents_tester.h"
 #include "extensions/browser/api_test_utils.h"
diff --git a/chrome/browser/extensions/blocklist.cc b/chrome/browser/extensions/blocklist.cc
index 3cf123c..f66ada1a 100644
--- a/chrome/browser/extensions/blocklist.cc
+++ b/chrome/browser/extensions/blocklist.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/buildflags.h"
+#include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/db/util.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
@@ -165,16 +166,6 @@
   blocklist_->RemoveObserver(this);
 }
 
-Blocklist::ScopedDatabaseManagerForTest::ScopedDatabaseManagerForTest(
-    scoped_refptr<SafeBrowsingDatabaseManager> database_manager)
-    : original_(GetDatabaseManager()) {
-  SetDatabaseManager(database_manager);
-}
-
-Blocklist::ScopedDatabaseManagerForTest::~ScopedDatabaseManagerForTest() {
-  SetDatabaseManager(original_);
-}
-
 Blocklist::Blocklist(ExtensionPrefs* prefs) {
   auto& lazy_database_manager = g_database_manager.Get();
   // Using base::Unretained is safe because when this object goes away, the
diff --git a/chrome/browser/extensions/blocklist.h b/chrome/browser/extensions/blocklist.h
index 7b5214e..c1a02a8 100644
--- a/chrome/browser/extensions/blocklist.h
+++ b/chrome/browser/extensions/blocklist.h
@@ -18,13 +18,16 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "extensions/browser/blocklist_state.h"
 
 namespace content {
 class BrowserContext;
 }
 
+namespace safe_browsing {
+class SafeBrowsingDatabaseManager;
+}
+
 namespace extensions {
 
 class BlocklistStateFetcher;
@@ -47,22 +50,6 @@
     raw_ptr<Blocklist> blocklist_;
   };
 
-  class ScopedDatabaseManagerForTest {
-   public:
-    explicit ScopedDatabaseManagerForTest(
-        scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
-            database_manager);
-
-    ScopedDatabaseManagerForTest(const ScopedDatabaseManagerForTest&) = delete;
-    ScopedDatabaseManagerForTest& operator=(
-        const ScopedDatabaseManagerForTest&) = delete;
-
-    ~ScopedDatabaseManagerForTest();
-
-   private:
-    scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> original_;
-  };
-
   using BlocklistStateMap = std::map<std::string, BlocklistState>;
 
   using GetBlocklistedIDsCallback =
@@ -124,6 +111,8 @@
   void RemoveObserver(Observer* observer);
 
  private:
+  friend class ScopedDatabaseManagerForTest;
+
   // Use via ScopedDatabaseManagerForTest.
   static void SetDatabaseManager(
       scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
diff --git a/chrome/browser/extensions/blocklist_unittest.cc b/chrome/browser/extensions/blocklist_unittest.cc
index e51e74c8..b078f93 100644
--- a/chrome/browser/extensions/blocklist_unittest.cc
+++ b/chrome/browser/extensions/blocklist_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/extensions/blocklist_state_fetcher.h"
 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
+#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
 #include "chrome/browser/extensions/test_blocklist.h"
 #include "chrome/browser/extensions/test_blocklist_state_fetcher.h"
 #include "chrome/browser/extensions/test_extension_prefs.h"
@@ -142,7 +143,7 @@
   Blocklist blocklist(prefs());
   scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db(
       new FakeSafeBrowsingDatabaseManager(true));
-  Blocklist::ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
+  ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
 
   std::string a = AddExtension("a");
   std::string b = AddExtension("b");
diff --git a/chrome/browser/extensions/chrome_app_sorting.cc b/chrome/browser/extensions/chrome_app_sorting.cc
index b6c693e..ac84c48 100644
--- a/chrome/browser/extensions/chrome_app_sorting.cc
+++ b/chrome/browser/extensions/chrome_app_sorting.cc
@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "build/build_config.h"
@@ -693,7 +692,7 @@
       extensions::kWebStoreAppId,
   };
   const std::vector<const char*> app_ids(
-      kDefaultAppOrder, kDefaultAppOrder + base::size(kDefaultAppOrder));
+      kDefaultAppOrder, kDefaultAppOrder + std::size(kDefaultAppOrder));
 #endif
 
   syncer::StringOrdinal page_ordinal = CreateFirstAppPageOrdinal();
diff --git a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
index 4eb2520..3ba07a0 100644
--- a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
+++ b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
@@ -104,7 +104,7 @@
   AddComponentResourceEntries(kComponentExtensionResources,
                               kComponentExtensionResourcesSize);
   AddComponentResourceEntries(kExtraComponentExtensionResources,
-                              base::size(kExtraComponentExtensionResources));
+                              std::size(kExtraComponentExtensionResources));
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Add Files app JS modules resources.
diff --git a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
index 952f3be5..73e2500 100644
--- a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
+++ b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "build/branding_buildflags.h"
@@ -45,7 +44,7 @@
 #endif
   };
 
-  for (size_t i = 0; i < base::size(kAllowed); ++i) {
+  for (size_t i = 0; i < std::size(kAllowed); ++i) {
     if (extension_id == kAllowed[i])
       return true;
   }
@@ -111,7 +110,7 @@
       extension_misc::kSwitchAccessExtensionId,
   };
 
-  for (size_t i = 0; i < base::size(kAllowed); ++i) {
+  for (size_t i = 0; i < std::size(kAllowed); ++i) {
     if (extension_id == kAllowed[i])
       return true;
   }
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index 407ab7c8..fab4522 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -11,7 +11,6 @@
 
 #include "base/at_exit.h"
 #include "base/bind.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"
@@ -32,6 +31,7 @@
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
 #include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h"
+#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
 #include "chrome/browser/extensions/scripting_permissions_modifier.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
@@ -528,7 +528,7 @@
 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) {
   const bool kTestData[] = {false, true};
 
-  for (size_t i = 0; i < base::size(kTestData); ++i) {
+  for (size_t i = 0; i < std::size(kTestData); ++i) {
     std::unique_ptr<MockPromptProxy> mock_prompt =
         CreateMockPromptProxyForBrowser(browser());
 
@@ -645,7 +645,7 @@
 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blocklist) {
   scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db(
       new FakeSafeBrowsingDatabaseManager(true));
-  Blocklist::ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
+  ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
 
   const std::string extension_id = "gllekhaobjnhgeagipipnkpmmmpchacm";
   blocklist_db->SetUnsafe(extension_id);
diff --git a/chrome/browser/extensions/extension_management_constants.cc b/chrome/browser/extensions/extension_management_constants.cc
index 352ace3..e664f84 100644
--- a/chrome/browser/extensions/extension_management_constants.cc
+++ b/chrome/browser/extensions/extension_management_constants.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/extensions/extension_management_constants.h"
 
-#include "base/cxx17_backports.h"
-
 namespace extensions {
 namespace schema_constants {
 
@@ -56,7 +54,7 @@
     // ExtensionAllowedTypes policy.
 };
 
-const size_t kAllowedTypesMapSize = base::size(kAllowedTypesMap);
+const size_t kAllowedTypesMapSize = std::size(kAllowedTypesMap);
 
 Manifest::Type GetManifestType(const std::string& name) {
   for (size_t index = 0; index < kAllowedTypesMapSize; ++index) {
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc
index 881d2bb6..d428cc5 100644
--- a/chrome/browser/extensions/extension_protocols_unittest.cc
+++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
@@ -405,7 +404,7 @@
       {"split enabled", true, true, true, false},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     scoped_refptr<Extension> extension =
         CreateTestExtension(cases[i].name, cases[i].incognito_split_mode);
     AddExtension(extension, cases[i].incognito_enabled, false);
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 2e4abd7..c40f07db 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -17,7 +17,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_file_value_serializer.h"
@@ -70,6 +69,7 @@
 #include "chrome/browser/extensions/permissions_updater.h"
 #include "chrome/browser/extensions/plugin_manager.h"
 #include "chrome/browser/extensions/preinstalled_apps.h"
+#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
 #include "chrome/browser/extensions/test_blocklist.h"
 #include "chrome/browser/extensions/test_extension_system.h"
 #include "chrome/browser/extensions/unpacked_installer.h"
@@ -2198,7 +2198,7 @@
     base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
   };
 
-  for (size_t i = 0; i < base::size(punctuated_names); ++i) {
+  for (size_t i = 0; i < std::size(punctuated_names); ++i) {
     SCOPED_TRACE(punctuated_names[i].value().c_str());
     base::FilePath output_dir = temp_dir.GetPath().Append(punctuated_names[i]);
 
@@ -3508,7 +3508,7 @@
 TEST_F(ExtensionServiceTest, BlocklistedExtensionWillNotInstall) {
   scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db(
       new FakeSafeBrowsingDatabaseManager(true));
-  Blocklist::ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
+  ScopedDatabaseManagerForTest scoped_blocklist_db(blocklist_db);
 
   InitializeEmptyExtensionService();
   service()->Init();
@@ -7014,7 +7014,7 @@
       {page_action, "1.0.0.0", "page_action.crx"},
       {minimal_platform_app_crx, "0.1", "minimal_platform_app.crx"}};
 
-  for (size_t i = 0; i < base::size(extension_info); ++i) {
+  for (size_t i = 0; i < std::size(extension_info); ++i) {
     reg_provider->UpdateOrAddExtension(
         extension_info[i][0], extension_info[i][1],
         data_dir().AppendASCII(extension_info[i][2]));
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index e69904ef..88e14de 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
+
 #include <stddef.h>
 
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/extensions/extension_special_storage_policy.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/content_settings/core/common/content_settings.h"
@@ -370,8 +370,8 @@
     SpecialStoragePolicy::STORAGE_UNLIMITED,
   };
 
-  ASSERT_EQ(base::size(apps), base::size(change_flags));
-  for (size_t i = 0; i < base::size(apps); ++i) {
+  ASSERT_EQ(std::size(apps), std::size(change_flags));
+  for (size_t i = 0; i < std::size(apps); ++i) {
     SCOPED_TRACE(testing::Message() << "i: " << i);
     observer.ExpectGrant(apps[i]->id(), change_flags[i]);
     policy_->GrantRightsForExtension(apps[i].get());
@@ -379,14 +379,14 @@
     EXPECT_TRUE(observer.IsCompleted());
   }
 
-  for (size_t i = 0; i < base::size(apps); ++i) {
+  for (size_t i = 0; i < std::size(apps); ++i) {
     SCOPED_TRACE(testing::Message() << "i: " << i);
     policy_->GrantRightsForExtension(apps[i].get());
     base::RunLoop().RunUntilIdle();
     EXPECT_TRUE(observer.IsCompleted());
   }
 
-  for (size_t i = 0; i < base::size(apps); ++i) {
+  for (size_t i = 0; i < std::size(apps); ++i) {
     SCOPED_TRACE(testing::Message() << "i: " << i);
     observer.ExpectRevoke(apps[i]->id(), change_flags[i]);
     policy_->RevokeRightsForExtension(apps[i].get());
@@ -394,7 +394,7 @@
     EXPECT_TRUE(observer.IsCompleted());
   }
 
-  for (size_t i = 0; i < base::size(apps); ++i) {
+  for (size_t i = 0; i < std::size(apps); ++i) {
     SCOPED_TRACE(testing::Message() << "i: " << i);
     policy_->RevokeRightsForExtension(apps[i].get());
     base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/extensions/install_signer.cc b/chrome/browser/extensions/install_signer.cc
index b958b7e..e693fcd 100644
--- a/chrome/browser/extensions/install_signer.cc
+++ b/chrome/browser/extensions/install_signer.cc
@@ -101,7 +101,7 @@
   hash->Update(salt.data(), salt.size());
 
   std::string result_bytes(crypto::kSHA256Length, 0);
-  hash->Finish(base::data(result_bytes), result_bytes.size());
+  hash->Finish(std::data(result_bytes), result_bytes.size());
 
   base::Base64Encode(result_bytes, result);
   return true;
@@ -291,7 +291,7 @@
   }
 
   salt_ = std::string(kSaltBytes, 0);
-  crypto::RandBytes(base::data(salt_), salt_.size());
+  crypto::RandBytes(std::data(salt_), salt_.size());
 
   std::string hash_base64;
   if (!HashWithMachineId(salt_, &hash_base64)) {
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index afdbb22..37b0cc6 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -28,6 +28,7 @@
 #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 "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/common/url_constants.h"
diff --git a/chrome/browser/extensions/permission_messages_unittest.cc b/chrome/browser/extensions/permission_messages_unittest.cc
index 90fdb4a..19c2a547 100644
--- a/chrome/browser/extensions/permission_messages_unittest.cc
+++ b/chrome/browser/extensions/permission_messages_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/permissions_test_util.h"
@@ -344,7 +343,7 @@
   EXPECT_EQ(kMessage, messages.front().message());
   const std::vector<std::u16string>& submessages =
       messages.front().submessages();
-  ASSERT_EQ(base::size(kDetails), submessages.size());
+  ASSERT_EQ(std::size(kDetails), submessages.size());
   for (size_t i = 0; i < submessages.size(); i++)
     EXPECT_EQ(base::ASCIIToUTF16(kDetails[i]), submessages[i]);
 }
diff --git a/chrome/browser/extensions/preinstalled_apps.cc b/chrome/browser/extensions/preinstalled_apps.cc
index cd69b01..5808bc8a 100644
--- a/chrome/browser/extensions/preinstalled_apps.cc
+++ b/chrome/browser/extensions/preinstalled_apps.cc
@@ -10,7 +10,6 @@
 #include <set>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/browser_process.h"
@@ -41,7 +40,7 @@
   // an API. See http://crbug.com/101357
   const std::string& locale = g_browser_process->GetApplicationLocale();
   static const char* const unsupported_locales[] = {"CN", "TR", "IR"};
-  for (size_t i = 0; i < base::size(unsupported_locales); ++i) {
+  for (size_t i = 0; i < std::size(unsupported_locales); ++i) {
     if (base::EndsWith(locale, unsupported_locales[i],
                        base::CompareCase::INSENSITIVE_ASCII)) {
       return false;
diff --git a/chrome/browser/extensions/process_manager_browsertest.cc b/chrome/browser/extensions/process_manager_browsertest.cc
index 9bfc3b8..8f5b135 100644
--- a/chrome/browser/extensions/process_manager_browsertest.cc
+++ b/chrome/browser/extensions/process_manager_browsertest.cc
@@ -875,7 +875,7 @@
 
   // Navigate the popup to each nested URL with extension origin.
   GURL nested_urls[] = {blob_url, filesystem_url};
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     EXPECT_TRUE(ExecuteScript(
         popup, "location.href = '" + nested_urls[i].spec() + "';"));
 
@@ -908,7 +908,7 @@
 
   // Navigate second subframe to each nested URL from the main frame (i.e.,
   // from non-extension process).  These should be canceled.
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame2", nested_urls[i]));
     content::RenderFrameHost* second_frame = ChildFrameAt(main_frame, 1);
 
@@ -1047,7 +1047,7 @@
   // Navigate second subframe to each nested URL from the main frame (i.e.,
   // from non-extension process).  These should be canceled.
   GURL nested_urls[] = {blob_url, filesystem_url};
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame2", nested_urls[i]));
     content::RenderFrameHost* second_frame = ChildFrameAt(main_frame, 1);
 
@@ -1094,7 +1094,7 @@
   // From the main frame, navigate its subframe to each nested URL.  This
   // should be allowed and should stay in the extension process.
   GURL nested_urls[] = {blob_url, filesystem_url};
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     EXPECT_TRUE(content::NavigateIframeToURL(tab, "frame0", nested_urls[i]));
     content::RenderFrameHost* child = ChildFrameAt(main_frame, 0);
     EXPECT_EQ(nested_urls[i], child->GetLastCommittedURL());
@@ -1231,7 +1231,7 @@
   // Try navigating the web tab to each nested URL with the app's origin.  This
   // should be blocked.
   GURL nested_urls[] = {blob_url, filesystem_url};
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     content::TestNavigationObserver observer(web_tab);
     EXPECT_TRUE(ExecuteScript(
         web_tab, "location.href = '" + nested_urls[i].spec() + "';"));
@@ -1348,7 +1348,7 @@
   // Attempt opening the nested urls using window.open(url, '', 'noopener').
   // This should not be allowed.
   GURL nested_urls[] = {blob_url, filesystem_url};
-  for (size_t i = 0; i < base::size(nested_urls); i++) {
+  for (size_t i = 0; i < std::size(nested_urls); i++) {
     content::WebContents* new_popup =
         OpenPopupNoOpener(tab->GetMainFrame(), nested_urls[i]);
 
diff --git a/chrome/browser/extensions/scoped_database_manager_for_test.cc b/chrome/browser/extensions/scoped_database_manager_for_test.cc
new file mode 100644
index 0000000..813ec55c8
--- /dev/null
+++ b/chrome/browser/extensions/scoped_database_manager_for_test.cc
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
+
+#include "chrome/browser/extensions/blocklist.h"
+#include "components/safe_browsing/core/browser/db/database_manager.h"
+
+using safe_browsing::SafeBrowsingDatabaseManager;
+
+namespace extensions {
+
+ScopedDatabaseManagerForTest::ScopedDatabaseManagerForTest(
+    scoped_refptr<SafeBrowsingDatabaseManager> database_manager)
+    : original_(Blocklist::GetDatabaseManager()) {
+  Blocklist::SetDatabaseManager(database_manager);
+}
+
+ScopedDatabaseManagerForTest::~ScopedDatabaseManagerForTest() {
+  Blocklist::SetDatabaseManager(original_);
+}
+
+}  // namespace extensions
diff --git a/chrome/browser/extensions/scoped_database_manager_for_test.h b/chrome/browser/extensions/scoped_database_manager_for_test.h
new file mode 100644
index 0000000..9598c7f
--- /dev/null
+++ b/chrome/browser/extensions/scoped_database_manager_for_test.h
@@ -0,0 +1,31 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_SCOPED_DATABASE_MANAGER_FOR_TEST_H_
+#define CHROME_BROWSER_EXTENSIONS_SCOPED_DATABASE_MANAGER_FOR_TEST_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "components/safe_browsing/core/browser/db/database_manager.h"
+
+namespace extensions {
+
+class ScopedDatabaseManagerForTest {
+ public:
+  explicit ScopedDatabaseManagerForTest(
+      scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+          database_manager);
+
+  ScopedDatabaseManagerForTest(const ScopedDatabaseManagerForTest&) = delete;
+  ScopedDatabaseManagerForTest& operator=(const ScopedDatabaseManagerForTest&) =
+      delete;
+
+  ~ScopedDatabaseManagerForTest();
+
+ private:
+  scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> original_;
+};
+
+}  // namespace extensions
+
+#endif  // CHROME_BROWSER_EXTENSIONS_SCOPED_DATABASE_MANAGER_FOR_TEST_H_
diff --git a/chrome/browser/extensions/test_blocklist.h b/chrome/browser/extensions/test_blocklist.h
index 9c112c9..432106f 100644
--- a/chrome/browser/extensions/test_blocklist.h
+++ b/chrome/browser/extensions/test_blocklist.h
@@ -11,6 +11,7 @@
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/extensions/blocklist.h"
 #include "chrome/browser/extensions/blocklist_state_fetcher.h"
+#include "chrome/browser/extensions/scoped_database_manager_for_test.h"
 
 namespace extensions {
 
@@ -89,7 +90,7 @@
 
   scoped_refptr<FakeSafeBrowsingDatabaseManager> blocklist_db_;
 
-  Blocklist::ScopedDatabaseManagerForTest scoped_blocklist_db_;
+  ScopedDatabaseManagerForTest scoped_blocklist_db_;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc
index caeb67b..2ab11aa 100644
--- a/chrome/browser/extensions/updater/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -2150,8 +2150,8 @@
     // rollcall and active pings.
     int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
 
-    for (size_t i = 0; i < base::size(ping_cases); i++) {
-      for (size_t j = 0; j < base::size(ping_cases); j++) {
+    for (size_t i = 0; i < std::size(ping_cases); i++) {
+      for (size_t j = 0; j < std::size(ping_cases); j++) {
         for (size_t k = 0; k < 2; k++) {
           int rollcall_ping_days = ping_cases[i];
           int active_ping_days = ping_cases[j];
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc
index c095682a..dd22edd 100644
--- a/chrome/browser/external_protocol/external_protocol_handler.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc
@@ -320,13 +320,13 @@
   }
 
   // Always block the hard-coded denied schemes.
-  for (size_t i = 0; i < base::size(kDeniedSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kDeniedSchemes); ++i) {
     if (kDeniedSchemes[i] == scheme)
       return BLOCK;
   }
 
   // Always allow the hard-coded allowed schemes.
-  for (size_t i = 0; i < base::size(kAllowedSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kAllowedSchemes); ++i) {
     if (kAllowedSchemes[i] == scheme)
       return DONT_BLOCK;
   }
diff --git a/chrome/browser/file_select_helper_unittest.cc b/chrome/browser/file_select_helper_unittest.cc
index 141a13c..e313878 100644
--- a/chrome/browser/file_select_helper_unittest.cc
+++ b/chrome/browser/file_select_helper_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/file_select_helper.h"
+
 #include <stddef.h>
 
 #include <string>
@@ -9,7 +11,6 @@
 #include <vector>
 
 #include "base/command_line.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"
@@ -17,7 +18,6 @@
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "build/build_config.h"
-#include "chrome/browser/file_select_helper.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/file_select_listener.h"
@@ -131,7 +131,7 @@
   const char* files_to_verify[] = {"Contents/Info.plist",
                                    "Contents/MacOS/Calculator",
                                    "Contents/_CodeSignature/CodeResources"};
-  size_t file_count = base::size(files_to_verify);
+  size_t file_count = std::size(files_to_verify);
   for (size_t i = 0; i < file_count; i++) {
     const char* relative_path = files_to_verify[i];
     base::FilePath orig_file = src.Append(relative_path);
diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc
index 0d0593f..563d5e1 100644
--- a/chrome/browser/first_run/upgrade_util_win.cc
+++ b/chrome/browser/first_run/upgrade_util_win.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/first_run/upgrade_util.h"
+#include "chrome/browser/first_run/upgrade_util_win.h"
 
 // Must be first.
 #include <windows.h>
@@ -18,7 +18,6 @@
 
 #include "base/base_paths.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -34,7 +33,7 @@
 #include "base/win/windows_version.h"
 #include "build/branding_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/first_run/upgrade_util_win.h"
+#include "chrome/browser/first_run/upgrade_util.h"
 #include "chrome/browser/shell_integration.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
@@ -220,7 +219,7 @@
 
   if (!::GetMappedFileName(::GetCurrentProcess(),
                            reinterpret_cast<void*>(::GetModuleHandle(NULL)),
-                           mapped_file_name, base::size(mapped_file_name))) {
+                           mapped_file_name, std::size(mapped_file_name))) {
     return false;
   }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index b321abc..ef75e6e 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1411,9 +1411,14 @@
     "expiry_milestone": 110
   },
   {
-      "name": "dynamic-color-android",
-      "owners": [ "skym", "clank-sbui-team@google.com" ],
-      "expiry_milestone": 100
+    "name": "dynamic-color-android",
+    "owners": [ "skym", "clank-sbui-team@google.com" ],
+    "expiry_milestone": 105
+  },
+  {
+    "name": "dynamic-color-buttons-android",
+    "owners": [ "skym", "sinansahin@google.com", "clank-sbui-team@google.com" ],
+    "expiry_milestone": 105
   },
   {
     "name": "dynamic-color-gamut",
@@ -4184,6 +4189,11 @@
     "expiry_milestone": 105
   },
   {
+    "name": "nearby-sharing-visibility-reminder",
+    "owners": ["pushi@google.com", "chromeos-cross-device-eng@google.com"],
+    "expiry_milestone": 103
+  },
+  {
     "name": "nearby-sharing-wifilan",
     "owners": [ "nohle@google.com", "chromeos-cross-device-eng@google.com" ],
     "expiry_milestone": 105
@@ -5233,12 +5243,12 @@
   {
     "name": "scrollable-tabstrip",
     "owners": [ "chrome-desktop-ui-sea@google.com", "tbergquist" ],
-    "expiry_milestone": 100
+    "expiry_milestone": 105
   },
   {
     "name": "scrollable-tabstrip-buttons",
     "owners": [ "chrome-desktop-ui-sea@google.com", "tbergquist" ],
-    "expiry_milestone": 100
+    "expiry_milestone": 105
   },
   {
     "name": "sct-auditing",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 671befe..dabb889 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1222,12 +1222,6 @@
     "Allows website to access a managed configuration provided by the device "
     "administrator for the origin.";
 
-const char kEnablePciguardUiName[] =
-    "Enable Pciguard (Thunderbolt + USB4 tunneling) UI for settings";
-const char kEnablePciguardUiDescription[] =
-    "Enable toggling Pciguard settings through the Settings App. By default, "
-    "this flag is enabled.";
-
 const char kEnablePenetratingImageSelectionName[] =
     "Penetrating Image Selection";
 const char kEnablePenetratingImageSelectionDescription[] =
@@ -3135,6 +3129,12 @@
     "Enabled dynamic colors on supported devices, such as Pixel devices "
     "running Android 12.";
 
+const char kDynamicColorButtonsAndroidName[] =
+    "Dynamic colors for buttons on Android";
+const char kDynamicColorButtonsAndroidDescription[] =
+    "If enabled, dynamic colors will be enabled for call to action buttons, "
+    "links and clickable spans.";
+
 const char kAutofillManualFallbackAndroidName[] =
     "Enable Autofill manual fallback for Addresses and Payments (Android)";
 const char kAutofillManualFallbackAndroidDescription[] =
@@ -5127,6 +5127,12 @@
 const char kNearbySharingSelfShareDescription[] =
     "Enables seamless sharing between a user's own devices.";
 
+const char kNearbySharingVisibilityReminderName[] =
+    "Nearby Sharing visibility reminder notification";
+const char kNearbySharingVisibilityReminderDescription[] =
+    "Enables notification to remind users of their Nearby Share visibility "
+    "selections";
+
 const char kNearbySharingWifiLanName[] = "Nearby Sharing WifiLan";
 const char kNearbySharingWifiLanDescription[] =
     "Enables WifiLan as a Nearby Share transfer medium.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index b1468664..2c9ad95 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -670,9 +670,6 @@
 extern const char kEnableNewDownloadBackendName[];
 extern const char kEnableNewDownloadBackendDescription[];
 
-extern const char kEnablePciguardUiName[];
-extern const char kEnablePciguardUiDescription[];
-
 extern const char kEnablePenetratingImageSelectionName[];
 extern const char kEnablePenetratingImageSelectionDescription[];
 
@@ -1780,6 +1777,9 @@
 extern const char kDynamicColorAndroidName[];
 extern const char kDynamicColorAndroidDescription[];
 
+extern const char kDynamicColorButtonsAndroidName[];
+extern const char kDynamicColorButtonsAndroidDescription[];
+
 extern const char kAutofillManualFallbackAndroidName[];
 extern const char kAutofillManualFallbackAndroidDescription[];
 
@@ -2954,6 +2954,9 @@
 extern const char kNearbySharingSelfShareName[];
 extern const char kNearbySharingSelfShareDescription[];
 
+extern const char kNearbySharingVisibilityReminderName[];
+extern const char kNearbySharingVisibilityReminderDescription[];
+
 extern const char kNearbySharingWifiLanName[];
 extern const char kNearbySharingWifiLanDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 89d7b56..1491179 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -225,6 +225,7 @@
     &kDownloadRename,
     &kDuetTabStripIntegrationAndroid,
     &kDynamicColorAndroid,
+    &kDynamicColorButtonsAndroid,
     &kEnableDangerousDownloadDialog,
     &kEnableDuplicateDownloadDialog,
     &kExperimentsForAgsa,
@@ -630,6 +631,9 @@
 const base::Feature kDynamicColorAndroid{"DynamicColorAndroid",
                                          base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kDynamicColorButtonsAndroid{
+    "DynamicColorButtonsAndroid", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kEnableDangerousDownloadDialog{
     "EnableDangerousDownloadDialog", base::FEATURE_ENABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 5c2ed81..473f902 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -92,6 +92,7 @@
 extern const base::Feature kDownloadRename;
 extern const base::Feature kDuetTabStripIntegrationAndroid;
 extern const base::Feature kDynamicColorAndroid;
+extern const base::Feature kDynamicColorButtonsAndroid;
 extern const base::Feature kEnableDangerousDownloadDialog;
 extern const base::Feature kEnableDuplicateDownloadDialog;
 extern const base::Feature kEnableMixedContentDownloadDialog;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
index b5d3b92d..f0f9c65e 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -78,6 +78,7 @@
                     .put(ChromeFeatureList.CLOSE_TAB_SUGGESTIONS, false)
                     .put(ChromeFeatureList.CRITICAL_PERSISTED_TAB_DATA, false)
                     .put(ChromeFeatureList.DYNAMIC_COLOR_ANDROID, true)
+                    .put(ChromeFeatureList.DYNAMIC_COLOR_BUTTONS_ANDROID, false)
                     .put(ChromeFeatureList.INSTANT_START, false)
                     .put(ChromeFeatureList.TAB_TO_GTS_ANIMATION, true)
                     .put(ChromeFeatureList.TEST_DEFAULT_DISABLED, false)
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index dbe9cafd..84edac89 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -325,6 +325,7 @@
             "UseDownloadOfflineContentProvider";
     public static final String DOWNLOAD_LATER = "DownloadLater";
     public static final String DYNAMIC_COLOR_ANDROID = "DynamicColorAndroid";
+    public static final String DYNAMIC_COLOR_BUTTONS_ANDROID = "DynamicColorButtonsAndroid";
     public static final String EARLY_LIBRARY_LOAD = "EarlyLibraryLoad";
     public static final String ELIDE_PRIORITIZATION_OF_PRE_NATIVE_BOOTSTRAP_TASKS =
             "ElidePrioritizationOfPreNativeBootstrapTasks";
diff --git a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
index 2d8ba11..ed2cba5 100644
--- a/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
+++ b/chrome/browser/global_keyboard_shortcuts_mac_unittest.mm
@@ -2,16 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/global_keyboard_shortcuts_mac.h"
+
 #include <AppKit/NSEvent.h>
 #include <Carbon/Carbon.h>
 #include <stddef.h>
 
 #include <initializer_list>
 
-#include "chrome/browser/global_keyboard_shortcuts_mac.h"
-
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/buildflags.h"
@@ -143,7 +142,7 @@
   // We only consider unshifted keys. A shifted numpad key gives a different
   // keyEquivalent than a shifted number key.
   const ShiftKeyState shift = ShiftKeyState::kUp;
-  for (unsigned int i = 0; i < base::size(equivalents); ++i) {
+  for (unsigned int i = 0; i < std::size(equivalents); ++i) {
     for (CommandKeyState command :
          {CommandKeyState::kUp, CommandKeyState::kDown}) {
       for (OptionKeyState option :
diff --git a/chrome/browser/google/google_brand.cc b/chrome/browser/google/google_brand.cc
index f029868..e0d7ec2 100644
--- a/chrome/browser/google/google_brand.cc
+++ b/chrome/browser/google/google_brand.cc
@@ -119,7 +119,7 @@
       "CHOU", "CHOX", "CHOY", "CHOZ", "CHPD", "CHPE", "CHPF", "CHPG", "ECBA",
       "ECBB", "ECDA", "ECDB", "ECSA", "ECSB", "ECVA", "ECVB", "ECWA", "ECWB",
       "ECWC", "ECWD", "ECWE", "ECWF", "EUBB", "EUBC", "GGLA", "GGLS"};
-  const char* const* end = &kOrganicBrands[base::size(kOrganicBrands)];
+  const char* const* end = &kOrganicBrands[std::size(kOrganicBrands)];
   if (std::binary_search(&kOrganicBrands[0], end, brand))
     return true;
 
diff --git a/chrome/browser/history/top_sites_factory.cc b/chrome/browser/history/top_sites_factory.cc
index f999604..770e212 100644
--- a/chrome/browser/history/top_sites_factory.cc
+++ b/chrome/browser/history/top_sites_factory.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/memory/singleton.h"
 #include "build/branding_buildflags.h"
@@ -73,8 +72,8 @@
   PrefService* pref_service = profile->GetPrefs();
   bool hide_web_store_icon = pref_service->GetBoolean(prefs::kHideWebStoreIcon);
 
-  prepopulated_pages->reserve(base::size(kRawPrepopulatedPages));
-  for (size_t i = 0; i < base::size(kRawPrepopulatedPages); ++i) {
+  prepopulated_pages->reserve(std::size(kRawPrepopulatedPages));
+  for (size_t i = 0; i < std::size(kRawPrepopulatedPages); ++i) {
     const RawPrepopulatedPage& page = kRawPrepopulatedPages[i];
     if (hide_web_store_icon && page.url_id == IDS_WEBSTORE_URL)
       continue;
diff --git a/chrome/browser/importer/edge_importer_browsertest_win.cc b/chrome/browser/importer/edge_importer_browsertest_win.cc
index 3346191..b9b0e29 100644
--- a/chrome/browser/importer/edge_importer_browsertest_win.cc
+++ b/chrome/browser/importer/edge_importer_browsertest_win.cc
@@ -7,7 +7,6 @@
 #include <string>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -180,7 +179,7 @@
       {false, 0, {}, L"InvalidFavicon", "http://www.invalid-favicon.com/"},
   };
   std::vector<BookmarkInfo> bookmark_entries(
-      kEdgeBookmarks, kEdgeBookmarks + base::size(kEdgeBookmarks));
+      kEdgeBookmarks, kEdgeBookmarks + std::size(kEdgeBookmarks));
 
   const FaviconGroup kEdgeFaviconGroup[] = {
       {L"http://www.links-sublink.com/favicon.ico",
@@ -198,7 +197,7 @@
   };
 
   std::vector<FaviconGroup> favicon_groups(
-      kEdgeFaviconGroup, kEdgeFaviconGroup + base::size(kEdgeFaviconGroup));
+      kEdgeFaviconGroup, kEdgeFaviconGroup + std::size(kEdgeFaviconGroup));
 
   base::FilePath data_path;
   ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &data_path));
@@ -242,11 +241,11 @@
   const BookmarkInfo kEdgeBookmarks[] = {
       {false, 0, {}, L"Google", "http://www.google.com/"}};
   std::vector<BookmarkInfo> bookmark_entries(
-      kEdgeBookmarks, kEdgeBookmarks + base::size(kEdgeBookmarks));
+      kEdgeBookmarks, kEdgeBookmarks + std::size(kEdgeBookmarks));
   const FaviconGroup kEdgeFaviconGroup[] = {
       {L"http://www.google.com/favicon.ico", L"http://www.google.com/"}};
   std::vector<FaviconGroup> favicon_groups(
-      kEdgeFaviconGroup, kEdgeFaviconGroup + base::size(kEdgeFaviconGroup));
+      kEdgeFaviconGroup, kEdgeFaviconGroup + std::size(kEdgeFaviconGroup));
 
   base::FilePath data_path;
   ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &data_path));
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc
index e819cf5d..49a61ca 100644
--- a/chrome/browser/importer/ie_importer_browsertest_win.cc
+++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -3,8 +3,9 @@
 // found in the LICENSE file.
 
 // The order of these includes is important.
-#include <windows.h>
 #include <unknwn.h>
+#include <windows.h>
+
 #include <intshcut.h>
 #include <objbase.h>
 #include <shlguid.h>
@@ -20,7 +21,6 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
@@ -232,8 +232,8 @@
   void ImportEnded() override {
     base::RunLoop::QuitCurrentWhenIdleDeprecated();
     if (importer_items_ & importer::FAVORITES) {
-      EXPECT_EQ(base::size(kIEBookmarks), bookmark_count_);
-      EXPECT_EQ(base::size(kIEFaviconGroup), favicon_count_);
+      EXPECT_EQ(std::size(kIEBookmarks), bookmark_count_);
+      EXPECT_EQ(std::size(kIEFaviconGroup), favicon_count_);
     }
     if (importer_items_ & importer::HISTORY)
       EXPECT_EQ(2u, history_count_);
@@ -277,7 +277,7 @@
 
   void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks,
                     const std::u16string& top_level_folder_name) override {
-    ASSERT_LE(bookmark_count_ + bookmarks.size(), base::size(kIEBookmarks));
+    ASSERT_LE(bookmark_count_ + bookmarks.size(), std::size(kIEBookmarks));
     // Importer should import the IE Favorites folder the same as the list,
     // in the same order.
     for (size_t i = 0; i < bookmarks.size(); ++i) {
@@ -290,10 +290,10 @@
 
   void AddFavicons(const favicon_base::FaviconUsageDataList& usage) override {
     // Importer should group the favicon information for each favicon URL.
-    for (size_t i = 0; i < base::size(kIEFaviconGroup); ++i) {
+    for (size_t i = 0; i < std::size(kIEFaviconGroup); ++i) {
       GURL favicon_url(kIEFaviconGroup[i].favicon_url);
       std::set<GURL> urls;
-      for (size_t j = 0; j < base::size(kIEFaviconGroup[i].site_url); ++j)
+      for (size_t j = 0; j < std::size(kIEFaviconGroup[i].site_url); ++j)
         urls.insert(GURL(kIEFaviconGroup[i].site_url[j]));
 
       SCOPED_TRACE(testing::Message() << "Expected Favicon: " << favicon_url);
@@ -341,7 +341,7 @@
   void ImportItemEnded(importer::ImportItem item) override {}
   void ImportEnded() override {
     base::RunLoop::QuitCurrentWhenIdleDeprecated();
-    EXPECT_EQ(base::size(kIESortedBookmarks), bookmark_count_);
+    EXPECT_EQ(std::size(kIESortedBookmarks), bookmark_count_);
   }
 
   // ProfileWriter:
@@ -355,7 +355,7 @@
   void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks,
                     const std::u16string& top_level_folder_name) override {
     ASSERT_LE(bookmark_count_ + bookmarks.size(),
-              base::size(kIESortedBookmarks));
+              std::size(kIESortedBookmarks));
     for (size_t i = 0; i < bookmarks.size(); ++i) {
       EXPECT_NO_FATAL_FAILURE(
           TestEqualBookmarkEntry(bookmarks[i],
@@ -436,7 +436,7 @@
   ASSERT_TRUE(
       CreateOrderBlob(base::FilePath(path), L"",
                       std::vector<std::wstring>(
-                          root_links, root_links + base::size(root_links))));
+                          root_links, root_links + std::size(root_links))));
 
   // Sets up a special history link.
   Microsoft::WRL::ComPtr<IUrlHistoryStg2> url_history_stg2;
@@ -519,7 +519,7 @@
 
   // Verify malformed registry data are safely ignored and alphabetical
   // sort is performed.
-  for (size_t i = 0; i < base::size(kBadBinary); ++i) {
+  for (size_t i = 0; i < std::size(kBadBinary); ++i) {
     std::wstring key_path(importer::GetIEFavoritesOrderKey());
     base::win::RegKey key;
     ASSERT_EQ(ERROR_SUCCESS,
diff --git a/chrome/browser/lifetime/switch_utils_unittest.cc b/chrome/browser/lifetime/switch_utils_unittest.cc
index 891bdf0..aa784f9 100644
--- a/chrome/browser/lifetime/switch_utils_unittest.cc
+++ b/chrome/browser/lifetime/switch_utils_unittest.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/lifetime/switch_utils.h"
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -18,7 +17,7 @@
       FILE_PATH_LITERAL("--make-default-browser"),
       FILE_PATH_LITERAL("--foo"),
       FILE_PATH_LITERAL("--bar")};
-  base::CommandLine cmd_line(base::size(argv), argv);
+  base::CommandLine cmd_line(std::size(argv), argv);
   EXPECT_FALSE(cmd_line.GetCommandLineString().empty());
 
   base::CommandLine::SwitchMap switches = cmd_line.GetSwitches();
@@ -58,7 +57,7 @@
       FILE_PATH_LITERAL("--foo"),
       FILE_PATH_LITERAL("/prefetch:1"),
       FILE_PATH_LITERAL("--bar")};
-  base::CommandLine cmd_line(base::size(argv), argv);
+  base::CommandLine cmd_line(std::size(argv), argv);
   EXPECT_FALSE(cmd_line.GetCommandLineString().empty());
 
   base::CommandLine::SwitchMap switches = cmd_line.GetSwitches();
@@ -77,7 +76,7 @@
       FILE_PATH_LITERAL("/prefetch:1"),
       FILE_PATH_LITERAL("--force-first-run"),
       FILE_PATH_LITERAL("--bar")};
-  base::CommandLine cmd_line(base::size(argv), argv);
+  base::CommandLine cmd_line(std::size(argv), argv);
   EXPECT_FALSE(cmd_line.GetCommandLineString().empty());
 
   base::CommandLine::SwitchMap switches = cmd_line.GetSwitches();
diff --git a/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm b/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
index e39a3c4..d47a02c 100644
--- a/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
+++ b/chrome/browser/local_discovery/service_discovery_client_mac_unittest.mm
@@ -146,7 +146,7 @@
   const uint8_t record_bytes[] = {2, 'a', 'b', 3, 'd', '=', 'e'};
   base::scoped_nsobject<TestNSNetService> test_service([[TestNSNetService alloc]
       initWithData:[NSData dataWithBytes:record_bytes
-                                  length:base::size(record_bytes)]]);
+                                  length:std::size(record_bytes)]]);
 
   const std::string kIp = "2001:4860:4860::8844";
   const uint16_t kPort = 4321;
@@ -184,7 +184,7 @@
   };
   base::scoped_nsobject<TestNSNetService> test_service([[TestNSNetService alloc]
       initWithData:[NSData dataWithBytes:record_bytes
-                                  length:base::size(record_bytes)]]);
+                                  length:std::size(record_bytes)]]);
 
   const std::string kIp = "2001:4860:4860::8844";
   const uint16_t kPort = 4321;
diff --git a/chrome/browser/locale_tests_browsertest.cc b/chrome/browser/locale_tests_browsertest.cc
index f071ff60..26bb8253 100644
--- a/chrome/browser/locale_tests_browsertest.cc
+++ b/chrome/browser/locale_tests_browsertest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "build/build_config.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -36,7 +35,7 @@
       { "zh-TW", "zh_TW.UTF-8" }
     };
     bool found_locale = false;
-    for (size_t i = 0; i < base::size(kLocales); ++i) {
+    for (size_t i = 0; i < std::size(kLocales); ++i) {
       if (kLocales[i].chrome_locale == locale) {
         found_locale = true;
         setenv("LC_ALL", kLocales[i].system_locale, 1);
diff --git a/chrome/browser/mac/exception_processor.mm b/chrome/browser/mac/exception_processor.mm
index 8474792..2ff2573 100644
--- a/chrome/browser/mac/exception_processor.mm
+++ b/chrome/browser/mac/exception_processor.mm
@@ -4,15 +4,14 @@
 
 #import "chrome/browser/mac/exception_processor.h"
 
-#include <dlfcn.h>
 #import <Foundation/Foundation.h>
+#include <dlfcn.h>
 #include <libunwind.h>
 #include <objc/objc-exception.h>
 
 #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"
@@ -58,11 +57,11 @@
   };
 
   // Make sure our array hasn't outgrown our abilities to track it.
-  static_assert(base::size(kKnownNSExceptionNames) < kKnownNSExceptionCount,
+  static_assert(std::size(kKnownNSExceptionNames) < kKnownNSExceptionCount,
                 "Cannot track more exceptions");
 
   NSString* name = [exception name];
-  for (size_t i = 0; i < base::size(kKnownNSExceptionNames); ++i) {
+  for (size_t i = 0; i < std::size(kKnownNSExceptionNames); ++i) {
     if (name == kKnownNSExceptionNames[i]) {
       return i;
     }
diff --git a/chrome/browser/mac/install_from_dmg.mm b/chrome/browser/mac/install_from_dmg.mm
index 1a4707b..30a3aa5 100644
--- a/chrome/browser/mac/install_from_dmg.mm
+++ b/chrome/browser/mac/install_from_dmg.mm
@@ -19,7 +19,6 @@
 
 #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"
@@ -234,7 +233,7 @@
   }
 
   const char dev_root[] = "/dev/";
-  const int dev_root_length = base::size(dev_root) - 1;
+  const int dev_root_length = std::size(dev_root) - 1;
   if (strncmp(statfs_buf.f_mntfromname, dev_root, dev_root_length) != 0) {
     // Not rooted at dev_root, no BSD name to search on.
     return DiskImageStatusFalse;
diff --git a/chrome/browser/media/router/discovery/dial/dial_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_service_impl_unittest.cc
index a72e9f08..bf4aa81 100644
--- a/chrome/browser/media/router/discovery/dial/dial_service_impl_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_service_impl_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
@@ -138,7 +137,7 @@
 
 TEST_F(DialServiceImplTest, TestOnDeviceDiscovered) {
   dial_service_.discovery_active_ = true;
-  int response_size = base::size(kValidResponse) - 1;
+  int response_size = std::size(kValidResponse) - 1;
   dial_socket_->recv_buffer_ =
       base::MakeRefCounted<net::IOBufferWithSize>(response_size);
   strncpy(dial_socket_->recv_buffer_->data(), kValidResponse, response_size);
diff --git a/chrome/browser/media/router/discovery/discovery_network_list_win.cc b/chrome/browser/media/router/discovery/discovery_network_list_win.cc
index cf55ac3c..5ca829b 100644
--- a/chrome/browser/media/router/discovery/discovery_network_list_win.cc
+++ b/chrome/browser/media/router/discovery/discovery_network_list_win.cc
@@ -8,7 +8,6 @@
 #include <ws2tcpip.h>
 
 #include <iphlpapi.h>  // NOLINT
-
 #include <windot11.h>  // NOLINT
 #include <wlanapi.h>   // NOLINT
 
@@ -20,7 +19,6 @@
 
 #include "base/check.h"
 #include "base/containers/small_map.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 
@@ -70,7 +68,7 @@
   static std::unique_ptr<WlanApi> Create() {
     static const wchar_t* kWlanDllPath = L"%WINDIR%\\system32\\wlanapi.dll";
     wchar_t path[MAX_PATH] = {0};
-    ExpandEnvironmentStrings(kWlanDllPath, path, base::size(path));
+    ExpandEnvironmentStrings(kWlanDllPath, path, std::size(path));
     HINSTANCE library =
         LoadLibraryEx(path, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
     if (!library) {
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.cc b/chrome/browser/media/router/test/media_router_mojo_test.cc
index a88d719a..0919735 100644
--- a/chrome/browser/media/router/test/media_router_mojo_test.cc
+++ b/chrome/browser/media/router/test/media_router_mojo_test.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 
 using testing::_;
@@ -263,12 +262,12 @@
 void MediaRouterMojoTest::TestSendRouteBinaryMessage() {
   ProvideTestRoute(mojom::MediaRouteProviderId::CAST, kRouteId);
   auto expected_binary_data = std::make_unique<std::vector<uint8_t>>(
-      kBinaryMessage, kBinaryMessage + base::size(kBinaryMessage));
+      kBinaryMessage, kBinaryMessage + std::size(kBinaryMessage));
   EXPECT_CALL(mock_cast_provider_, SendRouteBinaryMessage(kRouteId, _))
       .WillOnce([](const MediaRoute::Id& route_id,
                    const std::vector<uint8_t>& data) {
         EXPECT_EQ(
-            0, memcmp(kBinaryMessage, &(data[0]), base::size(kBinaryMessage)));
+            0, memcmp(kBinaryMessage, &(data[0]), std::size(kBinaryMessage)));
       });
 
   router()->SendRouteBinaryMessage(kRouteId, std::move(expected_binary_data));
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
index be9a9a53..10419bc 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler_unittest.cc
@@ -112,7 +112,7 @@
          true /* expect_tabs */, false /* expect_current_tab */,
          request_audio /* expect_audio */,
          fake_desktop_media_id_response /* selected_source */}};
-    picker_factory_->SetTestFlags(test_flags, base::size(test_flags));
+    picker_factory_->SetTestFlags(test_flags, std::size(test_flags));
     blink::mojom::MediaStreamType audio_type =
         request_audio ? blink::mojom::MediaStreamType::GUM_DESKTOP_AUDIO_CAPTURE
                       : blink::mojom::MediaStreamType::NO_SERVICE;
@@ -217,7 +217,7 @@
        true /* expect_tabs */, false /* expect_current_tab */,
        false /* expect_audio */, content::DesktopMediaID(),
        true /* cancelled */}};
-  picker_factory_->SetTestFlags(test_flags, base::size(test_flags));
+  picker_factory_->SetTestFlags(test_flags, std::size(test_flags));
   content::MediaStreamRequest request(
       render_process_id, render_frame_id, page_request_id, GURL(kOrigin), false,
       blink::MEDIA_DEVICE_UPDATE, std::string(), std::string(),
@@ -249,7 +249,7 @@
        true /* expect_tabs */, false /* expect_current_tab */,
        false /* expect_audio */, content::DesktopMediaID(),
        true /* cancelled */}};
-  picker_factory_->SetTestFlags(test_flags, base::size(test_flags));
+  picker_factory_->SetTestFlags(test_flags, std::size(test_flags));
   content::MediaStreamRequest request(
       0, 0, 0, GURL(kOrigin), false, blink::MEDIA_DEVICE_UPDATE, std::string(),
       std::string(), blink::mojom::MediaStreamType::NO_SERVICE,
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
index a4a875f..e3250f9 100644
--- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -227,7 +227,7 @@
   EXPECT_EQ(1u, devices.size());
   EXPECT_EQ(blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE,
             devices[0].type);
-  EXPECT_TRUE(devices[0].display_media_info.has_value());
+  EXPECT_TRUE(devices[0].display_media_info);
 }
 
 TEST_F(DisplayMediaAccessHandlerTest, PermissionGivenToRequestWithAudio) {
@@ -251,7 +251,7 @@
   EXPECT_EQ(2u, devices.size());
   EXPECT_EQ(blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE,
             devices[0].type);
-  EXPECT_TRUE(devices[0].display_media_info.has_value());
+  EXPECT_TRUE(devices[0].display_media_info);
   EXPECT_EQ(blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE,
             devices[1].type);
   EXPECT_TRUE(devices[1].input.IsValid());
diff --git a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
index e2991f0..2e7bc71 100644
--- a/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
+++ b/chrome/browser/media/webrtc/media_stream_capture_indicator.cc
@@ -90,7 +90,7 @@
 // different from capturing a tab or a single window on a desktop.
 bool IsDeviceCapturingDisplay(const blink::MediaStreamDevice& device) {
   return device.display_media_info &&
-         device.display_media_info.value()->display_surface ==
+         device.display_media_info->display_surface ==
              media::mojom::DisplayCaptureSurfaceType::MONITOR;
 }
 
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_history.cc b/chrome/browser/media/webrtc/webrtc_event_log_history.cc
index 8686b2ef..fc7f652 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_history.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_history.cc
@@ -8,7 +8,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
@@ -31,7 +30,7 @@
 // No need to use \r\n for Windows; better have a consistent file format
 // between platforms.
 const char kEOL[] = "\n";
-static_assert(base::size(kEOL) == 1 + 1 /* +1 for the implicit \0. */,
+static_assert(std::size(kEOL) == 1 + 1 /* +1 for the implicit \0. */,
               "SplitString relies on this being a single character.");
 
 // |time| must *not* be earlier than UNIX epoch start. If it is, the empty
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
index c559ae1..5c84f4a 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_common.cc
@@ -7,7 +7,6 @@
 #include <cctype>
 #include <limits>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
@@ -928,7 +927,7 @@
 bool IsValidRemoteBoundLogFilename(const std::string& filename) {
   // The -1 is because of the implict \0.
   const size_t kPrefixLength =
-      base::size(kRemoteBoundWebRtcEventLogFileNamePrefix) - 1;
+      std::size(kRemoteBoundWebRtcEventLogFileNamePrefix) - 1;
 
   // [prefix]_[web_app_id]_[log_id]
   const size_t expected_length =
@@ -1008,7 +1007,7 @@
 
   // The -1 is because of the implict \0.
   const size_t kPrefixLength =
-      base::size(kRemoteBoundWebRtcEventLogFileNamePrefix) - 1;
+      std::size(kRemoteBoundWebRtcEventLogFileNamePrefix) - 1;
 
   // The +1 is for the underscore between the prefix and the web-app ID.
   // Length verified by above call to IsValidRemoteBoundLogFilename().
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_local.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_local.cc
index e85b67e..d7fee010 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_local.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_local.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/media/webrtc/webrtc_event_log_manager_local.h"
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
@@ -239,11 +238,11 @@
   // [user_defined]_[date]_[time]_[render_process_id]_[lid].[extension]
   char stamp[100];
   int written =
-      base::snprintf(stamp, base::size(stamp), "%04d%02d%02d_%02d%02d_%d_%d",
+      base::snprintf(stamp, std::size(stamp), "%04d%02d%02d_%02d%02d_%d_%d",
                      now.year, now.month, now.day_of_month, now.hour,
                      now.minute, key.render_process_id, key.lid);
   CHECK_GT(written, 0);
-  CHECK_LT(static_cast<size_t>(written), base::size(stamp));
+  CHECK_LT(static_cast<size_t>(written), std::size(stamp));
 
   return base_path.InsertBeforeExtension(FILE_PATH_LITERAL("_"))
       .AddExtension(log_file_writer_factory_.Extension())
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
index a566b24..5e83121ee 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
@@ -17,7 +17,6 @@
 
 #include "base/big_endian.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -2311,7 +2310,7 @@
   }
 
   // All log files must be created in their own context's directory.
-  for (size_t i = 0; i < base::size(browser_contexts); ++i) {
+  for (size_t i = 0; i < std::size(browser_contexts); ++i) {
     ASSERT_TRUE(file_paths[i]);
     EXPECT_TRUE(browser_contexts[i]->GetPath().IsParent(*file_paths[i]));
   }
@@ -2564,9 +2563,9 @@
 
 TEST_F(WebRtcEventLogManagerTest, DifferentRemoteLogsMayHaveDifferentMaximums) {
   const std::string logs[2] = {"abra", "cadabra"};
-  std::vector<absl::optional<base::FilePath>> file_paths(base::size(logs));
+  std::vector<absl::optional<base::FilePath>> file_paths(std::size(logs));
   std::vector<PeerConnectionKey> keys;
-  for (size_t i = 0; i < base::size(logs); ++i) {
+  for (size_t i = 0; i < std::size(logs); ++i) {
     keys.push_back(GetPeerConnectionKey(rph_.get(), i));
     ON_CALL(remote_observer_, OnRemoteLogStarted(keys[i], _, _))
         .WillByDefault(Invoke(SaveFilePathTo(&file_paths[i])));
@@ -2878,7 +2877,7 @@
 
   base::FilePath::StringPieceType extensions[] = {
       kWebRtcEventLogUncompressedExtension, kWebRtcEventLogGzippedExtension};
-  ASSERT_LE(base::size(extensions), kMaxPendingRemoteBoundWebRtcEventLogs)
+  ASSERT_LE(std::size(extensions), kMaxPendingRemoteBoundWebRtcEventLogs)
       << "Lacking test coverage.";
 
   // Avoid arbitrary ordering due to files being created in the same second.
@@ -2891,7 +2890,7 @@
     time += base::Seconds(1);
 
     const auto& extension = extensions[ext];
-    ext = (ext + 1) % base::size(extensions);
+    ext = (ext + 1) % std::size(extensions);
 
     base::FilePath file_path;
     base::File file;
diff --git a/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc b/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc
index cdeeef3..7b03b5b 100644
--- a/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/location.h"
@@ -99,8 +98,8 @@
     *incoming_dump = dir.AppendASCII("recv");
     *outgoing_dump = dir.AppendASCII("send");
     const char dummy[] = "dummy";
-    EXPECT_GT(base::WriteFile(*incoming_dump, dummy, base::size(dummy)), 0);
-    EXPECT_GT(base::WriteFile(*outgoing_dump, dummy, base::size(dummy)), 0);
+    EXPECT_GT(base::WriteFile(*incoming_dump, dummy, std::size(dummy)), 0);
+    EXPECT_GT(base::WriteFile(*outgoing_dump, dummy, std::size(dummy)), 0);
   }
 
   void FlushTaskRunners() {
@@ -126,7 +125,7 @@
   types[1] = RTP_DUMP_OUTGOING;
   types[2] = RTP_DUMP_BOTH;
 
-  for (size_t i = 0; i < base::size(types); ++i) {
+  for (size_t i = 0; i < std::size(types); ++i) {
     DVLOG(2) << "Verifying state transition: type = " << types[i];
 
     // Only StartDump is allowed in STATE_NONE.
@@ -216,10 +215,10 @@
 
   std::unique_ptr<WebRtcRtpDumpHandler> handlers[6];
 
-  for (size_t i = 0; i < base::size(handlers); ++i) {
+  for (size_t i = 0; i < std::size(handlers); ++i) {
     handlers[i] = std::make_unique<WebRtcRtpDumpHandler>(base::FilePath());
 
-    if (i < base::size(handlers) - 1) {
+    if (i < std::size(handlers) - 1) {
       EXPECT_TRUE(handlers[i]->StartDump(RTP_DUMP_INCOMING, &error));
     } else {
       EXPECT_FALSE(handlers[i]->StartDump(RTP_DUMP_INCOMING, &error));
diff --git a/chrome/browser/media/webrtc/webrtc_rtp_dump_writer.cc b/chrome/browser/media/webrtc/webrtc_rtp_dump_writer.cc
index 3d15f2b..38ed8f1 100644
--- a/chrome/browser/media/webrtc/webrtc_rtp_dump_writer.cc
+++ b/chrome/browser/media/webrtc/webrtc_rtp_dump_writer.cc
@@ -8,7 +8,6 @@
 
 #include "base/big_endian.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/task/post_task.h"
@@ -294,7 +293,7 @@
 
     // Writes the dump file header.
     AppendToBuffer(kRtpDumpFileHeaderFirstLine,
-                   base::size(kRtpDumpFileHeaderFirstLine) - 1, dest_buffer);
+                   std::size(kRtpDumpFileHeaderFirstLine) - 1, dest_buffer);
     WriteRtpDumpFileHeaderBigEndian(start_time_, dest_buffer);
   }
 
diff --git a/chrome/browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc b/chrome/browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc
index 18b7139..408d248 100644
--- a/chrome/browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/big_endian.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
@@ -148,9 +147,9 @@
     size_t dump_pos = 0;
 
     // Verifies the first line.
-    EXPECT_EQ(memcmp(&dump[0], kFirstLine, base::size(kFirstLine) - 1), 0);
+    EXPECT_EQ(memcmp(&dump[0], kFirstLine, std::size(kFirstLine) - 1), 0);
 
-    dump_pos += base::size(kFirstLine) - 1;
+    dump_pos += std::size(kFirstLine) - 1;
     EXPECT_GT(dump.size(), dump_pos);
 
     // Skips the file header.
diff --git a/chrome/browser/media/webrtc/window_icon_util_mac.mm b/chrome/browser/media/webrtc/window_icon_util_mac.mm
index 3188ad8..169218d 100644
--- a/chrome/browser/media/webrtc/window_icon_util_mac.mm
+++ b/chrome/browser/media/webrtc/window_icon_util_mac.mm
@@ -6,7 +6,6 @@
 
 #import <Cocoa/Cocoa.h>
 
-#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
 #include "third_party/libyuv/include/libyuv/convert_argb.h"
@@ -17,7 +16,7 @@
   CGWindowID ids[1];
   ids[0] = id.id;
   base::ScopedCFTypeRef<CFArrayRef> window_id_array(CFArrayCreate(
-      nullptr, reinterpret_cast<const void**>(&ids), base::size(ids), nullptr));
+      nullptr, reinterpret_cast<const void**>(&ids), std::size(ids), nullptr));
   base::ScopedCFTypeRef<CFArrayRef> window_array(
       CGWindowListCreateDescriptionFromArray(window_id_array));
   if (!window_array || 0 == CFArrayGetCount(window_array)) {
diff --git a/chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator_unittest.cc b/chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator_unittest.cc
index 8e0abca..3ca301ed 100644
--- a/chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator_unittest.cc
+++ b/chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
 #include <utility>
 
-#include "base/cxx17_backports.h"
-#include "chrome/browser/media_galleries/chromeos/mtp_device_object_enumerator.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -49,7 +49,7 @@
 
 TEST_F(MTPDeviceObjectEnumeratorTest, Traversal) {
   std::vector<device::mojom::MtpFileEntryPtr> entries;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     auto entry = device::mojom::MtpFileEntry::New();
     entry->file_name = kTestCases[i].name;
     entry->file_size = kTestCases[i].size;
@@ -63,7 +63,7 @@
   MTPDeviceObjectEnumerator enumerator(std::move(entries));
   TestEnumeratorIsEmpty(&enumerator);
   TestEnumeratorIsEmpty(&enumerator);
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     EXPECT_EQ(kTestCases[i].name, enumerator.Next().value());
     EXPECT_EQ(kTestCases[i].size, enumerator.Size());
     EXPECT_EQ(kTestCases[i].is_directory, enumerator.IsDirectory());
diff --git a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
index b80f292..808aafc9 100644
--- a/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
+++ b/chrome/browser/media_galleries/fileapi/media_file_validator_browsertest.cc
@@ -4,11 +4,11 @@
 
 #include <stddef.h>
 #include <stdint.h>
+
 #include <utility>
 
 #include "base/bind.h"
 #include "base/callback_helpers.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"
@@ -271,7 +271,7 @@
 };
 
 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, UnsupportedExtension) {
-  MoveTest("a.txt", std::string(kValidImage, base::size(kValidImage)), false);
+  MoveTest("a.txt", std::string(kValidImage, std::size(kValidImage)), false);
 }
 
 // TODO(crbug.com/1169640): Re-enable. Flaky on Linux.
@@ -281,19 +281,17 @@
 #define MAYBE_ValidImage ValidImage
 #endif
 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, MAYBE_ValidImage) {
-  MoveTest("a.webp", std::string(kValidImage, base::size(kValidImage)), true);
+  MoveTest("a.webp", std::string(kValidImage, std::size(kValidImage)), true);
 }
 
 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidImage) {
   MoveTest("a.webp",
-           std::string(kInvalidMediaFile, base::size(kInvalidMediaFile)),
-           false);
+           std::string(kInvalidMediaFile, std::size(kInvalidMediaFile)), false);
 }
 
 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, InvalidAudio) {
   MoveTest("a.ogg",
-           std::string(kInvalidMediaFile, base::size(kInvalidMediaFile)),
-           false);
+           std::string(kInvalidMediaFile, std::size(kInvalidMediaFile)), false);
 }
 
 IN_PROC_BROWSER_TEST_F(MediaFileValidatorTest, ValidAudio) {
diff --git a/chrome/browser/media_galleries/fileapi/media_path_filter.cc b/chrome/browser/media_galleries/fileapi/media_path_filter.cc
index 65d93ca..fc6e4e7 100644
--- a/chrome/browser/media_galleries/fileapi/media_path_filter.cc
+++ b/chrome/browser/media_galleries/fileapi/media_path_filter.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/containers/cxx20_erase.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "net/base/mime_util.h"
@@ -172,16 +171,13 @@
   AddExtensionsToMediaFileExtensionMap(GetMediaExtensionList("video/*"),
                                        MEDIA_GALLERY_FILE_TYPE_VIDEO);
   AddAdditionalExtensionsToMediaFileExtensionMap(
-      kExtraSupportedImageExtensions,
-      base::size(kExtraSupportedImageExtensions),
+      kExtraSupportedImageExtensions, std::size(kExtraSupportedImageExtensions),
       MEDIA_GALLERY_FILE_TYPE_IMAGE);
   AddAdditionalExtensionsToMediaFileExtensionMap(
-      kExtraSupportedAudioExtensions,
-      base::size(kExtraSupportedAudioExtensions),
+      kExtraSupportedAudioExtensions, std::size(kExtraSupportedAudioExtensions),
       MEDIA_GALLERY_FILE_TYPE_AUDIO);
   AddAdditionalExtensionsToMediaFileExtensionMap(
-      kExtraSupportedVideoExtensions,
-      base::size(kExtraSupportedVideoExtensions),
+      kExtraSupportedVideoExtensions, std::size(kExtraSupportedVideoExtensions),
       MEDIA_GALLERY_FILE_TYPE_VIDEO);
 
   initialized_ = true;
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
index e07f770..61d0a92 100644
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
 
 #include <stddef.h>
+
 #include <set>
 #include <string>
 #include <utility>
@@ -12,7 +13,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/format_macros.h"
@@ -203,9 +203,9 @@
 
 TEST_F(NativeMediaFileUtilTest, DirectoryExistsAndFileExistsFiltering) {
   PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                 base::size(kFilteringTestCases));
+                                 std::size(kFilteringTestCases));
 
-  for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
     FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
 
     base::File::Error expectation = kFilteringTestCases[i].visible
@@ -227,7 +227,7 @@
 
 TEST_F(NativeMediaFileUtilTest, ReadDirectoryFiltering) {
   PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                 base::size(kFilteringTestCases));
+                                 std::size(kFilteringTestCases));
 
   std::set<base::FilePath::StringType> content;
   FileSystemURL url = CreateURL(FPL(""));
@@ -238,7 +238,7 @@
   EXPECT_TRUE(completed);
   EXPECT_EQ(6u, content.size());
 
-  for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
     base::FilePath::StringType name =
         base::FilePath(kFilteringTestCases[i].path).BaseName().value();
     auto found = content.find(name);
@@ -250,7 +250,7 @@
   // Run the loop twice. The second loop attempts to create directories that are
   // pre-existing. Though the result should be the same.
   for (int loop_count = 0; loop_count < 2; ++loop_count) {
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       if (kFilteringTestCases[i].is_directory) {
         FileSystemURL root_url = CreateURL(FPL(""));
         FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
@@ -278,9 +278,9 @@
   for (int loop_count = 0; loop_count < 2; ++loop_count) {
     if (loop_count == 1) {
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       // Always start with an empty destination directory.
       // Copying to a non-empty destination directory is an invalid operation.
       ASSERT_TRUE(base::DeletePathRecursively(dest_path));
@@ -319,7 +319,7 @@
       ASSERT_TRUE(base::DeletePathRecursively(root_path()));
       ASSERT_TRUE(base::CreateDirectory(root_path()));
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
 
     // Always create a dummy source data file.
@@ -328,7 +328,7 @@
     static const char kDummyData[] = "dummy";
     ASSERT_TRUE(base::WriteFile(src_path, kDummyData));
 
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
         // These directories do not exist in this case, so Copy() will not
         // treat them as directories. Thus invalidating these test cases.
@@ -380,9 +380,9 @@
   for (int loop_count = 0; loop_count < 2; ++loop_count) {
     if (loop_count == 1) {
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       // Always start with an empty destination directory.
       // Moving to a non-empty destination directory is an invalid operation.
       ASSERT_TRUE(base::DeletePathRecursively(dest_path));
@@ -421,10 +421,10 @@
       ASSERT_TRUE(base::DeletePathRecursively(root_path()));
       ASSERT_TRUE(base::CreateDirectory(root_path()));
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
 
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
         // These directories do not exist in this case, so Copy() will not
         // treat them as directories. Thus invalidating these test cases.
@@ -480,9 +480,9 @@
   for (int loop_count = 0; loop_count < 2; ++loop_count) {
     if (loop_count == 1) {
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       FileSystemURL root_url = CreateURL(FPL(""));
       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
 
@@ -507,9 +507,9 @@
   for (int loop_count = 0; loop_count < 2; ++loop_count) {
     if (loop_count == 1) {
       PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                     base::size(kFilteringTestCases));
+                                     std::size(kFilteringTestCases));
     }
-    for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+    for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
       FileSystemURL root_url = CreateURL(FPL(""));
       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
 
@@ -539,8 +539,8 @@
 
 TEST_F(NativeMediaFileUtilTest, CreateSnapshot) {
   PopulateDirectoryWithTestCases(root_path(), kFilteringTestCases,
-                                 base::size(kFilteringTestCases));
-  for (size_t i = 0; i < base::size(kFilteringTestCases); ++i) {
+                                 std::size(kFilteringTestCases));
+  for (size_t i = 0; i < std::size(kFilteringTestCases); ++i) {
     if (kFilteringTestCases[i].is_directory ||
         !kFilteringTestCases[i].visible) {
       continue;
diff --git a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
index 2d51a2da..adcb34d 100644
--- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
+++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
@@ -45,7 +45,7 @@
 
   result = std::make_unique<std::string>();
   result->resize(file_info.size);
-  if (file.Read(0, base::data(*result), file_info.size) != file_info.size) {
+  if (file.Read(0, std::data(*result), file_info.size) != file_info.size) {
     result.reset();
   }
 
diff --git a/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc b/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
index 59f1ef1..ef580851 100644
--- a/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
+++ b/chrome/browser/media_galleries/media_galleries_permissions_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "chrome/browser/extensions/extension_prefs_unittest.h"
@@ -120,7 +119,7 @@
                                   {&extension2_id_, &extension2_expectation_},
                                   {&extension3_id_, &extension3_expectation_},
                                   {&extension4_id_, &extension4_expectation_}};
-    for (size_t i = 0; i < base::size(test_data); i++) {
+    for (size_t i = 0; i < std::size(test_data); i++) {
       std::vector<MediaGalleryPermission> actual =
           gallery_prefs_->GetGalleryPermissionsFromPrefs(*test_data[i].id);
       EXPECT_EQ(test_data[i].expectation->size(), actual.size());
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.cc b/chrome/browser/media_galleries/media_galleries_preferences.cc
index f4232a8..d42b5b5 100644
--- a/chrome/browser/media_galleries/media_galleries_preferences.cc
+++ b/chrome/browser/media_galleries/media_galleries_preferences.cc
@@ -512,7 +512,7 @@
     {chrome::DIR_USER_VIDEOS, MediaGalleryPrefInfo::kVideosDefault},
   };
 
-  for (size_t i = 0; i < base::size(kDirectories); ++i) {
+  for (size_t i = 0; i < std::size(kDirectories); ++i) {
     base::FilePath path;
     if (!base::PathService::Get(kDirectories[i].directory_key, &path))
       continue;
diff --git a/chrome/browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc b/chrome/browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc
index 7fe599f..43f17a8 100644
--- a/chrome/browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc
+++ b/chrome/browser/media_galleries/win/mtp_device_object_enumerator_unittest.cc
@@ -12,7 +12,6 @@
 #include <ctime>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/time/time.h"
 #include "chrome/browser/media_galleries/win/mtp_device_object_entry.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -66,7 +65,7 @@
 
 TEST_F(MTPDeviceObjectEnumeratorWinTest, Traversal) {
   MTPDeviceObjectEntries entries;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     entries.push_back(MTPDeviceObjectEntry(
         kTestCases[i].object_id,
         kTestCases[i].name,
@@ -77,7 +76,7 @@
   MTPDeviceObjectEnumerator enumerator(entries);
   TestEnumeratorIsEmpty(&enumerator);
   TestEnumeratorIsEmpty(&enumerator);
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     EXPECT_EQ(kTestCases[i].name, enumerator.Next().AsUTF16Unsafe());
     EXPECT_EQ(kTestCases[i].object_id, enumerator.GetObjectId());
     EXPECT_EQ(kTestCases[i].size, enumerator.Size());
diff --git a/chrome/browser/metrics/perf/cpu_identity.cc b/chrome/browser/metrics/perf/cpu_identity.cc
index ea23b85..bf0c1af 100644
--- a/chrome/browser/metrics/perf/cpu_identity.cc
+++ b/chrome/browser/metrics/perf/cpu_identity.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/metrics/perf/cpu_identity.h"
 
-#include <algorithm>  // for std::lower_bound()
 #include <string.h>
 
+#include <algorithm>  // for std::lower_bound()
+
 #include "base/cpu.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
@@ -69,7 +69,7 @@
 };
 
 const CpuUarchTableEntry* kCpuUarchTableEnd =
-    kCpuUarchTable + base::size(kCpuUarchTable);
+    kCpuUarchTable + std::size(kCpuUarchTable);
 
 bool CpuUarchTableCmp(const CpuUarchTableEntry& a,
                       const CpuUarchTableEntry& b) {
diff --git a/chrome/browser/metrics/perf/metric_provider.cc b/chrome/browser/metrics/perf/metric_provider.cc
index f70dbdc..21e66c66e 100644
--- a/chrome/browser/metrics/perf/metric_provider.cc
+++ b/chrome/browser/metrics/perf/metric_provider.cc
@@ -194,20 +194,23 @@
     return RecordAttemptStatus::kSyncServiceUnavailable;
   syncer::SyncUserSettings* sync_settings = sync_service->GetUserSettings();
 
+  // IsSyncFeatureEnabled should be checked regardless of
+  // SyncSettingsCategorization status.
+  if (!sync_service->IsSyncFeatureEnabled())
+    return RecordAttemptStatus::kChromeSyncFeatureDisabled;
+
   // SyncSettingsCategorization splits the sync settings between Chrome and
   // ChromeOS. The App Sync toggle is moved under the ChromeOS settings.
   // If SyncSettingsCategorization is enabled, we will directly read from
-  // the OS settings. Otherwise, we read from Chrome settings. We then check if
-  // the sync feature is enabled and the App Sync toggle is on.
+  // the OS settings.
   if (chromeos::features::IsSyncSettingsCategorizationEnabled()) {
     if (!sync_settings->GetSelectedOsTypes().Has(
             syncer::UserSelectableOsType::kOsApps))
       return RecordAttemptStatus::kOSAppSyncDisabled;
     return RecordAttemptStatus::kAppSyncEnabled;
   }
+
   // Read chrome settings if SyncSettingsCategorization is disabled.
-  if (!sync_service->IsSyncFeatureEnabled())
-    return RecordAttemptStatus::kChromeSyncFeatureDisabled;
   if (!sync_settings->GetSelectedTypes().Has(syncer::UserSelectableType::kApps))
     return RecordAttemptStatus::kChromeAppSyncDisabled;
   return RecordAttemptStatus::kAppSyncEnabled;
diff --git a/chrome/browser/metrics/perf/metric_provider_unittest.cc b/chrome/browser/metrics/perf/metric_provider_unittest.cc
index 1e12b51..4a318b3f 100644
--- a/chrome/browser/metrics/perf/metric_provider_unittest.cc
+++ b/chrome/browser/metrics/perf/metric_provider_unittest.cc
@@ -405,6 +405,40 @@
       TestMetricProvider::RecordAttemptStatus::kNoLoadedProfile, 1);
 }
 
+TEST_F(MetricProviderSyncSettingsTest,
+       SettingsCategorizationSyncFeatureDisabled) {
+  base::HistogramTester histogram_tester;
+  std::vector<SampledProfile> stored_profiles;
+  metric_provider_->OnUserLoggedIn();
+  feature_list_.InitAndEnableFeature(
+      chromeos::features::kSyncSettingsCategorization);
+
+  // The first testing profile has both sync-the-feature and App sync enabled.
+  TestSyncService* sync_service1 =
+      GetSyncService(testing_profile_manager_->CreateTestingProfile("user1"));
+  EnableOSAppSync(sync_service1);
+
+  // The second testing profile has kOsApps type enabled, but sync-the-feature
+  // is turned off by marking FirstSetupComplete as false.
+  TestSyncService* sync_service2 =
+      GetSyncService(testing_profile_manager_->CreateTestingProfile("user2"));
+  EnableOSAppSync(sync_service2);
+  sync_service2->SetFirstSetupComplete(false);
+
+  task_environment_.FastForwardBy(kPeriodicCollectionInterval);
+
+  EXPECT_TRUE(metric_provider_->GetSampledProfiles(&stored_profiles));
+  EXPECT_EQ(stored_profiles.size(), 1u);
+
+  const SampledProfile& profile = stored_profiles[0];
+  EXPECT_EQ(SampledProfile::PERIODIC_COLLECTION, profile.trigger_event());
+  EXPECT_EQ(SerializeMessageToVector(perf_data_redacted_),
+            SerializeMessageToVector(profile.perf_data()));
+  histogram_tester.ExpectUniqueSample(
+      "ChromeOS.CWP.RecordTest",
+      TestMetricProvider::RecordAttemptStatus::kChromeSyncFeatureDisabled, 1);
+}
+
 TEST_F(MetricProviderSyncSettingsTest, SettingsCategorizationAppSyncEnabled) {
   base::HistogramTester histogram_tester;
   std::vector<SampledProfile> stored_profiles;
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc
index f9962206..aa16fd7 100644
--- a/chrome/browser/metrics/process_memory_metrics_emitter.cc
+++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -13,7 +13,6 @@
 #include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/stringprintf.h"
@@ -828,7 +827,7 @@
                              &Memory_Experimental::SetGpuMemory};
 
   uint64_t total = 0;
-  for (size_t i = 0; i < base::size(gpu_categories); ++i) {
+  for (size_t i = 0; i < std::size(gpu_categories); ++i) {
     total +=
         pmd.GetMetric(gpu_categories[i], synthetic_metric.metric).value_or(0);
   }
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_features.cc b/chrome/browser/nearby_sharing/common/nearby_share_features.cc
index cb1c149..b823040 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_features.cc
+++ b/chrome/browser/nearby_sharing/common/nearby_share_features.cc
@@ -40,6 +40,11 @@
 const base::Feature kNearbySharingSelfShare{"NearbySharingSelfShare",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables notification to reminde users of their visibility selections.
+const base::Feature kNearbySharingVisibilityReminder(
+    "NearbyShareVisibilityReminder",
+    base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables use of WebRTC in Nearby Share.
 const base::Feature kNearbySharingWebRtc{"NearbySharingWebRtc",
                                          base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_features.h b/chrome/browser/nearby_sharing/common/nearby_share_features.h
index 303f247..127fdf3 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_features.h
+++ b/chrome/browser/nearby_sharing/common/nearby_share_features.h
@@ -16,6 +16,7 @@
 extern const base::Feature kNearbySharingOnePageOnboarding;
 extern const base::Feature kNearbySharingReceiveWifiCredentials;
 extern const base::Feature kNearbySharingSelfShare;
+extern const base::Feature kNearbySharingVisibilityReminder;
 extern const base::Feature kNearbySharingWebRtc;
 extern const base::Feature kNearbySharingWifiLan;
 
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc b/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
index 83c67f3f..404fb515 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
+++ b/chrome/browser/nearby_sharing/common/nearby_share_prefs.cc
@@ -55,7 +55,8 @@
     "nearby_sharing.scheduler.upload_device_name";
 const char kNearbySharingSchedulerUploadLocalDeviceCertificatesPrefName[] =
     "nearby_sharing.scheduler.upload_local_device_certificates";
-
+const char kNearbySharingNextVisibilityReminderTimePrefName[] =
+    "nearby_sharing.next_visibility_reminder_time";
 }  // namespace prefs
 
 void RegisterNearbySharingPrefs(PrefRegistrySimple* registry) {
@@ -91,6 +92,9 @@
   registry->RegisterTimePref(
       prefs::kNearbySharingNearbyDeviceTryingToShareDismissedTimePrefName,
       /*default_value=*/base::Time());
+  registry->RegisterTimePref(
+      prefs::kNearbySharingNextVisibilityReminderTimePrefName,
+      /*default_value=*/base::Time());
   registry->RegisterDictionaryPref(
       prefs::kNearbySharingPublicCertificateExpirationDictPrefName);
   registry->RegisterListPref(
diff --git a/chrome/browser/nearby_sharing/common/nearby_share_prefs.h b/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
index 1d689ff7..b50d284 100644
--- a/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
+++ b/chrome/browser/nearby_sharing/common/nearby_share_prefs.h
@@ -35,6 +35,7 @@
 extern const char kNearbySharingSchedulerUploadDeviceNamePrefName[];
 extern const char
     kNearbySharingSchedulerUploadLocalDeviceCertificatesPrefName[];
+extern const char kNearbySharingNextVisibilityReminderTimePrefName[];
 
 }  // namespace prefs
 
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.cc b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
index ae38945..a52e450 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc
@@ -21,6 +21,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_enums.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"
@@ -52,6 +53,8 @@
     "chrome://nearby_share/result/";
 constexpr char kNearbyDeviceTryingToShareNotificationId[] =
     "chrome://nearby_share/nearby_device_trying_to_share";
+constexpr char kNearbyVisibilityReminderNotificationId[] =
+    "chrome://nearby_share/visibility_reminder";
 constexpr char kNearbyNotifier[] = "nearby";
 
 std::string CreateNotificationIdForShareTarget(
@@ -591,6 +594,52 @@
   NearbyNotificationManager* manager_;
 };
 
+bool IsVisibilityReminderEnabled() {
+  return base::FeatureList::IsEnabled(
+      features::kNearbySharingVisibilityReminder);
+}
+
+class NearbyVisibilityReminderNotificationDelegate
+    : public NearbyNotificationDelegate {
+ public:
+  explicit NearbyVisibilityReminderNotificationDelegate(
+      NearbyNotificationManager* manager)
+      : manager_(manager) {
+    // Make sure the delegate is only created when the feature flag is enabled.
+    DCHECK(IsVisibilityReminderEnabled());
+  }
+
+  ~NearbyVisibilityReminderNotificationDelegate() override = default;
+
+  void OnClick(const std::string& notification_id,
+               const absl::optional<int>& action_index) override {
+    if (!action_index) {
+      // Open settings when user click the notification.
+      manager_->OnNearbyVisibilityReminderClicked();
+      return;
+    }
+
+    switch (*action_index) {
+      case 0:
+        manager_->OnNearbyVisibilityReminderClicked();
+        break;
+      case 1:
+        manager_->OnNearbyVisibilityReminderDismissed();
+        break;
+      default:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  void OnClose(const std::string& notification_id) override {
+    manager_->OnNearbyVisibilityReminderDismissed();
+  }
+
+ private:
+  NearbyNotificationManager* manager_;
+};
+
 bool ShouldShowNearbyDeviceTryingToShareNotification(
     PrefService* pref_service) {
   base::Time last_dismissed = pref_service->GetTime(
@@ -609,6 +658,14 @@
   return true;
 }
 
+bool ShouldShowNearbyVisibilityReminderNotification(PrefService* pref_service) {
+  Visibility visibility = static_cast<Visibility>(
+      pref_service->GetInteger(prefs::kNearbySharingBackgroundVisibilityName));
+
+  return visibility == Visibility::kAllContacts ||
+         visibility == Visibility::kSelectedContacts;
+}
+
 void UpdateNearbyDeviceTryingToShareDismissedTime(PrefService* pref_service) {
   pref_service->SetTime(
       prefs::kNearbySharingNearbyDeviceTryingToShareDismissedTimePrefName,
@@ -1030,6 +1087,35 @@
       /*metadata=*/nullptr);
 }
 
+void NearbyNotificationManager::ShowVisibilityReminder() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  DCHECK(IsVisibilityReminderEnabled());
+  DCHECK(ShouldShowNearbyVisibilityReminderNotification(pref_service_));
+
+  message_center::Notification notification =
+      CreateNearbyNotification(kNearbyVisibilityReminderNotificationId);
+  notification.set_title(l10n_util::GetStringUTF16(
+      IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE));
+  notification.set_message(l10n_util::GetStringUTF16(
+      IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE));
+
+  std::vector<message_center::ButtonInfo> notification_actions;
+  notification_actions.emplace_back(
+      l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION));
+  notification_actions.emplace_back(
+      l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_DISMISS_ACTION));
+
+  notification.set_buttons(notification_actions);
+
+  delegate_map_[kNearbyVisibilityReminderNotificationId] =
+      std::make_unique<NearbyVisibilityReminderNotificationDelegate>(this);
+
+  notification_display_service_->Display(
+      NotificationHandler::Type::NEARBY_SHARE, notification,
+      /*metadata=*/nullptr);
+}
+
 void NearbyNotificationManager::CloseTransfer() {
   delegate_map_.erase(kNearbyInProgressNotificationId);
   notification_display_service_->Close(NotificationHandler::Type::NEARBY_SHARE,
@@ -1043,6 +1129,12 @@
       kNearbyDeviceTryingToShareNotificationId);
 }
 
+void NearbyNotificationManager::CloseVisibilityReminder() {
+  delegate_map_.erase(kNearbyVisibilityReminderNotificationId);
+  notification_display_service_->Close(NotificationHandler::Type::NEARBY_SHARE,
+                                       kNearbyVisibilityReminderNotificationId);
+}
+
 NearbyNotificationDelegate* NearbyNotificationManager::GetNotificationDelegate(
     const std::string& notification_id) {
   auto iter = delegate_map_.find(notification_id);
@@ -1138,6 +1230,20 @@
                                        notification_id);
 }
 
+void NearbyNotificationManager::OnNearbyVisibilityReminderClicked() {
+  CloseVisibilityReminder();
+
+  std::string path =
+      std::string(chromeos::settings::mojom::kNearbyShareSubpagePath) +
+      "?visibility";
+
+  settings_opener_->ShowSettingsPage(profile_, path);
+}
+
+void NearbyNotificationManager::OnNearbyVisibilityReminderDismissed() {
+  CloseVisibilityReminder();
+}
+
 void NearbyNotificationManager::SetOnSuccessClickedForTesting(
     base::OnceCallback<void(SuccessNotificationAction)> callback) {
   success_action_test_callback_ = std::move(callback);
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager.h b/chrome/browser/nearby_sharing/nearby_notification_manager.h
index 08c962e..0d1b920 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager.h
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager.h
@@ -112,6 +112,9 @@
   // Shows a notification for send or receive cancellation.
   void ShowCancelled(const ShareTarget& share_target);
 
+  // Shows a notification to remind users of their current visibility selection.
+  void ShowVisibilityReminder();
+
   // Closes any currently shown transfer notification (e.g. progress or
   // connection).
   void CloseTransfer();
@@ -121,6 +124,9 @@
   // visibility mode UI.
   void CloseNearbyDeviceTryingToShare();
 
+  // Closes any currently shown nearby visibility reminder notification.
+  void CloseVisibilityReminder();
+
   // Gets the currently registered delegate for |notification_id|.
   NearbyNotificationDelegate* GetNotificationDelegate(
       const std::string& notification_id);
@@ -145,6 +151,12 @@
 
   void CloseSuccessNotification(const std::string& notification_id);
 
+  // Called when the nearby visibility reminder notification got clicked.
+  void OnNearbyVisibilityReminderClicked();
+
+  // Called when the nearby visibility reminder notification got dismissed.
+  void OnNearbyVisibilityReminderDismissed();
+
   void SetOnSuccessClickedForTesting(
       base::OnceCallback<void(SuccessNotificationAction)> callback);
   void SetSettingsOpenerForTesting(
diff --git a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
index 38a3082..4a208b6 100644
--- a/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
+++ b/chrome/browser/nearby_sharing/nearby_notification_manager_unittest.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.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/threading/thread_restrictions.h"
@@ -26,6 +27,7 @@
 #include "chrome/browser/download/download_core_service_factory.h"
 #include "chrome/browser/download/download_core_service_impl.h"
 #include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/nearby_sharing/common/nearby_share_enums.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/constants.h"
@@ -140,12 +142,23 @@
 
 class NearbyNotificationManagerTestBase : public testing::Test {
  public:
-  explicit NearbyNotificationManagerTestBase(bool enable_self_share) {
-    is_self_share_enabled_ = enable_self_share;
+  explicit NearbyNotificationManagerTestBase(
+      std::tuple<bool, bool> feature_list) {
+    std::vector<base::Feature> enabled_features;
+    std::vector<base::Feature> disabled_features;
+    is_self_share_enabled_ = std::get<0>(feature_list);
+    is_visibility_reminder_enabled_ = std::get<1>(feature_list);
     if (is_self_share_enabled_) {
-      scoped_feature_list_.InitAndEnableFeature(
-          features::kNearbySharingSelfShare);
+      enabled_features.push_back(features::kNearbySharingSelfShare);
+    } else {
+      disabled_features.push_back(features::kNearbySharingSelfShare);
     }
+    if (is_visibility_reminder_enabled_) {
+      enabled_features.push_back(features::kNearbySharingVisibilityReminder);
+    } else {
+      disabled_features.push_back(features::kNearbySharingVisibilityReminder);
+    }
+    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
     RegisterNearbySharingPrefs(pref_service_.registry());
   }
 
@@ -242,6 +255,11 @@
     return share_target;
   }
 
+  void ExpectShowVisibilityReminderDcheckDeath() {
+    ::testing::FLAGS_gtest_death_test_style = "fast";
+    EXPECT_DCHECK_DEATH(manager()->ShowVisibilityReminder());
+  }
+
  protected:
   base::test::ScopedFeatureList scoped_feature_list_;
   base::ScopedTempDir temp_dir_;
@@ -257,14 +275,17 @@
   data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
   MockSettingsOpener* settings_opener_;
   bool is_self_share_enabled_ = false;
+  bool is_visibility_reminder_enabled_ = false;
 };
 
-// We parameterize these tests to run them with Self Share enabled and disabled.
-class NearbyNotificationManagerTest : public NearbyNotificationManagerTestBase,
-                                      public testing::WithParamInterface<bool> {
+// We parameterize these tests to run them with Self Share and Nearby Share
+// Visibility Reminder enabled and disabled.
+class NearbyNotificationManagerTest
+    : public NearbyNotificationManagerTestBase,
+      public testing::WithParamInterface<std::tuple<bool, bool>> {
  public:
   NearbyNotificationManagerTest()
-      : NearbyNotificationManagerTestBase(/*enable_self_share=*/GetParam()) {}
+      : NearbyNotificationManagerTestBase(/*feature_list=*/GetParam()) {}
 };
 
 struct AttachmentsTestParamInternal {
@@ -342,9 +363,10 @@
      IDS_NEARBY_FILE_ATTACHMENTS_NOT_CAPITALIZED_UNKNOWN},
 };
 
-// Boolean parameters are |is_incoming| and |enable_self_share|.
+// Boolean parameter is |is_incoming| and the tuple parameter is featuree list
+// contains |enable_self_share| and |enable_visibility_reminder|.
 using AttachmentsTestParam =
-    std::tuple<AttachmentsTestParamInternal, bool, bool>;
+    std::tuple<AttachmentsTestParamInternal, bool, std::tuple<bool, bool>>;
 
 class NearbyNotificationManagerAttachmentsTest
     : public NearbyNotificationManagerTestBase,
@@ -352,11 +374,12 @@
  public:
   NearbyNotificationManagerAttachmentsTest()
       : NearbyNotificationManagerTestBase(
-            /*enable_self_share=*/std::get<2>(GetParam())) {}
+            /*feature_list=*/std::get<2>(GetParam())) {}
 };
 
-// Boolean parameters are |with_token| and |enable_self_share|.
-using ConnectionRequestTestParam = std::tuple<bool, bool>;
+// Boolean parameter is |with_token| and the tuple parameter is featuree list
+// contains |enable_self_share| and |enable_visibility_reminder|.
+using ConnectionRequestTestParam = std::tuple<bool, std::tuple<bool, bool>>;
 
 class NearbyNotificationManagerConnectionRequestTest
     : public NearbyNotificationManagerTestBase,
@@ -364,7 +387,7 @@
  public:
   NearbyNotificationManagerConnectionRequestTest()
       : NearbyNotificationManagerTestBase(
-            /*enable_self_share=*/std::get<1>(GetParam())) {}
+            /*feature_list=*/std::get<1>(GetParam())) {}
 };
 
 std::u16string FormatNotificationTitle(
@@ -624,7 +647,7 @@
     NearbyNotificationManagerAttachmentsTest,
     testing::Combine(testing::ValuesIn(kAttachmentsTestParams),
                      testing::Bool(),
-                     testing::Bool()));
+                     testing::Combine(testing::Bool(), testing::Bool())));
 
 TEST_P(NearbyNotificationManagerConnectionRequestTest,
        ShowConnectionRequest_ShowsNotification) {
@@ -699,7 +722,9 @@
 
 INSTANTIATE_TEST_SUITE_P(NearbyNotificationManagerConnectionRequestTest,
                          NearbyNotificationManagerConnectionRequestTest,
-                         testing::Combine(testing::Bool(), testing::Bool()));
+                         testing::Combine(testing::Bool(),
+                                          testing::Combine(testing::Bool(),
+                                                           testing::Bool())));
 
 TEST_P(NearbyNotificationManagerTest,
        ShowConnectionRequest_DeviceNameEncoding) {
@@ -1608,6 +1633,134 @@
   ASSERT_EQ(6u, notifications.size());
 }
 
+TEST_P(NearbyNotificationManagerTest, ShowVisibilityReminder_Contacts_Mode) {
+  pref_service_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName,
+                           static_cast<int>(Visibility::kAllContacts));
+  if (!is_visibility_reminder_enabled_) {
+    ExpectShowVisibilityReminderDcheckDeath();
+  } else {
+    manager()->ShowVisibilityReminder();
+    std::vector<message_center::Notification> notifications =
+        GetDisplayedNotifications();
+    ASSERT_EQ(1u, notifications.size());
+    const message_center::Notification& notification = notifications[0];
+    EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE, notification.type());
+    EXPECT_EQ(l10n_util::GetStringUTF16(
+                  IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_TITLE),
+              notification.title());
+    EXPECT_EQ(l10n_util::GetStringUTF16(
+                  IDS_NEARBY_NOTIFICATION_VISIBILITY_REMINDER_MESSAGE),
+              notification.message());
+    EXPECT_TRUE(notification.icon().IsEmpty());
+    EXPECT_EQ(GURL(), notification.origin_url());
+    EXPECT_FALSE(notification.never_timeout());
+    EXPECT_FALSE(notification.renotify());
+    EXPECT_EQ(&kNearbyShareIcon, &notification.vector_small_image());
+    EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_SOURCE),
+              notification.display_source());
+    EXPECT_EQ(2u, notification.buttons().size());
+
+    std::vector<std::u16string> expected_button_titles;
+    expected_button_titles.push_back(l10n_util::GetStringUTF16(
+        IDS_NEARBY_NOTIFICATION_GO_TO_SETTINGS_ACTION));
+    expected_button_titles.push_back(
+        l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_DISMISS_ACTION));
+
+    const std::vector<message_center::ButtonInfo>& buttons =
+        notification.buttons();
+    ASSERT_EQ(expected_button_titles.size(), buttons.size());
+
+    for (size_t i = 0; i < expected_button_titles.size(); ++i)
+      EXPECT_EQ(expected_button_titles[i], buttons[i].title);
+  }
+}
+
+TEST_P(NearbyNotificationManagerTest, ShowVisibilityReminder_Hidden_Mode) {
+  ExpectShowVisibilityReminderDcheckDeath();
+}
+
+TEST_P(NearbyNotificationManagerTest,
+       ShowVisibilityReminder_Notification_Clicked) {
+  pref_service_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName,
+                           static_cast<int>(Visibility::kSelectedContacts));
+  if (!is_visibility_reminder_enabled_) {
+    ExpectShowVisibilityReminderDcheckDeath();
+  } else {
+    manager()->ShowVisibilityReminder();
+    std::vector<message_center::Notification> notifications =
+        GetDisplayedNotifications();
+    ASSERT_EQ(1u, notifications.size());
+    EXPECT_CALL(*settings_opener_, ShowSettingsPage(_, _));
+    notification_tester_->SimulateClick(NotificationHandler::Type::NEARBY_SHARE,
+                                        notifications[0].id(),
+                                        /*action_index=*/absl::optional<int>(),
+                                        /*reply=*/absl::nullopt);
+
+    // Notification should be closed.
+    EXPECT_EQ(0u, GetDisplayedNotifications().size());
+  }
+}
+
+TEST_P(NearbyNotificationManagerTest, ShowVisibilityReminder_Settings_Clicked) {
+  pref_service_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName,
+                           static_cast<int>(Visibility::kAllContacts));
+  if (!is_visibility_reminder_enabled_) {
+    ExpectShowVisibilityReminderDcheckDeath();
+  } else {
+    manager()->ShowVisibilityReminder();
+    std::vector<message_center::Notification> notifications =
+        GetDisplayedNotifications();
+    ASSERT_EQ(1u, notifications.size());
+    EXPECT_CALL(*settings_opener_, ShowSettingsPage(_, _));
+    notification_tester_->SimulateClick(NotificationHandler::Type::NEARBY_SHARE,
+                                        notifications[0].id(),
+                                        /*action_index=*/0,
+                                        /*reply=*/absl::nullopt);
+
+    // Notification should be closed.
+    EXPECT_EQ(0u, GetDisplayedNotifications().size());
+  }
+}
+
+TEST_P(NearbyNotificationManagerTest, ShowVisibilityReminder_Dismiss_Clicked) {
+  pref_service_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName,
+                           static_cast<int>(Visibility::kAllContacts));
+  if (!is_visibility_reminder_enabled_) {
+    ExpectShowVisibilityReminderDcheckDeath();
+  } else {
+    manager()->ShowVisibilityReminder();
+    std::vector<message_center::Notification> notifications =
+        GetDisplayedNotifications();
+    ASSERT_EQ(1u, notifications.size());
+    notification_tester_->SimulateClick(NotificationHandler::Type::NEARBY_SHARE,
+                                        notifications[0].id(),
+                                        /*action_index=*/1,
+                                        /*reply=*/absl::nullopt);
+
+    // Notification should be closed.
+    EXPECT_EQ(0u, GetDisplayedNotifications().size());
+  }
+}
+
+TEST_P(NearbyNotificationManagerTest,
+       ShowVisibilityReminder_Notification_Closed) {
+  pref_service_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName,
+                           static_cast<int>(Visibility::kAllContacts));
+  if (!is_visibility_reminder_enabled_) {
+    ExpectShowVisibilityReminderDcheckDeath();
+  } else {
+    manager()->ShowVisibilityReminder();
+    std::vector<message_center::Notification> notifications =
+        GetDisplayedNotifications();
+    ASSERT_EQ(1u, notifications.size());
+    notification_tester_->RemoveNotification(
+        NotificationHandler::Type::NEARBY_SHARE, notifications[0].id(), true);
+
+    // Notification should be closed.
+    EXPECT_EQ(0u, GetDisplayedNotifications().size());
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(NearbyNotificationManagerTest,
                          NearbyNotificationManagerTest,
-                         testing::Bool());
+                         testing::Combine(testing::Bool(), testing::Bool()));
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
index 5a0b86d4..3a3e9ed 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -26,12 +26,14 @@
 #include "base/task/task_runner_util.h"
 #include "base/task/thread_pool.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/nearby_sharing/certificates/common.h"
 #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h"
 #include "chrome/browser/nearby_sharing/certificates/nearby_share_encrypted_metadata_key.h"
 #include "chrome/browser/nearby_sharing/client/nearby_share_client_impl.h"
+#include "chrome/browser/nearby_sharing/common/nearby_share_enums.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/constants.h"
@@ -103,6 +105,12 @@
 constexpr base::TimeDelta kClearNearbyProcessUnexpectedShutdownCountDelay =
     base::Minutes(1);
 
+// The length of window during which we display visibility reminder
+// notification to users. The real length set for timer should be calculated
+// by (180 - kNearbySharingVisibilityReminderLastShownTimePrefName set in
+// nearby_share_prefs).
+constexpr base::TimeDelta kNearbyVisibilityReminderTimerDelay = base::Days(180);
+
 bool IsBackgroundScanningFeatureEnabled() {
   return base::FeatureList::IsEnabled(
              features::kNearbySharingBackgroundScanning) &&
@@ -234,6 +242,11 @@
   return payload_id;
 }
 
+bool IsVisibilityReminderEnabled() {
+  return base::FeatureList::IsEnabled(
+      features::kNearbySharingVisibilityReminder);
+}
+
 // Wraps a call to OnTransferUpdate() to filter any updates after receiving a
 // final status.
 class TransferUpdateDecorator : public TransferUpdateCallback {
@@ -348,6 +361,7 @@
     certificate_manager_->Start();
     BindToNearbyProcess();
   }
+  UpdateVisibilityReminderTimer(/*reset_timestamp=*/false);
 }
 
 NearbySharingServiceImpl::~NearbySharingServiceImpl() {
@@ -1224,6 +1238,7 @@
     process_reference_.reset();
   }
 
+  UpdateVisibilityReminderTimer(/*reset_timestamp=*/false);
   InvalidateSurfaceState();
 }
 
@@ -1256,6 +1271,9 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   NS_LOG(INFO) << __func__ << ": Nearby sharing visibility changed to "
                << new_visibility;
+
+  UpdateVisibilityReminderTimer(/*reset_timestamp=*/true);
+
   StopAdvertisingAndInvalidateSurfaceState();
 }
 
@@ -4244,3 +4262,41 @@
     info->connection()->Close();
   }
 }
+
+void NearbySharingServiceImpl::UpdateVisibilityReminderTimer(
+    bool reset_timestamp) {
+  if (!IsVisibilityReminderEnabled() || !settings_.GetEnabled() ||
+      !IsVisibleInBackground(settings_.GetVisibility())) {
+    visibility_reminder_timer_.Stop();
+    return;
+  }
+
+  if (reset_timestamp ||
+      prefs_->GetTime(prefs::kNearbySharingNextVisibilityReminderTimePrefName)
+          .is_null()) {
+    prefs_->SetTime(prefs::kNearbySharingNextVisibilityReminderTimePrefName,
+                    base::Time::Now() + kNearbyVisibilityReminderTimerDelay);
+  }
+
+  visibility_reminder_timer_.Start(
+      FROM_HERE, GetTimeUntilNextVisibilityReminder(),
+      base::BindOnce(&NearbySharingServiceImpl::OnVisibilityReminderTimerFired,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void NearbySharingServiceImpl::OnVisibilityReminderTimerFired() {
+  nearby_notification_manager_->ShowVisibilityReminder();
+  UpdateVisibilityReminderTimer(/*reset_timestamp=*/true);
+}
+
+// Calculate the actual time when next visibility reminder will be shown.
+base::TimeDelta NearbySharingServiceImpl::GetTimeUntilNextVisibilityReminder() {
+  base::Time next_visibility_reminder_time =
+      prefs_->GetTime(prefs::kNearbySharingNextVisibilityReminderTimePrefName);
+  base::TimeDelta time_until_next_reminder =
+      next_visibility_reminder_time - base::Time::Now();
+
+  // Immediately show visibility reminder if it's already passed 180 days since
+  // last time user saw the reminder.
+  return std::max(base::Seconds(0), time_until_next_reminder);
+}
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
index c9a8137..1f01f66 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -412,6 +412,15 @@
   void AbortAndCloseConnectionIfNecessary(const TransferMetadata::Status status,
                                           const ShareTarget& share_target);
 
+  // The method is responsible for updating visibility reminder timer:
+  // 1) Stops the timer if the feature flag is disabled OR Nearby Share is
+  // disabled OR visibility is changed to 'Hidden"; 2) Restart the timer and
+  // update the timestamp if we force it to update OR it's past 180 days since
+  // last time we updated it.
+  void UpdateVisibilityReminderTimer(bool reset_timestamp);
+  void OnVisibilityReminderTimerFired();
+  base::TimeDelta GetTimeUntilNextVisibilityReminder();
+
   PrefService* prefs_ = nullptr;
   Profile* profile_;
   std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_;
@@ -549,6 +558,9 @@
   // immediately after a completed share.
   base::OneShotTimer fast_initiation_scanner_cooldown_timer_;
 
+  // Used to control when to show visibility reminder notification to users.
+  base::OneShotTimer visibility_reminder_timer_;
+
   // Available free disk space for testing. Using real disk space can introduce
   // flakiness in tests.
   absl::optional<int64_t> free_disk_space_for_testing_;
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
index cc7761b..d1b2a6b 100644
--- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
+++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
@@ -45,6 +45,7 @@
 #include "chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h"
 #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h"
 #include "chrome/browser/nearby_sharing/nearby_connections_manager.h"
+#include "chrome/browser/nearby_sharing/nearby_notification_manager.h"
 #include "chrome/browser/nearby_sharing/nearby_share_feature_status.h"
 #include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
 #include "chrome/browser/nearby_sharing/power_client.h"
@@ -340,7 +341,8 @@
 // all permutations. To add or a remove a feature you can just update this list.
 const std::vector<base::Feature> kTestFeatures = {
     features::kNearbySharingBackgroundScanning,
-    features::kNearbySharingSelfShare};
+    features::kNearbySharingSelfShare,
+    features::kNearbySharingVisibilityReminder};
 
 bool FileExists(const base::FilePath& file_path) {
   base::ScopedAllowBlockingForTesting allow_blocking;
@@ -531,6 +533,8 @@
     service_ = CreateService();
     SetFakeFastInitiationAdvertiserFactory(/*should_succeed_on_start=*/true);
 
+    EXPECT_FALSE(IsVisibilityReminderTimerRunning());
+
     service_->set_free_disk_space_for_testing(kFreeDiskSpace);
 
     // From now on we don't allow any blocking tasks anymore.
@@ -1329,6 +1333,10 @@
     service_->recent_nearby_process_unexpected_shutdown_count_ = count;
   }
 
+  bool IsVisibilityReminderTimerRunning() {
+    return service_->visibility_reminder_timer_.IsRunning();
+  }
+
   base::test::ScopedFeatureList scoped_feature_list_;
   base::ScopedTempDir temp_dir_;
   // We need to ensure that |network_notifier_| is created and destroyed after
@@ -4945,6 +4953,22 @@
   EXPECT_EQ(1u, fast_initiation_scanner_factory_->scanner_destroyed_count());
 }
 
+TEST_P(NearbySharingServiceImplTest, VisibilityReminderTimerAfterSixMonth) {
+  SetVisibility(Visibility::kAllContacts);
+  task_environment_.FastForwardBy(base::Days(180));
+  std::vector<message_center::Notification> notifications =
+      notification_tester_->GetDisplayedNotificationsForType(
+          NotificationHandler::Type::NEARBY_SHARE);
+
+  if (!base::FeatureList::IsEnabled(
+          features::kNearbySharingVisibilityReminder)) {
+    EXPECT_EQ(0u, notifications.size());
+  } else {
+    // Visibility reminder notification should display after 180 days.
+    EXPECT_EQ(1u, notifications.size());
+  }
+}
+
 TEST_P(NearbySharingServiceImplTest, CreateShareTarget) {
   sharing::mojom::AdvertisementPtr advertisement =
       sharing::mojom::Advertisement::New(
@@ -4987,4 +5011,79 @@
                          NearbySharingServiceImplTest,
                          testing::Range<size_t>(0, 1 << kTestFeatures.size()));
 
+// The boolean variable represents is service enabled. Visibility represents
+// different visibility selections.
+using VisibilityReminderTestParams =
+    std::tuple<bool, nearby_share::mojom::Visibility, size_t>;
+
+class NearbySharingServiceVisibilityReminderTest
+    : public NearbySharingServiceImplTestBase,
+      public testing::WithParamInterface<VisibilityReminderTestParams> {
+ public:
+  NearbySharingServiceVisibilityReminderTest()
+      : NearbySharingServiceImplTestBase(std::get<2>(GetParam())) {}
+};
+
+TEST_P(NearbySharingServiceVisibilityReminderTest,
+       StartOrStopVisibilityReminderTimerAppropriatelyWhenEnableOrDisable) {
+  bool is_enabled = std::get<0>(GetParam());
+  nearby_share::mojom::Visibility visibility = std::get<1>(GetParam());
+
+  SetVisibility(visibility);
+  SetIsEnabled(is_enabled);
+  if (is_enabled) {
+    switch (visibility) {
+      case nearby_share::mojom::Visibility::kAllContacts:
+      case nearby_share::mojom::Visibility::kSelectedContacts:
+        EXPECT_EQ(base::FeatureList::IsEnabled(
+                      features::kNearbySharingVisibilityReminder),
+                  IsVisibilityReminderTimerRunning());
+        break;
+      case nearby_share::mojom::Visibility::kNoOne:
+        EXPECT_FALSE(IsVisibilityReminderTimerRunning());
+        break;
+      default:
+        break;
+    }
+  } else {
+    EXPECT_FALSE(IsVisibilityReminderTimerRunning());
+  }
+}
+
+TEST_P(NearbySharingServiceVisibilityReminderTest,
+       StartOrStopVisibilityReminderTimerAppropriatelyWhenChangeVisibility) {
+  bool is_enabled = std::get<0>(GetParam());
+  nearby_share::mojom::Visibility visibility = std::get<1>(GetParam());
+
+  SetIsEnabled(is_enabled);
+  if (is_enabled) {
+    SetVisibility(visibility);
+    switch (visibility) {
+      case nearby_share::mojom::Visibility::kAllContacts:
+      case nearby_share::mojom::Visibility::kSelectedContacts:
+        EXPECT_EQ(base::FeatureList::IsEnabled(
+                      features::kNearbySharingVisibilityReminder),
+                  IsVisibilityReminderTimerRunning());
+        break;
+      case nearby_share::mojom::Visibility::kNoOne:
+        EXPECT_FALSE(IsVisibilityReminderTimerRunning());
+        break;
+      default:
+        break;
+    }
+  } else {
+    EXPECT_FALSE(IsVisibilityReminderTimerRunning());
+  }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    NearbySharingServiceImplTest,
+    NearbySharingServiceVisibilityReminderTest,
+    testing::Combine(
+        testing::Bool(),
+        testing::Values(nearby_share::mojom::Visibility::kAllContacts,
+                        nearby_share::mojom::Visibility::kSelectedContacts,
+                        nearby_share::mojom::Visibility::kNoOne),
+        testing::Range<size_t>(0, 1 << kTestFeatures.size())));
+
 }  // namespace NearbySharingServiceUnitTests
diff --git a/chrome/browser/net/service_providers_win.cc b/chrome/browser/net/service_providers_win.cc
index 1c424fda..17dd328 100644
--- a/chrome/browser/net/service_providers_win.cc
+++ b/chrome/browser/net/service_providers_win.cc
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/values.h"
 
@@ -93,7 +92,7 @@
     // http://msdn.microsoft.com/en-us/library/ms742239%28v=VS.85%29.aspx
 
     wchar_t path[MAX_PATH];
-    int path_length = base::size(path);
+    int path_length = std::size(path);
     if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path,
                                 &path_length, &error)) {
       service_provider.path = path;
diff --git a/chrome/browser/notifications/platform_notification_service_unittest.cc b/chrome/browser/notifications/platform_notification_service_unittest.cc
index 84a27f0..af48d83 100644
--- a/chrome/browser/notifications/platform_notification_service_unittest.cc
+++ b/chrome/browser/notifications/platform_notification_service_unittest.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/utf_string_conversions.h"
@@ -201,8 +200,7 @@
 TEST_F(PlatformNotificationServiceTest, DisplayNonPersistentPropertiesMatch) {
   std::vector<int> vibration_pattern(
       kNotificationVibrationPattern,
-      kNotificationVibrationPattern +
-          base::size(kNotificationVibrationPattern));
+      kNotificationVibrationPattern + std::size(kNotificationVibrationPattern));
 
   PlatformNotificationData data;
   data.title = u"My notification's title";
@@ -234,8 +232,7 @@
 TEST_F(PlatformNotificationServiceTest, DisplayPersistentPropertiesMatch) {
   std::vector<int> vibration_pattern(
       kNotificationVibrationPattern,
-      kNotificationVibrationPattern +
-          base::size(kNotificationVibrationPattern));
+      kNotificationVibrationPattern + std::size(kNotificationVibrationPattern));
   PlatformNotificationData data;
   data.title = u"My notification's title";
   data.body = u"Hello, world!";
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeNativeUnitTest.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeNativeUnitTest.java
index a0cfe43..958009b5 100644
--- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeNativeUnitTest.java
+++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeNativeUnitTest.java
@@ -64,8 +64,8 @@
     public void testCanApplyOptimizationAsyncHasHint() {
         OptimizationGuideBridge bridge = new OptimizationGuideBridge();
 
-        NavigationHandle navHandle = new NavigationHandle(0, new GURL(TEST_URL), null, null, true,
-                false, false, null, null, 0, false, false, false, false, 0);
+        NavigationHandle navHandle = new NavigationHandle(0, new GURL(TEST_URL), GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         OptimizationGuideCallback callback = new OptimizationGuideCallback();
         bridge.canApplyOptimizationAsync(navHandle, OptimizationType.PERFORMANCE_HINTS, callback);
 
diff --git a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java b/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
index 6f80a8f..75ec274 100644
--- a/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
+++ b/chrome/browser/optimization_guide/android/javatests/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuideBridgeUnitTest.java
@@ -131,8 +131,8 @@
     public void testCanApplyOptimizationAsync_withoutNativeBridge() {
         GURL gurl = new GURL(TEST_URL);
         OptimizationGuideBridge bridge = new OptimizationGuideBridge(0);
-        NavigationHandle navHandle = new NavigationHandle(0, new GURL(TEST_URL), null, null, true,
-                false, false, null, null, 0, false, false, false, false, 0);
+        NavigationHandle navHandle = new NavigationHandle(0, new GURL(TEST_URL), GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
 
         bridge.canApplyOptimizationAsync(
                 navHandle, OptimizationType.PERFORMANCE_HINTS, mCallbackMock);
@@ -151,8 +151,8 @@
     public void testCanApplyOptimizationAsync() {
         GURL gurl = new GURL(TEST_URL);
         OptimizationGuideBridge bridge = new OptimizationGuideBridge(1);
-        NavigationHandle navHandle = new NavigationHandle(0, gurl, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navHandle = new NavigationHandle(0, gurl, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
 
         bridge.canApplyOptimizationAsync(
                 navHandle, OptimizationType.PERFORMANCE_HINTS, mCallbackMock);
diff --git a/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer.cc
index 9e3a998..1cc7483 100644
--- a/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer.h"
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
 #include "content/public/browser/navigation_handle.h"
@@ -122,7 +121,7 @@
   // Record understat metrics for the time to first contentful paint.
   static constexpr const int kUnderStatRecordingIntervalsSeconds[] = {1, 2, 5,
                                                                       8, 10};
-  static_assert(base::size(kUnderStatRecordingIntervalsSeconds) ==
+  static_assert(std::size(kUnderStatRecordingIntervalsSeconds) ==
                     static_cast<int>(PageLoadTimingUnderStat::kMaxValue),
                 " mismatch in  array length and enum size");
 
@@ -140,8 +139,8 @@
         PageLoadTimingUnderStat::kTotal);
   }
 
-  for (size_t index = 0;
-       index < base::size(kUnderStatRecordingIntervalsSeconds); ++index) {
+  for (size_t index = 0; index < std::size(kUnderStatRecordingIntervalsSeconds);
+       ++index) {
     base::TimeDelta threshold(
         base::Seconds(kUnderStatRecordingIntervalsSeconds[index]));
     if (fcp <= threshold) {
diff --git a/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer_unittest.cc
index d90f716..692359d 100644
--- a/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/scheme_page_load_metrics_observer_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_util.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
@@ -135,7 +134,7 @@
         base::Milliseconds(GetRecordedMetricValue(fcp_histogram_name));
 
     for (size_t index = 0;
-         index < base::size(kUnderStatRecordingIntervalsSeconds); ++index) {
+         index < std::size(kUnderStatRecordingIntervalsSeconds); ++index) {
       base::TimeDelta threshold(
           base::Seconds(kUnderStatRecordingIntervalsSeconds[index]));
       if (recorded_fcp_value <= threshold) {
@@ -153,7 +152,7 @@
     // of the same name in scheme_page_load_metrics_observer.cc.
     tester()->histogram_tester().ExpectBucketCount(
         fcp_understat_histogram_name,
-        base::size(kUnderStatRecordingIntervalsSeconds) + 1, 0);
+        std::size(kUnderStatRecordingIntervalsSeconds) + 1, 0);
   }
 
   raw_ptr<SchemePageLoadMetricsObserver> observer_;
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
index b137dcc..1ead637 100644
--- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
+++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
@@ -384,7 +384,7 @@
                 return getString(view, R.string.password_check_status_message_error_quota_limit);
             case PasswordCheckUIStatus.ERROR_QUOTA_LIMIT_ACCOUNT_CHECK:
                 NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(
-                        getResources(view), unusedView -> launchCheckupInAccount.run());
+                        view.getContext(), unusedView -> launchCheckupInAccount.run());
                 return SpanApplier.applySpans(
                         getString(view,
                                 R.string.password_check_status_message_error_quota_limit_account_check),
diff --git a/chrome/browser/password_manager/password_manager_util_mac.mm b/chrome/browser/password_manager/password_manager_util_mac.mm
index 7ace1fd..55e41d5 100644
--- a/chrome/browser/password_manager/password_manager_util_mac.mm
+++ b/chrome/browser/password_manager/password_manager_util_mac.mm
@@ -8,7 +8,6 @@
 #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"
@@ -26,7 +25,7 @@
   // kAuthorizationRuleAuthenticateAsSessionUser, to ensure that the session
   // user password, as opposed to an admin's password, is required.
   AuthorizationItem right_items[] = {{"system.login.screensaver", 0, NULL, 0}};
-  AuthorizationRights rights = {base::size(right_items), right_items};
+  AuthorizationRights rights = {std::size(right_items), right_items};
 
   NSString* prompt;
   switch (purpose) {
diff --git a/chrome/browser/password_manager/password_manager_util_win.cc b/chrome/browser/password_manager/password_manager_util_win.cc
index b5b8ac1..785266b 100644
--- a/chrome/browser/password_manager/password_manager_util_win.cc
+++ b/chrome/browser/password_manager/password_manager_util_win.cc
@@ -122,7 +122,7 @@
   LUID luid;
   HANDLE token = INVALID_HANDLE_VALUE;
 
-  strcpy_s(source.SourceName, base::size(source.SourceName), "Chrome");
+  strcpy_s(source.SourceName, std::size(source.SourceName), "Chrome");
   if (!AllocateLocallyUniqueId(&source.SourceIdentifier))
     return GetLastError();
 
@@ -274,7 +274,7 @@
                       password_manager::ReauthPurpose purpose) {
   bool retval = false;
   WCHAR cur_username[CREDUI_MAX_USERNAME_LENGTH + 1] = {};
-  DWORD cur_username_length = base::size(cur_username);
+  DWORD cur_username_length = std::size(cur_username);
 
   // If this is a standlone workstation, it's possible the current user has no
   // password, so check here and allow it.
diff --git a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
index 8a140e07..526e1b7 100644
--- a/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
+++ b/chrome/browser/performance_manager/decorators/helpers/page_live_state_decorator_helper_unittest.cc
@@ -52,8 +52,7 @@
 
   void EndToEndStreamPropertyTest(
       blink::mojom::MediaStreamType stream_type,
-      absl::optional<media::mojom::DisplayMediaInformationPtr>
-          display_media_info,
+      media::mojom::DisplayMediaInformationPtr display_media_info,
       bool (PageLiveStateDecorator::Data::*pm_getter)() const);
 
   // Forces deletion of the PageLiveStateDecoratorHelper.
@@ -67,7 +66,7 @@
 
 void PageLiveStateDecoratorHelperTest::EndToEndStreamPropertyTest(
     blink::mojom::MediaStreamType stream_type,
-    absl::optional<media::mojom::DisplayMediaInformationPtr> display_media_info,
+    media::mojom::DisplayMediaInformationPtr display_media_info,
     bool (PageLiveStateDecorator::Data::*pm_getter)() const) {
   // By default all properties are set to false.
   testing::TestPageNodePropertyOnPMSequence(
@@ -101,28 +100,28 @@
 TEST_F(PageLiveStateDecoratorHelperTest, OnIsCapturingVideoChanged) {
   EndToEndStreamPropertyTest(
       blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE,
-      /*display_media_info=*/absl::nullopt,
+      /*display_media_info=*/nullptr,
       &PageLiveStateDecorator::Data::IsCapturingVideo);
 }
 
 TEST_F(PageLiveStateDecoratorHelperTest, OnIsCapturingAudioChanged) {
   EndToEndStreamPropertyTest(
       blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE,
-      /*display_media_info=*/absl::nullopt,
+      /*display_media_info=*/nullptr,
       &PageLiveStateDecorator::Data::IsCapturingAudio);
 }
 
 TEST_F(PageLiveStateDecoratorHelperTest, OnIsBeingMirroredChanged) {
   EndToEndStreamPropertyTest(
       blink::mojom::MediaStreamType::GUM_TAB_VIDEO_CAPTURE,
-      /*display_media_info=*/absl::nullopt,
+      /*display_media_info=*/nullptr,
       &PageLiveStateDecorator::Data::IsBeingMirrored);
 }
 
 TEST_F(PageLiveStateDecoratorHelperTest, OnIsCapturingWindowChanged) {
   EndToEndStreamPropertyTest(
       blink::mojom::MediaStreamType::GUM_DESKTOP_VIDEO_CAPTURE,
-      /*display_media_info=*/absl::nullopt,
+      /*display_media_info=*/nullptr,
       &PageLiveStateDecorator::Data::IsCapturingWindow);
 }
 
diff --git a/chrome/browser/platform_util_unittest.cc b/chrome/browser/platform_util_unittest.cc
index 2645a178..16c4b0c 100644
--- a/chrome/browser/platform_util_unittest.cc
+++ b/chrome/browser/platform_util_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
@@ -187,7 +186,7 @@
     ASSERT_NO_FATAL_FAILURE(PlatformUtilTestBase::SetUp());
 
     static const char kTestFileData[] = "Cow says moo!";
-    const int kTestFileDataLength = base::size(kTestFileData) - 1;
+    const int kTestFileDataLength = std::size(kTestFileData) - 1;
 
     // This prevents platform_util from invoking any shell or external APIs
     // during tests. Doing so may result in external applications being launched
diff --git a/chrome/browser/platform_util_win.cc b/chrome/browser/platform_util_win.cc
index 6b84d3ed..9ce3b47 100644
--- a/chrome/browser/platform_util_win.cc
+++ b/chrome/browser/platform_util_win.cc
@@ -15,7 +15,6 @@
 
 #include "base/base_paths.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -73,8 +72,7 @@
   if (!platform_util::internal::AreShellOperationsAllowed())
     return;
 
-  hr =
-      SHOpenFolderAndSelectItems(dir_item, base::size(highlight), highlight, 0);
+  hr = SHOpenFolderAndSelectItems(dir_item, std::size(highlight), highlight, 0);
   if (FAILED(hr)) {
     // On some systems, the above call mysteriously fails with "file not
     // found" even though the file is there.  In these cases, ShellExecute()
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 6c4e2fd7..8e77d5d 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -13,7 +13,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/values.h"
 #include "build/branding_buildflags.h"
@@ -1665,7 +1664,7 @@
           base::BindRepeating(&PopulatePolicyHandlerParameters),
           base::BindRepeating(&GetChromePolicyDetails),
           AreFuturePoliciesSupported()));
-  for (size_t i = 0; i < base::size(kSimplePolicyMap); ++i) {
+  for (size_t i = 0; i < std::size(kSimplePolicyMap); ++i) {
     handlers->AddHandler(std::make_unique<SimplePolicyHandler>(
         kSimplePolicyMap[i].policy_name, kSimplePolicyMap[i].preference_path,
         kSimplePolicyMap[i].value_type));
diff --git a/chrome/browser/policy/site_isolation_policy_browsertest.cc b/chrome/browser/policy/site_isolation_policy_browsertest.cc
index 3f3c83b0..12a8e42 100644
--- a/chrome/browser/policy/site_isolation_policy_browsertest.cc
+++ b/chrome/browser/policy/site_isolation_policy_browsertest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
@@ -167,7 +166,7 @@
       {"http://foo.com/", true},
       {"http://example.org/pumpkins.html", true},
   };
-  CheckExpectations(expectations, base::size(expectations));
+  CheckExpectations(expectations, std::size(expectations));
 }
 
 IN_PROC_BROWSER_TEST_F(IsolateOriginsPolicyBrowserTest, Simple) {
@@ -178,7 +177,7 @@
       {"https://policy1.example.org/pumpkins.html", true},
       {"http://policy2.example.com/index.php", true},
   };
-  CheckIsolatedOriginExpectations(expectations, base::size(expectations));
+  CheckIsolatedOriginExpectations(expectations, std::size(expectations));
 
   // Simulate updating the policy at "browser runtime".
   policy::PolicyMap values;
@@ -202,7 +201,7 @@
       {"https://policy3.example.org/pumpkins.html", true},
       {"http://policy4.example.com/index.php", true},
   };
-  CheckIsolatedOriginExpectations(expectations2, base::size(expectations2));
+  CheckIsolatedOriginExpectations(expectations2, std::size(expectations2));
 }
 
 IN_PROC_BROWSER_TEST_F(NoOverrideSitePerProcessPolicyBrowserTest, Simple) {
@@ -210,7 +209,7 @@
       {"https://foo.com/noodles.html", true},
       {"http://example.org/pumpkins.html", true},
   };
-  CheckExpectations(expectations, base::size(expectations));
+  CheckExpectations(expectations, std::size(expectations));
 }
 
 // After https://crbug.com/910273 was fixed, enterprise policy can only be used
@@ -258,7 +257,7 @@
       {"https://foo.com/noodles.html", false},
       {"http://example.org/pumpkins.html", false},
   };
-  CheckExpectations(expectations, base::size(expectations));
+  CheckExpectations(expectations, std::size(expectations));
 }
 #endif
 
diff --git a/chrome/browser/policy/test/media_stream_policy_browsertest.cc b/chrome/browser/policy/test/media_stream_policy_browsertest.cc
index debe3ea..3133ec87 100644
--- a/chrome/browser/policy/test/media_stream_policy_browsertest.cc
+++ b/chrome/browser/policy/test/media_stream_policy_browsertest.cc
@@ -195,7 +195,7 @@
       nullptr,
   };
 
-  for (size_t i = 0; i < base::size(allow_pattern); ++i) {
+  for (size_t i = 0; i < std::size(allow_pattern); ++i) {
     PolicyMap policies;
     ConfigurePolicyMap(&policies, key::kAudioCaptureAllowed,
                        key::kAudioCaptureAllowedUrls, allow_pattern[i]);
@@ -259,7 +259,7 @@
       nullptr,
   };
 
-  for (size_t i = 0; i < base::size(allow_pattern); ++i) {
+  for (size_t i = 0; i < std::size(allow_pattern); ++i) {
     PolicyMap policies;
     ConfigurePolicyMap(&policies, key::kVideoCaptureAllowed,
                        key::kVideoCaptureAllowedUrls, allow_pattern[i]);
diff --git a/chrome/browser/policy/test/restore_on_startup_policy_browsertest.cc b/chrome/browser/policy/test/restore_on_startup_policy_browsertest.cc
index 7f3e8830..dff015139 100644
--- a/chrome/browser/policy/test/restore_on_startup_policy_browsertest.cc
+++ b/chrome/browser/policy/test/restore_on_startup_policy_browsertest.cc
@@ -6,7 +6,6 @@
 
 #include "base/command_line.h"
 #include "base/containers/cxx20_erase.h"
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/policy/url_blocking_policy_test_utils.h"
@@ -154,7 +153,7 @@
   // Check if |kRestoredURLs| are opened on the current browser.
   bool AreRestoredURLsOpened() const {
     TabStripModel* model = browser()->tab_strip_model();
-    if (model->count() != base::size(kRestoredURLs))
+    if (model->count() != std::size(kRestoredURLs))
       return false;
     for (int i = 0; i < model->count(); ++i) {
       if (model->GetWebContentsAt(i)->GetVisibleURL() != kRestoredURLs[i])
@@ -188,7 +187,7 @@
   // Most policy settings override this, except kPrefValueLast and
   // kPrefValueLastAndURLs which enforce a restore.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kRestoredURLs[0])));
-  for (size_t i = 1; i < base::size(kRestoredURLs); ++i) {
+  for (size_t i = 1; i < std::size(kRestoredURLs); ++i) {
     content::WindowedNotificationObserver observer(
         content::NOTIFICATION_LOAD_STOP,
         content::NotificationService::AllSources());
diff --git a/chrome/browser/policy/test/url_blocklist_policy_browsertest.cc b/chrome/browser/policy/test/url_blocklist_policy_browsertest.cc
index 1cd1228f..4861459 100644
--- a/chrome/browser/policy/test/url_blocklist_policy_browsertest.cc
+++ b/chrome/browser/policy/test/url_blocklist_policy_browsertest.cc
@@ -131,7 +131,7 @@
   FlushBlocklistPolicy();
   // All bbb.com URLs are blocked, and "aaa.com" is still unblocked.
   CheckCanOpenURL(browser(), kURLS[0]);
-  for (size_t i = 1; i < base::size(kURLS); ++i)
+  for (size_t i = 1; i < std::size(kURLS); ++i)
     CheckURLIsBlocked(browser(), kURLS[i]);
 
   // Allowlist some sites of bbb.com.
@@ -248,7 +248,7 @@
   FlushBlocklistPolicy();
   // All bbb.com URLs are blocked, and "aaa.com" is still unblocked.
   CheckCanOpenURL(incognito_browser, kURLS[0]);
-  for (size_t i = 1; i < base::size(kURLS); ++i)
+  for (size_t i = 1; i < std::size(kURLS); ++i)
     CheckURLIsBlocked(incognito_browser, kURLS[i]);
 
   // Allowlist some sites of bbb.com.
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc
index 85cf376..76f27818 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -43,7 +43,7 @@
   0.5f
 };
 
-static_assert(base::size(kConfidenceCutoff) ==
+static_assert(std::size(kConfidenceCutoff) ==
                   predictors::AutocompleteActionPredictor::LAST_PREDICT_ACTION,
               "kConfidenceCutoff count should match LAST_PREDICT_ACTION");
 
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
index c0eac3e..6f273a8 100644
--- a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
+++ b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
@@ -160,7 +160,7 @@
   }
 
   void AddAllRows() {
-    for (size_t i = 0; i < base::size(TestUrlDb()); ++i)
+    for (size_t i = 0; i < std::size(TestUrlDb()); ++i)
       AddRow(TestUrlDb()[i]);
   }
 
@@ -185,12 +185,12 @@
   void OnURLsDeletedTest(bool expired) {
     ASSERT_NO_FATAL_FAILURE(AddAllRows());
 
-    EXPECT_EQ(base::size(TestUrlDb()), db_cache()->size());
-    EXPECT_EQ(base::size(TestUrlDb()), db_id_cache()->size());
+    EXPECT_EQ(std::size(TestUrlDb()), db_cache()->size());
+    EXPECT_EQ(std::size(TestUrlDb()), db_id_cache()->size());
 
     std::vector<size_t> expected;
     history::URLRows rows;
-    for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+    for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
       bool expect_deleted = false;
 
       if (i < 2) {
@@ -225,7 +225,7 @@
     EXPECT_EQ(expected.size(), db_cache()->size());
     EXPECT_EQ(expected.size(), db_id_cache()->size());
 
-    for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+    for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
       DBCacheKey key = {TestUrlDb()[i].user_text, TestUrlDb()[i].url};
 
       bool deleted = !base::Contains(expected, i);
@@ -313,8 +313,8 @@
 TEST_F(AutocompleteActionPredictorTest, UpdateRow) {
   ASSERT_NO_FATAL_FAILURE(AddAllRows());
 
-  EXPECT_EQ(base::size(TestUrlDb()), db_cache()->size());
-  EXPECT_EQ(base::size(TestUrlDb()), db_id_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_id_cache()->size());
 
   // Get the data back out of the cache.
   const DBCacheKey key = {TestUrlDb()[0].user_text, TestUrlDb()[0].url};
@@ -349,8 +349,8 @@
 TEST_F(AutocompleteActionPredictorTest, DeleteAllRows) {
   ASSERT_NO_FATAL_FAILURE(AddAllRows());
 
-  EXPECT_EQ(base::size(TestUrlDb()), db_cache()->size());
-  EXPECT_EQ(base::size(TestUrlDb()), db_id_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_id_cache()->size());
 
   DeleteAllRows();
 
@@ -361,7 +361,7 @@
 TEST_F(AutocompleteActionPredictorTest, DeleteRowsFromCaches) {
   std::vector<AutocompleteActionPredictorTable::Row::Id> all_ids;
   history::URLRows rows;
-  for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
     std::string row_id = AddRow(TestUrlDb()[i]);
     all_ids.push_back(row_id);
 
@@ -369,17 +369,17 @@
       rows.push_back(history::URLRow(TestUrlDb()[i].url));
   }
 
-  EXPECT_EQ(base::size(TestUrlDb()), all_ids.size());
-  EXPECT_EQ(base::size(TestUrlDb()), db_cache()->size());
-  EXPECT_EQ(base::size(TestUrlDb()), db_id_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), all_ids.size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()), db_id_cache()->size());
 
   std::vector<AutocompleteActionPredictorTable::Row::Id> id_list;
   DeleteRowsFromCaches(rows, &id_list);
 
-  EXPECT_EQ(base::size(TestUrlDb()) - 2, db_cache()->size());
-  EXPECT_EQ(base::size(TestUrlDb()) - 2, db_id_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()) - 2, db_cache()->size());
+  EXPECT_EQ(std::size(TestUrlDb()) - 2, db_id_cache()->size());
 
-  for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
     DBCacheKey key = {TestUrlDb()[i].user_text, TestUrlDb()[i].url};
 
     bool deleted = (i < 2);
@@ -393,7 +393,7 @@
   std::vector<AutocompleteActionPredictorTable::Row::Id> expected;
   std::vector<AutocompleteActionPredictorTable::Row::Id> all_ids;
 
-  for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
     std::string row_id = AddRow(TestUrlDb()[i]);
     all_ids.push_back(row_id);
 
@@ -430,7 +430,7 @@
   std::vector<AutocompleteActionPredictorTable::Row::Id> id_list;
   std::vector<AutocompleteActionPredictorTable::Row::Id> expected;
 
-  for (size_t i = 0; i < base::size(TestUrlConfidenceDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlConfidenceDb()); ++i) {
     DeleteLowestConfidenceRowsFromCaches(1, &id_list);
     expected.push_back(test_url_ids[i]);
     EXPECT_THAT(id_list, ::testing::UnorderedElementsAreArray(expected));
@@ -452,7 +452,7 @@
   std::vector<AutocompleteActionPredictorTable::Row::Id> expected;
 
   const size_t count_to_remove = 4;
-  CHECK_LT(count_to_remove, base::size(TestUrlConfidenceDb()));
+  CHECK_LT(count_to_remove, std::size(TestUrlConfidenceDb()));
 
   for (size_t i = 0; i < count_to_remove; ++i)
     expected.push_back(test_url_ids[i]);
@@ -482,7 +482,7 @@
   AutocompleteMatch match;
   match.type = AutocompleteMatchType::HISTORY_URL;
 
-  for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
     match.destination_url = GURL(TestUrlDb()[i].url);
     EXPECT_EQ(TestUrlDb()[i].expected_action,
               predictor()->RecommendAction(TestUrlDb()[i].user_text, match))
@@ -496,7 +496,7 @@
   AutocompleteMatch match;
   match.type = AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED;
 
-  for (size_t i = 0; i < base::size(TestUrlDb()); ++i) {
+  for (size_t i = 0; i < std::size(TestUrlDb()); ++i) {
     match.destination_url = GURL(TestUrlDb()[i].url);
     AutocompleteActionPredictor::Action expected_action =
         (TestUrlDb()[i].expected_action ==
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc
index 17c1cc13..c23d5cc 100644
--- a/chrome/browser/predictors/loading_predictor_browsertest.cc
+++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -872,7 +872,7 @@
         host_url.host(), network_isolation_key));
   }
   // 2 connections to the main frame host + 1 connection per host for others.
-  const size_t expected_connections = base::size(kHtmlSubresourcesHosts) + 1;
+  const size_t expected_connections = std::size(kHtmlSubresourcesHosts) + 1;
   connection_tracker()->WaitForAcceptedConnections(expected_connections);
   EXPECT_EQ(expected_connections,
             connection_tracker()->GetAcceptedSocketCount());
@@ -1453,7 +1453,7 @@
         host_url, network_isolation_key));
   }
   // 2 connections to the main frame host + 1 connection per host for others.
-  const size_t expected_connections = base::size(kHtmlSubresourcesHosts) + 1;
+  const size_t expected_connections = std::size(kHtmlSubresourcesHosts) + 1;
   connection_tracker()->WaitForAcceptedConnections(expected_connections);
   EXPECT_EQ(expected_connections,
             connection_tracker()->GetAcceptedSocketCount());
@@ -1594,7 +1594,7 @@
   size_t expected_connections;
   if (IsLocalPredictionEnabled()) {
     // 2 connections to the main frame host  + 1 connection per host for others.
-    expected_connections = base::size(kHtmlSubresourcesHosts) + 1;
+    expected_connections = std::size(kHtmlSubresourcesHosts) + 1;
   } else {
     // There should always be 2 connections to the main frame host.
     expected_connections = 2;
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
index 1bd41fd3..4db97f9 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.cc
@@ -59,3 +59,10 @@
       network::mojom::FulfillTrustTokenIssuanceAnswer::Status::kNotFound;
   std::move(callback).Run(std::move(response));
 }
+
+void PrefetchProxyNetworkContextClient::OnCanSendSCTAuditingReport(
+    OnCanSendSCTAuditingReportCallback callback) {
+  std::move(callback).Run(false);
+}
+
+void PrefetchProxyNetworkContextClient::OnNewSCTAuditingReportSent() {}
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
index d1c8e5e..c6807e1 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_network_context_client.h
@@ -44,6 +44,9 @@
   void OnTrustTokenIssuanceDivertedToSystem(
       network::mojom::FulfillTrustTokenIssuanceRequestPtr request,
       OnTrustTokenIssuanceDivertedToSystemCallback callback) override;
+  void OnCanSendSCTAuditingReport(
+      OnCanSendSCTAuditingReportCallback callback) override;
+  void OnNewSCTAuditingReportSent() override;
 };
 
 #endif  // CHROME_BROWSER_PREFETCH_PREFETCH_PROXY_PREFETCH_PROXY_NETWORK_CONTEXT_CLIENT_H_
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper_unittest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper_unittest.cc
index 5f8e2b2a..254ffb93 100644
--- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper_unittest.cc
+++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper_unittest.cc
@@ -793,7 +793,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -833,7 +833,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_NOT_FOUND, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -991,7 +991,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -1042,7 +1042,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -1081,7 +1081,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -1162,7 +1162,7 @@
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 2);
 
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 2);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 2);
 
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 2);
@@ -1227,7 +1227,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
   histogram_tester.ExpectUniqueSample(
@@ -1644,7 +1644,7 @@
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 2);
 
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 2);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 2);
 
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 2);
@@ -1705,7 +1705,7 @@
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 2);
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 2);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 2);
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 2);
   histogram_tester.ExpectUniqueSample(
@@ -1770,7 +1770,7 @@
       "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1);
 
   histogram_tester.ExpectUniqueSample(
-      "PrefetchProxy.Prefetch.Mainframe.BodyLength", base::size(kHTMLBody), 1);
+      "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1);
 
   histogram_tester.ExpectUniqueSample(
       "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1);
diff --git a/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc b/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc
index d730824..58a2294 100644
--- a/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc
+++ b/chrome/browser/prefetch/search_prefetch/field_trial_settings.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/command_line.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/system/sys_info.h"
 
diff --git a/chrome/browser/prefetch/search_prefetch/field_trial_settings.h b/chrome/browser/prefetch/search_prefetch/field_trial_settings.h
index 8fae18fe..b31722a2 100644
--- a/chrome/browser/prefetch/search_prefetch/field_trial_settings.h
+++ b/chrome/browser/prefetch/search_prefetch/field_trial_settings.h
@@ -10,8 +10,6 @@
 
 extern const base::Feature kSearchPrefetchServicePrefetching;
 
-extern const char kSearchPrefetchServiceCommandLineFlag[];
-
 // Whether the search prefetch service actually initiates prefetches.
 bool SearchPrefetchServicePrefetchingIsEnabled();
 
diff --git a/chrome/browser/prefs/chrome_command_line_pref_store.cc b/chrome/browser/prefs/chrome_command_line_pref_store.cc
index 223c767..d66558a2 100644
--- a/chrome/browser/prefs/chrome_command_line_pref_store.cc
+++ b/chrome/browser/prefs/chrome_command_line_pref_store.cc
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "ash/constants/ash_switches.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
@@ -127,10 +126,10 @@
 
 void ChromeCommandLinePrefStore::ApplySimpleSwitches() {
   // Look for each switch we know about and set its preference accordingly.
-  ApplyStringSwitches(string_switch_map_, base::size(string_switch_map_));
-  ApplyPathSwitches(path_switch_map_, base::size(path_switch_map_));
-  ApplyIntegerSwitches(integer_switch_map_, base::size(integer_switch_map_));
-  ApplyBooleanSwitches(boolean_switch_map_, base::size(boolean_switch_map_));
+  ApplyStringSwitches(string_switch_map_, std::size(string_switch_map_));
+  ApplyPathSwitches(path_switch_map_, std::size(path_switch_map_));
+  ApplyIntegerSwitches(integer_switch_map_, std::size(integer_switch_map_));
+  ApplyBooleanSwitches(boolean_switch_map_, std::size(boolean_switch_map_));
 }
 
 void ChromeCommandLinePrefStore::ApplyProxyMode() {
diff --git a/chrome/browser/prefs/chrome_command_line_pref_store_proxy_unittest.cc b/chrome/browser/prefs/chrome_command_line_pref_store_proxy_unittest.cc
index 6af9cdb..eb6c1e4 100644
--- a/chrome/browser/prefs/chrome_command_line_pref_store_proxy_unittest.cc
+++ b/chrome/browser/prefs/chrome_command_line_pref_store_proxy_unittest.cc
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
-
 #include <gtest/gtest.h>
 #include <stddef.h>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
+#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -162,7 +160,7 @@
   net::ProxyConfigWithAnnotation* proxy_config() { return &proxy_config_; }
 
   void SetUp() override {
-    for (size_t i = 0; i < base::size(GetParam().switches); i++) {
+    for (size_t i = 0; i < std::size(GetParam().switches); i++) {
       const char* name = GetParam().switches[i].name;
       const char* value = GetParam().switches[i].value;
       if (name && value)
diff --git a/chrome/browser/prefs/chrome_command_line_pref_store_unittest.cc b/chrome/browser/prefs/chrome_command_line_pref_store_unittest.cc
index 2931a38a..9d16659 100644
--- a/chrome/browser/prefs/chrome_command_line_pref_store_unittest.cc
+++ b/chrome/browser/prefs/chrome_command_line_pref_store_unittest.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
+
 #include <stddef.h>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
-#include "chrome/browser/prefs/chrome_command_line_pref_store.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/language/core/browser/pref_names.h"
@@ -194,7 +194,7 @@
     "0x0005",
   };
   store1->VerifySSLCipherSuites(expected_ciphers1,
-                                base::size(expected_ciphers1));
+                                std::size(expected_ciphers1));
 
   base::CommandLine cl2(base::CommandLine::NO_PROGRAM);
   cl2.AppendSwitchASCII(switches::kCipherSuiteBlacklist,
@@ -207,7 +207,7 @@
     "0x0005",
   };
   store2->VerifySSLCipherSuites(expected_ciphers2,
-                                base::size(expected_ciphers2));
+                                std::size(expected_ciphers2));
 
   base::CommandLine cl3(base::CommandLine::NO_PROGRAM);
   cl3.AppendSwitchASCII(switches::kCipherSuiteBlacklist,
@@ -218,7 +218,7 @@
     "0x0004;MOAR;0x0005"
   };
   store3->VerifySSLCipherSuites(expected_ciphers3,
-                                base::size(expected_ciphers3));
+                                std::size(expected_ciphers3));
 }
 
 TEST(ChromeCommandLinePrefStoreTest, ExplicitlyAllowedPorts) {
@@ -236,7 +236,7 @@
   ASSERT_TRUE(store->GetValue(prefs::kExplicitlyAllowedNetworkPorts, &value));
   ASSERT_TRUE(value);
   ASSERT_TRUE(value->is_list());
-  ASSERT_EQ(base::size(kExpectedPorts), value->GetListDeprecated().size());
+  ASSERT_EQ(std::size(kExpectedPorts), value->GetListDeprecated().size());
 
   int i = 0;
   for (const base::Value& port : value->GetListDeprecated()) {
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index 055c9d3..b6ace65 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram_macros.h"
@@ -196,7 +195,7 @@
 
 // One more than the last tracked preferences ID above.
 const size_t kTrackedPrefsReportingIDsCount =
-    kTrackedPrefs[base::size(kTrackedPrefs) - 1].reporting_id + 1;
+    kTrackedPrefs[std::size(kTrackedPrefs) - 1].reporting_id + 1;
 
 // Each group enforces a superset of the protection provided by the previous
 // one.
@@ -244,7 +243,7 @@
       GetSettingsEnforcementGroup();
 
   std::vector<prefs::mojom::TrackedPreferenceMetadataPtr> result;
-  for (size_t i = 0; i < base::size(kTrackedPrefs); ++i) {
+  for (size_t i = 0; i < std::size(kTrackedPrefs); ++i) {
     prefs::mojom::TrackedPreferenceMetadataPtr data =
         prefs::ConstructTrackedMetadata(kTrackedPrefs[i]);
 
diff --git a/chrome/browser/prefs/pref_service_incognito_allowlist.cc b/chrome/browser/prefs/pref_service_incognito_allowlist.cc
index c65560a2..61f5c54 100644
--- a/chrome/browser/prefs/pref_service_incognito_allowlist.cc
+++ b/chrome/browser/prefs/pref_service_incognito_allowlist.cc
@@ -6,7 +6,6 @@
 
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/common/pref_names.h"
@@ -168,7 +167,7 @@
 std::vector<const char*> GetIncognitoPersistentPrefsAllowlist() {
   std::vector<const char*> allowlist;
   allowlist.insert(allowlist.end(), kPersistentPrefNames,
-                   kPersistentPrefNames + base::size(kPersistentPrefNames));
+                   kPersistentPrefNames + std::size(kPersistentPrefNames));
   return allowlist;
 }
 
diff --git a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
index 683bf1e4..22ebcfe 100644
--- a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
+++ b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
@@ -150,7 +149,7 @@
 
     ProfilePrefStoreManager::RegisterProfilePrefs(profile_pref_registry_.get());
     for (const prefs::TrackedPreferenceMetadata* it = kConfiguration;
-         it != kConfiguration + base::size(kConfiguration); ++it) {
+         it != kConfiguration + std::size(kConfiguration); ++it) {
       if (it->strategy == PrefTrackingStrategy::ATOMIC) {
         profile_pref_registry_->RegisterStringPref(it->name, std::string());
       } else {
diff --git a/chrome/browser/printing/pdf_nup_converter_client_browsertest.cc b/chrome/browser/printing/pdf_nup_converter_client_browsertest.cc
index 3f9f5b26..fbc543b 100644
--- a/chrome/browser/printing/pdf_nup_converter_client_browsertest.cc
+++ b/chrome/browser/printing/pdf_nup_converter_client_browsertest.cc
@@ -67,11 +67,11 @@
 base::MappedReadOnlyRegion GetBadDataRegion() {
   static const char kBadData[] = "BADDATA";
   base::MappedReadOnlyRegion pdf_region =
-      base::ReadOnlySharedMemoryRegion::Create(base::size(kBadData));
+      base::ReadOnlySharedMemoryRegion::Create(std::size(kBadData));
   if (!pdf_region.IsValid())
     return pdf_region;
 
-  memcpy(pdf_region.mapping.memory(), kBadData, base::size(kBadData));
+  memcpy(pdf_region.mapping.memory(), kBadData, std::size(kBadData));
   return pdf_region;
 }
 
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index b2076da..9b62e3d 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -46,6 +46,7 @@
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_features.h"
@@ -208,8 +209,8 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   std::unique_ptr<PrinterQuery> printer_query = queue->PopPrinterQuery(cookie);
   if (!printer_query) {
-    printer_query = queue->CreatePrinterQuery(
-        content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
+    printer_query =
+        queue->CreatePrinterQuery(content::GlobalRenderFrameHostId());
   }
   auto* printer_query_ptr = printer_query.get();
   printer_query_ptr->SetSettings(
@@ -1243,9 +1244,7 @@
   PrintCompositeClient::RequestedSubFrame* subframe_in_queue =
       client->requested_subframes_.begin()->get();
   ASSERT_EQ(kDefaultDocumentCookie, subframe_in_queue->document_cookie_);
-  ASSERT_EQ(test_frame->GetProcess()->GetID(),
-            subframe_in_queue->render_process_id_);
-  ASSERT_EQ(test_frame->GetRoutingID(), subframe_in_queue->render_frame_id_);
+  ASSERT_EQ(test_frame->GetGlobalId(), subframe_in_queue->rfh_id_);
 
   // Creates mojom::PrintCompositor.
   client->DoCompositeDocumentToPdf(
@@ -1903,11 +1902,9 @@
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
 class TestPrintJobWorker : public PrintJobWorkerOop {
  public:
-  TestPrintJobWorker(int render_process_id,
-                     int render_frame_id,
+  TestPrintJobWorker(content::GlobalRenderFrameHostId rfh_id,
                      TestPrintCallbacks* callbacks)
-      : PrintJobWorkerOop(render_process_id, render_frame_id),
-        callbacks_(callbacks) {}
+      : PrintJobWorkerOop(rfh_id), callbacks_(callbacks) {}
   TestPrintJobWorker(const TestPrintJobWorker&) = delete;
   TestPrintJobWorker& operator=(const TestPrintJobWorker&) = delete;
   ~TestPrintJobWorker() override = default;
@@ -2175,10 +2172,9 @@
   };
 
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
-  std::unique_ptr<PrintJobWorker> CreatePrintJobWorker(int render_process_id,
-                                                       int render_frame_id) {
-    return std::make_unique<TestPrintJobWorker>(
-        render_process_id, render_frame_id, &test_print_callbacks_);
+  std::unique_ptr<PrintJobWorker> CreatePrintJobWorker(
+      content::GlobalRenderFrameHostId rfh_id) {
+    return std::make_unique<TestPrintJobWorker>(rfh_id, &test_print_callbacks_);
   }
 #endif  // BUILDFLAG(ENABLE_OOP_PRINTING)
 
diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc
index 97b1fea..b0d6be0 100644
--- a/chrome/browser/printing/print_job_manager.cc
+++ b/chrome/browser/printing/print_job_manager.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/printing/print_job.h"
 #include "chrome/browser/printing/printer_query.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/notification_service.h"
 #include "printing/printed_document.h"
 
@@ -21,8 +22,7 @@
 
 namespace printing {
 
-PrintQueriesQueue::PrintQueriesQueue() {
-}
+PrintQueriesQueue::PrintQueriesQueue() = default;
 
 PrintQueriesQueue::~PrintQueriesQueue() {
   base::AutoLock lock(lock_);
@@ -53,9 +53,8 @@
 }
 
 std::unique_ptr<PrinterQuery> PrintQueriesQueue::CreatePrinterQuery(
-    int render_process_id,
-    int render_frame_id) {
-  return std::make_unique<PrinterQuery>(render_process_id, render_frame_id);
+    content::GlobalRenderFrameHostId rfh_id) {
+  return std::make_unique<PrinterQuery>(rfh_id);
 }
 
 void PrintQueriesQueue::Shutdown() {
diff --git a/chrome/browser/printing/print_job_manager.h b/chrome/browser/printing/print_job_manager.h
index 3fa6ef8..2d4c3017 100644
--- a/chrome/browser/printing/print_job_manager.h
+++ b/chrome/browser/printing/print_job_manager.h
@@ -14,6 +14,10 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 
+namespace content {
+struct GlobalRenderFrameHostId;
+}
+
 namespace printing {
 
 class JobEventDetails;
@@ -38,8 +42,7 @@
 
   // Creates new query. Virtual so that tests can override it.
   virtual std::unique_ptr<PrinterQuery> CreatePrinterQuery(
-      int render_process_id,
-      int render_frame_id);
+      content::GlobalRenderFrameHostId rfh_id);
 
   void Shutdown();
 
diff --git a/chrome/browser/printing/print_job_unittest.cc b/chrome/browser/printing/print_job_unittest.cc
index 70ff11d0..cd7cff0 100644
--- a/chrome/browser/printing/print_job_unittest.cc
+++ b/chrome/browser/printing/print_job_unittest.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/printing/print_job_worker.h"
 #include "chrome/browser/printing/printer_query.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/notification_service.h"
@@ -30,17 +31,13 @@
 
 class TestPrintJobWorker : public PrintJobWorker {
  public:
-  TestPrintJobWorker()
-      : PrintJobWorker(content::ChildProcessHost::kInvalidUniqueID,
-                       content::ChildProcessHost::kInvalidUniqueID) {}
+  TestPrintJobWorker() : PrintJobWorker(content::GlobalRenderFrameHostId()) {}
   friend class TestQuery;
 };
 
 class TestQuery : public PrinterQuery {
  public:
-  TestQuery()
-      : PrinterQuery(content::ChildProcessHost::kInvalidUniqueID,
-                     content::ChildProcessHost::kInvalidUniqueID) {}
+  TestQuery() : PrinterQuery(content::GlobalRenderFrameHostId()) {}
 
   void GetSettingsDone(base::OnceClosure callback,
                        std::unique_ptr<PrintSettings> new_settings,
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 7dbb9ae..2730599 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -25,6 +25,7 @@
 #include "components/device_event_log/device_event_log.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "printing/backend/print_backend.h"
@@ -62,7 +63,7 @@
 
 class PrintingContextDelegate : public PrintingContext::Delegate {
  public:
-  PrintingContextDelegate(int render_process_id, int render_frame_id);
+  explicit PrintingContextDelegate(content::GlobalRenderFrameHostId rfh_id);
 
   PrintingContextDelegate(const PrintingContextDelegate&) = delete;
   PrintingContextDelegate& operator=(const PrintingContextDelegate&) = delete;
@@ -75,21 +76,17 @@
   // Not exposed to PrintingContext::Delegate because of dependency issues.
   content::WebContents* GetWebContents();
 
-  int render_process_id() const { return render_process_id_; }
-  int render_frame_id() const { return render_frame_id_; }
+  content::GlobalRenderFrameHostId rfh_id() const { return rfh_id_; }
 
  private:
-  const int render_process_id_;
-  const int render_frame_id_;
+  const content::GlobalRenderFrameHostId rfh_id_;
 };
 
-PrintingContextDelegate::PrintingContextDelegate(int render_process_id,
-                                                 int render_frame_id)
-    : render_process_id_(render_process_id),
-      render_frame_id_(render_frame_id) {}
+PrintingContextDelegate::PrintingContextDelegate(
+    content::GlobalRenderFrameHostId rfh_id)
+    : rfh_id_(rfh_id) {}
 
-PrintingContextDelegate::~PrintingContextDelegate() {
-}
+PrintingContextDelegate::~PrintingContextDelegate() = default;
 
 gfx::NativeView PrintingContextDelegate::GetParentView() {
   content::WebContents* wc = GetWebContents();
@@ -98,8 +95,7 @@
 
 content::WebContents* PrintingContextDelegate::GetWebContents() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  auto* rfh =
-      content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
+  auto* rfh = content::RenderFrameHost::FromID(rfh_id_);
   return rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
 }
 
@@ -127,10 +123,9 @@
 
 }  // namespace
 
-PrintJobWorker::PrintJobWorker(int render_process_id, int render_frame_id)
+PrintJobWorker::PrintJobWorker(content::GlobalRenderFrameHostId rfh_id)
     : printing_context_delegate_(
-          std::make_unique<PrintingContextDelegate>(render_process_id,
-                                                    render_frame_id)),
+          std::make_unique<PrintingContextDelegate>(rfh_id)),
       printing_context_(
           PrintingContext::Create(printing_context_delegate_.get(),
                                   ShouldPrintingContextSkipSystemCalls())),
@@ -294,8 +289,8 @@
       PrintingContextAndroid::SetPendingPrint(
           web_contents->GetTopLevelNativeWindow(),
           GetPrintableForTab(tab->GetJavaObject()),
-          printing_context_delegate->render_process_id(),
-          printing_context_delegate->render_frame_id());
+          printing_context_delegate->rfh_id().child_id,
+          printing_context_delegate->rfh_id().frame_routing_id);
     }
   }
 #endif
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index b6616fa..465afca 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -20,6 +20,7 @@
 
 namespace content {
 class WebContents;
+struct GlobalRenderFrameHostId;
 }
 
 namespace printing {
@@ -38,7 +39,7 @@
       base::OnceCallback<void(std::unique_ptr<PrintSettings>,
                               mojom::ResultCode)>;
 
-  PrintJobWorker(int render_process_id, int render_frame_id);
+  explicit PrintJobWorker(content::GlobalRenderFrameHostId rfh_id);
 
   PrintJobWorker(const PrintJobWorker&) = delete;
   PrintJobWorker& operator=(const PrintJobWorker&) = delete;
diff --git a/chrome/browser/printing/print_job_worker_oop.cc b/chrome/browser/printing/print_job_worker_oop.cc
index a816711..7a5660cb 100644
--- a/chrome/browser/printing/print_job_worker_oop.cc
+++ b/chrome/browser/printing/print_job_worker_oop.cc
@@ -15,6 +15,7 @@
 #include "components/device_event_log/device_event_log.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "printing/metafile.h"
 #include "printing/printed_document.h"
 #include "printing/printing_features.h"
@@ -43,8 +44,8 @@
 
 }  // namespace
 
-PrintJobWorkerOop::PrintJobWorkerOop(int render_process_id, int render_frame_id)
-    : PrintJobWorker(render_process_id, render_frame_id) {}
+PrintJobWorkerOop::PrintJobWorkerOop(content::GlobalRenderFrameHostId rfh_id)
+    : PrintJobWorker(rfh_id) {}
 
 PrintJobWorkerOop::~PrintJobWorkerOop() {
   DCHECK(!service_manager_client_id_.has_value());
diff --git a/chrome/browser/printing/print_job_worker_oop.h b/chrome/browser/printing/print_job_worker_oop.h
index ff93a69..20d822f 100644
--- a/chrome/browser/printing/print_job_worker_oop.h
+++ b/chrome/browser/printing/print_job_worker_oop.h
@@ -31,7 +31,7 @@
 // thread.  PrintJob always outlives its worker instance.
 class PrintJobWorkerOop : public PrintJobWorker {
  public:
-  PrintJobWorkerOop(int render_process_id, int render_frame_id);
+  explicit PrintJobWorkerOop(content::GlobalRenderFrameHostId rfh_id);
   PrintJobWorkerOop(const PrintJobWorkerOop&) = delete;
   PrintJobWorkerOop& operator=(const PrintJobWorkerOop&) = delete;
   ~PrintJobWorkerOop() override;
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 7a62661..48ee06a 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/printing/print_preview_dialog_controller.h"
 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -222,13 +223,11 @@
 #endif
 }
 
-void PrintViewManager::OnPrintPreviewRequestRejected(int render_process_id,
-                                                     int render_frame_id) {
-  auto* rfh =
-      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
-  if (!rfh) {
+void PrintViewManager::OnPrintPreviewRequestRejected(
+    content::GlobalRenderFrameHostId rfh_id) {
+  if (!content::RenderFrameHost::FromID(rfh_id))
     return;
-  }
+
   PrintPreviewDone();
   PrintPreviewRejectedForTesting();
 }
@@ -343,21 +342,18 @@
   if (GetCurrentTargetFrame() != print_preview_rfh_)
     return;
 
-  int render_process_id = print_preview_rfh_->GetProcess()->GetID();
-  int render_frame_id = print_preview_rfh_->GetRoutingID();
-
   RejectPrintPreviewRequestIfRestricted(
       base::BindOnce(&PrintViewManager::OnScriptedPrintPreviewCallback,
                      weak_factory_.GetWeakPtr(), source_is_modifiable,
-                     render_process_id, render_frame_id));
+                     print_preview_rfh_->GetGlobalId()));
 }
 
-void PrintViewManager::OnScriptedPrintPreviewCallback(bool source_is_modifiable,
-                                                      int render_process_id,
-                                                      int render_frame_id,
-                                                      bool should_proceed) {
+void PrintViewManager::OnScriptedPrintPreviewCallback(
+    bool source_is_modifiable,
+    content::GlobalRenderFrameHostId rfh_id,
+    bool should_proceed) {
   if (!should_proceed) {
-    OnPrintPreviewRequestRejected(render_process_id, render_frame_id);
+    OnPrintPreviewRequestRejected(rfh_id);
     return;
   }
 
@@ -366,11 +362,9 @@
 
   DCHECK(print_preview_rfh_);
 
-  auto* rfh =
-      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
-  if (!rfh || rfh != print_preview_rfh_) {
+  auto* rfh = content::RenderFrameHost::FromID(rfh_id);
+  if (!rfh || rfh != print_preview_rfh_)
     return;
-  }
 
   PrintPreviewDialogController* dialog_controller =
       PrintPreviewDialogController::GetInstance();
@@ -394,35 +388,30 @@
 
 void PrintViewManager::RequestPrintPreview(
     mojom::RequestPrintPreviewParamsPtr params) {
-  content::RenderFrameHost* render_frame_host = GetCurrentTargetFrame();
-  content::RenderProcessHost* render_process_host =
-      render_frame_host->GetProcess();
-
-  RejectPrintPreviewRequestIfRestricted(base::BindOnce(
-      &PrintViewManager::OnRequestPrintPreviewCallback,
-      weak_factory_.GetWeakPtr(), std::move(params),
-      render_process_host->GetID(), render_frame_host->GetRoutingID()));
+  RejectPrintPreviewRequestIfRestricted(
+      base::BindOnce(&PrintViewManager::OnRequestPrintPreviewCallback,
+                     weak_factory_.GetWeakPtr(), std::move(params),
+                     GetCurrentTargetFrame()->GetGlobalId()));
 }
 
 void PrintViewManager::OnRequestPrintPreviewCallback(
     mojom::RequestPrintPreviewParamsPtr params,
-    int render_process_id,
-    int render_frame_id,
+    content::GlobalRenderFrameHostId rfh_id,
     bool should_proceed) {
   if (!should_proceed) {
-    OnPrintPreviewRequestRejected(render_process_id, render_frame_id);
+    OnPrintPreviewRequestRejected(rfh_id);
     return;
   }
+
   // Double-check that the RenderFrameHost is still alive and has a live
   // RenderFrame, since the DLP check is potentially asynchronous.
-  auto* render_frame_host =
-      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
-  if (!render_frame_host || !render_frame_host->IsRenderFrameLive()) {
+  auto* render_frame_host = content::RenderFrameHost::FromID(rfh_id);
+  if (!render_frame_host || !render_frame_host->IsRenderFrameLive())
     return;
-  }
-  if (params->webnode_only) {
+
+  if (params->webnode_only)
     PrintPreviewForWebNode(render_frame_host);
-  }
+
   PrintPreviewDialogController::PrintPreview(web_contents());
   PrintPreviewUI::SetInitialParams(GetPrintPreviewDialog(web_contents()),
                                    *params);
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index 8ce43d81..0a382c9e 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -15,6 +15,7 @@
 namespace content {
 class RenderFrameHost;
 class RenderProcessHost;
+struct GlobalRenderFrameHostId;
 }
 
 namespace printing {
@@ -111,16 +112,14 @@
   // RejectPrintPreviewRequestIfRestricted(). Based on value of
   // `should_proceed`, continues to show the print preview or cancels it.
   void OnScriptedPrintPreviewCallback(bool source_is_modifiable,
-                                      int render_process_id,
-                                      int render_frame_id,
+                                      content::GlobalRenderFrameHostId rfh_id,
                                       bool should_proceed);
 
   // Helper method for RequestPrintPreview(), called from
   // RejectPrintPreviewRequestIfRestricted(). Based on value of
   // `should_proceed`, continues to show the print preview or cancels it.
   void OnRequestPrintPreviewCallback(mojom::RequestPrintPreviewParamsPtr params,
-                                     int render_process_id,
-                                     int render_frame_id,
+                                     content::GlobalRenderFrameHostId rfh_id,
                                      bool should_proceed);
 
   void MaybeUnblockScriptedPreviewRPH();
@@ -135,8 +134,7 @@
   // Helper method for RejectPrintPreviewRequestIfRestricted(). Handles any
   // tasks that need to be done when the request is rejected due to
   // restrictions.
-  void OnPrintPreviewRequestRejected(int render_process_id,
-                                     int render_frame_id);
+  void OnPrintPreviewRequestRejected(content::GlobalRenderFrameHostId rfh_id);
 
   // Virtual method to be overridden in tests, in order to be notified whether
   // the print preview is shown or not due to policies or user actions.
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index ef7221ca..0e932ac 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -41,6 +41,7 @@
 #include "components/services/print_compositor/public/cpp/print_service_mojo_types.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
@@ -103,8 +104,7 @@
 }
 
 void CreateQueryWithSettings(base::Value job_settings,
-                             int render_process_id,
-                             int render_frame_id,
+                             content::GlobalRenderFrameHostId rfh_id,
                              scoped_refptr<PrintQueriesQueue> queue,
                              PrintSettingsCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -112,7 +112,7 @@
   PrintSettingsCallback callback_wrapper =
       base::BindOnce(OnPrintSettingsDoneWrapper, std::move(callback));
   std::unique_ptr<printing::PrinterQuery> printer_query =
-      queue->CreatePrinterQuery(render_process_id, render_frame_id);
+      queue->CreatePrinterQuery(rfh_id);
   auto* printer_query_ptr = printer_query.get();
   printer_query_ptr->SetSettings(
       std::move(job_settings),
@@ -149,13 +149,12 @@
 void GetDefaultPrintSettingsOnIO(
     mojom::PrintManagerHost::GetDefaultPrintSettingsCallback callback,
     scoped_refptr<PrintQueriesQueue> queue,
-    int process_id,
-    int routing_id) {
+    content::GlobalRenderFrameHostId rfh_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   std::unique_ptr<PrinterQuery> printer_query = queue->PopPrinterQuery(0);
   if (!printer_query)
-    printer_query = queue->CreatePrinterQuery(process_id, routing_id);
+    printer_query = queue->CreatePrinterQuery(rfh_id);
 
   // Loads default settings. This is asynchronous, only the mojo message sender
   // will hang until the settings are retrieved.
@@ -224,8 +223,8 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   std::unique_ptr<PrinterQuery> printer_query = queue->PopPrinterQuery(cookie);
   if (!printer_query) {
-    printer_query = queue->CreatePrinterQuery(
-        content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
+    printer_query =
+        queue->CreatePrinterQuery(content::GlobalRenderFrameHostId());
   }
   auto* printer_query_ptr = printer_query.get();
   printer_query_ptr->SetSettings(
@@ -264,8 +263,7 @@
 void ScriptedPrintOnIO(mojom::ScriptedPrintParamsPtr params,
                        mojom::PrintManagerHost::ScriptedPrintCallback callback,
                        scoped_refptr<PrintQueriesQueue> queue,
-                       int process_id,
-                       int routing_id) {
+                       content::GlobalRenderFrameHostId rfh_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
   ModuleDatabase::GetInstance()->DisableThirdPartyBlocking();
@@ -273,9 +271,9 @@
 
   std::unique_ptr<PrinterQuery> printer_query =
       queue->PopPrinterQuery(params->cookie);
-  if (!printer_query) {
-    printer_query = queue->CreatePrinterQuery(process_id, routing_id);
-  }
+  if (!printer_query)
+    printer_query = queue->CreatePrinterQuery(rfh_id);
+
   auto* printer_query_ptr = printer_query.get();
   printer_query_ptr->GetSettings(
       PrinterQuery::GetSettingsAskParam::ASK_USER, params->expected_pages_count,
@@ -350,8 +348,7 @@
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(CreateQueryWithSettings, std::move(job_settings),
-                     rfh->GetProcess()->GetID(), rfh->GetRoutingID(), queue_,
-                     std::move(settings_callback)));
+                     rfh->GetGlobalId(), queue_, std::move(settings_callback)));
 }
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 
@@ -615,8 +612,7 @@
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE,
       base::BindOnce(&GetDefaultPrintSettingsOnIO, std::move(callback_wrapper),
-                     queue_, render_frame_host->GetProcess()->GetID(),
-                     render_frame_host->GetRoutingID()));
+                     queue_, render_frame_host->GetGlobalId()));
 }
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -674,15 +670,13 @@
     std::move(callback).Run(CreateEmptyPrintPagesParamsPtr());
     return;
   }
-  int process_id = render_process_host->GetID();
-  int routing_id = render_frame_host->GetRoutingID();
   auto callback_wrapper = base::BindOnce(
       &PrintViewManagerBase::ScriptedPrintReply, weak_ptr_factory_.GetWeakPtr(),
-      std::move(callback), process_id);
+      std::move(callback), render_process_host->GetID());
   content::GetIOThreadTaskRunner({})->PostTask(
       FROM_HERE, base::BindOnce(&ScriptedPrintOnIO, std::move(params),
-                                std::move(callback_wrapper), queue_, process_id,
-                                routing_id));
+                                std::move(callback_wrapper), queue_,
+                                render_frame_host->GetGlobalId()));
 }
 
 void PrintViewManagerBase::PrintingFailed(int32_t cookie) {
diff --git a/chrome/browser/printing/print_view_manager_basic_unittest.cc b/chrome/browser/printing/print_view_manager_basic_unittest.cc
index 7c90c3a..7869f34 100644
--- a/chrome/browser/printing/print_view_manager_basic_unittest.cc
+++ b/chrome/browser/printing/print_view_manager_basic_unittest.cc
@@ -53,8 +53,7 @@
 
   // Setup enough of a PrinterQuery to make GetPrintedPagesCount work
   auto queue = g_browser_process->print_job_manager()->queue();
-  auto query = queue->CreatePrinterQuery(main_rfh()->GetProcess()->GetID(),
-                                         main_rfh()->GetRoutingID());
+  auto query = queue->CreatePrinterQuery(main_rfh()->GetGlobalId());
   base::RunLoop runloop;
   query->SetSettings(GetPrintTicket(mojom::PrinterType::kLocal),
                      runloop.QuitClosure());
diff --git a/chrome/browser/printing/print_view_manager_unittest.cc b/chrome/browser/printing/print_view_manager_unittest.cc
index 3ac2687..b73da667 100644
--- a/chrome/browser/printing/print_view_manager_unittest.cc
+++ b/chrome/browser/printing/print_view_manager_unittest.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/printing/common/print.mojom.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_renderer_host.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
@@ -53,8 +54,7 @@
   // settings indicated by `printable_offset_x_`, `printable_offset_y_`, and
   // `print_driver_type_`.
   std::unique_ptr<PrinterQuery> CreatePrinterQuery(
-      int render_process_id,
-      int render_frame_id) override;
+      content::GlobalRenderFrameHostId rfh_id) override;
 
   // Sets the printer's printable area offsets to `offset_x` and `offset_y`,
   // which should be in pixels. Used to fill in printer settings that would
@@ -81,7 +81,7 @@
  public:
   // Can only be called on the IO thread, since this inherits from
   // `PrinterQuery`.
-  TestPrinterQuery(int render_process_id, int render_frame_id);
+  explicit TestPrinterQuery(content::GlobalRenderFrameHostId rfh_id);
   TestPrinterQuery(const TestPrinterQuery&) = delete;
   TestPrinterQuery& operator=(const TestPrinterQuery&) = delete;
   ~TestPrinterQuery() override;
@@ -113,10 +113,8 @@
 };
 
 std::unique_ptr<PrinterQuery> TestPrintQueriesQueue::CreatePrinterQuery(
-    int render_process_id,
-    int render_frame_id) {
-  auto test_query =
-      std::make_unique<TestPrinterQuery>(render_process_id, render_frame_id);
+    content::GlobalRenderFrameHostId rfh_id) {
+  auto test_query = std::make_unique<TestPrinterQuery>(rfh_id);
 #if BUILDFLAG(IS_WIN)
   test_query->SetPrinterLanguageType(printer_language_type_);
 #endif
@@ -137,8 +135,8 @@
 }
 #endif
 
-TestPrinterQuery::TestPrinterQuery(int render_process_id, int render_frame_id)
-    : PrinterQuery(render_process_id, render_frame_id) {}
+TestPrinterQuery::TestPrinterQuery(content::GlobalRenderFrameHostId rfh_id)
+    : PrinterQuery(rfh_id) {}
 
 TestPrinterQuery::~TestPrinterQuery() = default;
 
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
index 6f620e2..e7d2646 100644
--- a/chrome/browser/printing/printer_query.cc
+++ b/chrome/browser/printing/printer_query.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/printing/print_job_worker.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "printing/buildflags/buildflags.h"
 #include "printing/print_settings.h"
 
@@ -31,27 +32,22 @@
 
 CreatePrintJobWorkerCallback* g_create_print_job_worker_for_testing = nullptr;
 
-std::unique_ptr<PrintJobWorker> CreateWorker(int render_process_id,
-                                             int render_frame_id) {
-  if (g_create_print_job_worker_for_testing) {
-    return g_create_print_job_worker_for_testing->Run(render_process_id,
-                                                      render_frame_id);
-  }
+std::unique_ptr<PrintJobWorker> CreateWorker(
+    content::GlobalRenderFrameHostId rfh_id) {
+  if (g_create_print_job_worker_for_testing)
+    return g_create_print_job_worker_for_testing->Run(rfh_id);
 
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
-  if (features::kEnableOopPrintDriversJobPrint.Get()) {
-    return std::make_unique<PrintJobWorkerOop>(render_process_id,
-                                               render_frame_id);
-  }
+  if (features::kEnableOopPrintDriversJobPrint.Get())
+    return std::make_unique<PrintJobWorkerOop>(rfh_id);
 #endif
-  return std::make_unique<PrintJobWorker>(render_process_id, render_frame_id);
+  return std::make_unique<PrintJobWorker>(rfh_id);
 }
 
 }  // namespace
 
-PrinterQuery::PrinterQuery(int render_process_id, int render_frame_id)
-    : cookie_(PrintSettings::NewCookie()),
-      worker_(CreateWorker(render_process_id, render_frame_id)) {
+PrinterQuery::PrinterQuery(content::GlobalRenderFrameHostId rfh_id)
+    : cookie_(PrintSettings::NewCookie()), worker_(CreateWorker(rfh_id)) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 }
 
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
index 28c8b1b7..9b5762b5 100644
--- a/chrome/browser/printing/printer_query.h
+++ b/chrome/browser/printing/printer_query.h
@@ -18,12 +18,17 @@
 class Location;
 }
 
+namespace content {
+struct GlobalRenderFrameHostId;
+}
+
 namespace printing {
 
 class PrintJobWorker;
 
-using CreatePrintJobWorkerCallback = base::RepeatingCallback<std::unique_ptr<
-    PrintJobWorker>(int render_process_id, int render_frame_id)>;
+using CreatePrintJobWorkerCallback =
+    base::RepeatingCallback<std::unique_ptr<PrintJobWorker>(
+        content::GlobalRenderFrameHostId rfh_id)>;
 
 // Query the printer for settings.
 class PrinterQuery {
@@ -35,7 +40,7 @@
   };
 
   // Can only be called on the IO thread.
-  PrinterQuery(int render_process_id, int render_frame_id);
+  explicit PrinterQuery(content::GlobalRenderFrameHostId rfh_id);
 
   PrinterQuery(const PrinterQuery&) = delete;
   PrinterQuery& operator=(const PrinterQuery&) = delete;
diff --git a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/FlocSettingsFragment.java b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/FlocSettingsFragment.java
index 0f6d26ee..419d8f7 100644
--- a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/FlocSettingsFragment.java
+++ b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/FlocSettingsFragment.java
@@ -51,7 +51,7 @@
                                 + " "
                                 + getContext().getString(R.string.privacy_sandbox_floc_description),
                         new SpanInfo("<link>", "</link>",
-                                new NoUnderlineClickableSpan(getContext().getResources(),
+                                new NoUnderlineClickableSpan(getContext(),
                                         (widget) -> openUrlInCct(getFlocRegionsUrl())))));
         findPreference(RESET_FLOC_EXPLANATION)
                 .setSummary(PrivacySandboxBridge.getFlocResetExplanationString());
diff --git a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java
index 9ad745b..851ab94 100644
--- a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java
+++ b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragment.java
@@ -75,7 +75,7 @@
                 .setSummary(SpanApplier.applySpans(
                         getContext().getString(R.string.privacy_sandbox_description_two),
                         new SpanInfo("<link>", "</link>",
-                                new NoUnderlineClickableSpan(getContext().getResources(),
+                                new NoUnderlineClickableSpan(getContext(),
                                         (widget) -> openUrlInCct(PRIVACY_SANDBOX_URL)))));
         // Format the toggle description, which has bullet points.
         findPreference(TOGGLE_DESCRIPTION_PREFERENCE)
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index c9f26ea..35fbe86 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <stddef.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -55,13 +56,10 @@
 #include <string>
 #include <type_traits>
 
-#include <stddef.h>
-
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/unique_ptr_adapters.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_descriptor_watcher_posix.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -144,7 +142,7 @@
 const char kShutdownToken[] = "SHUTDOWN";
 const char kTokenDelimiter = '\0';
 const int kMaxMessageLength = 32 * 1024;
-const int kMaxACKMessageLength = base::size(kShutdownToken) - 1;
+const int kMaxACKMessageLength = std::size(kShutdownToken) - 1;
 
 bool g_disable_prompt = false;
 bool g_skip_is_chrome_process_check = false;
@@ -259,7 +257,7 @@
   // maximally-sized paths on a platform where the singleton socket path is
   // already long. 11.5 xnu-7195.141.2/bsd/kern/uipc_usrreq.c unp_bind,
   // unp_connect.
-  if (path.length() > base::size(addr->sun_path))
+  if (path.length() > std::size(addr->sun_path))
     return false;
 
   // On input to the kernel, sun_len is ignored and overwritten by the value of
@@ -279,10 +277,10 @@
 #else
   // The portable version: NUL-terminate sun_path and don’t touch sun_len (which
   // may not even exist).
-  if (path.length() >= base::size(addr->sun_path))
+  if (path.length() >= std::size(addr->sun_path))
     return false;
   *socklen = sizeof(*addr);
-  base::strlcpy(addr->sun_path, path.c_str(), base::size(addr->sun_path));
+  base::strlcpy(addr->sun_path, path.c_str(), std::size(addr->sun_path));
 #endif
   return true;
 }
@@ -653,13 +651,13 @@
   if (parent_->notification_callback_.Run(base::CommandLine(argv),
                                           base::FilePath(current_dir))) {
     // Send back "ACK" message to prevent the client process from starting up.
-    reader->FinishWithACK(kACKToken, base::size(kACKToken) - 1);
+    reader->FinishWithACK(kACKToken, std::size(kACKToken) - 1);
   } else {
     LOG(WARNING) << "Not handling interprocess notification as browser"
                     " is shutting down";
     // Send back "SHUTDOWN" message, so that the client process can start up
     // without killing this process.
-    reader->FinishWithACK(kShutdownToken, base::size(kShutdownToken) - 1);
+    reader->FinishWithACK(kShutdownToken, std::size(kShutdownToken) - 1);
     return;
   }
 }
@@ -700,7 +698,7 @@
   }
 
   // Validate the message.  The shortest message is kStartToken\0x\0x
-  const size_t kMinMessageLength = base::size(kStartToken) + 4;
+  const size_t kMinMessageLength = std::size(kStartToken) + 4;
   if (bytes_read_ < kMinMessageLength) {
     buf_[bytes_read_] = 0;
     LOG(ERROR) << "Invalid socket message (wrong length):" << buf_;
@@ -919,12 +917,12 @@
   }
 
   buf[len] = '\0';
-  if (strncmp(buf, kShutdownToken, base::size(kShutdownToken) - 1) == 0) {
+  if (strncmp(buf, kShutdownToken, std::size(kShutdownToken) - 1) == 0) {
     // The other process is shutting down, it's safe to start a new process.
     internal::SendRemoteProcessInteractionResultHistogram(
         REMOTE_PROCESS_SHUTTING_DOWN);
     return PROCESS_NONE;
-  } else if (strncmp(buf, kACKToken, base::size(kACKToken) - 1) == 0) {
+  } else if (strncmp(buf, kACKToken, std::size(kACKToken) - 1) == 0) {
 #if defined(TOOLKIT_VIEWS) && \
     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
     // Likely NULL in unit tests.
diff --git a/chrome/browser/process_singleton_win_unittest.cc b/chrome/browser/process_singleton_win_unittest.cc
index 40b466ee..a91135e 100644
--- a/chrome/browser/process_singleton_win_unittest.cc
+++ b/chrome/browser/process_singleton_win_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/check.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/notreached.h"
@@ -207,7 +206,7 @@
     // The wait should always return because either |ready_event| is signaled or
     // |browser_victim_| died unexpectedly or exited on error.
     DWORD result =
-        ::WaitForMultipleObjects(base::size(handles), handles, FALSE, INFINITE);
+        ::WaitForMultipleObjects(std::size(handles), handles, FALSE, INFINITE);
     ASSERT_EQ(WAIT_OBJECT_0, result);
   }
 
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index eb3fb1d..b933dbe 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/synchronization/atomic_flag.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
@@ -136,7 +135,7 @@
   };
 
   ResettableFlags reset_triggered_for_flags = 0;
-  for (size_t i = 0; i < base::size(flagToMethod); ++i) {
+  for (size_t i = 0; i < std::size(flagToMethod); ++i) {
     if (resettable_flags & flagToMethod[i].flag) {
       reset_triggered_for_flags |= flagToMethod[i].flag;
       (this->*flagToMethod[i].method)();
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 452276f..8b71369 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -13,7 +13,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
@@ -668,8 +667,7 @@
   startup_pref = SessionStartupPref::GetStartupPref(prefs);
   EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
   const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
-  EXPECT_EQ(std::vector<GURL>(urls, urls + base::size(urls)),
-            startup_pref.urls);
+  EXPECT_EQ(std::vector<GURL>(urls, urls + std::size(urls)), startup_pref.urls);
 }
 
 
@@ -679,15 +677,14 @@
 
   const GURL urls[] = {GURL("http://foo"), GURL("http://bar")};
   SessionStartupPref startup_pref(SessionStartupPref::URLS);
-  startup_pref.urls.assign(urls, urls + base::size(urls));
+  startup_pref.urls.assign(urls, urls + std::size(urls));
   SessionStartupPref::SetStartupPref(prefs, startup_pref);
 
   ResetAndWait(ProfileResetter::STARTUP_PAGES, std::string());
 
   startup_pref = SessionStartupPref::GetStartupPref(prefs);
   EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type);
-  EXPECT_EQ(std::vector<GURL>(urls, urls + base::size(urls)),
-            startup_pref.urls);
+  EXPECT_EQ(std::vector<GURL>(urls, urls + std::size(urls)), startup_pref.urls);
 }
 
 TEST_F(PinnedTabsResetTest, ResetPinnedTabs) {
@@ -864,7 +861,7 @@
   EXPECT_EQ(diff_fields, nonorganic_snap.FindDifferentFields(organic_snap));
   nonorganic_snap.Subtract(organic_snap);
   const GURL urls[] = {GURL("http://foo.de"), GURL("http://goo.gl")};
-  EXPECT_EQ(std::vector<GURL>(urls, urls + base::size(urls)),
+  EXPECT_EQ(std::vector<GURL>(urls, urls + std::size(urls)),
             nonorganic_snap.startup_urls());
   EXPECT_EQ(SessionStartupPref::URLS, nonorganic_snap.startup_type());
   EXPECT_EQ("http://www.foo.com", nonorganic_snap.homepage());
diff --git a/chrome/browser/profiles/profile_attributes_storage.cc b/chrome/browser/profiles/profile_attributes_storage.cc
index 5c78ce0f..7ea72da 100644
--- a/chrome/browser/profiles/profile_attributes_storage.cc
+++ b/chrome/browser/profiles/profile_attributes_storage.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 #include "base/check.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/i18n/number_formatting.h"
 #include "base/i18n/string_compare.h"
@@ -564,7 +563,7 @@
     return true;
 
   // Check if it's one of the old-style profile names.
-  for (size_t i = 0; i < base::size(kDefaultNames); ++i) {
+  for (size_t i = 0; i < std::size(kDefaultNames); ++i) {
     if (name == l10n_util::GetStringUTF16(kDefaultNames[i]))
       return true;
   }
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
index 7435518..ce213fb 100644
--- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc
+++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -433,7 +433,7 @@
       {"path_4", "name_4", AccountId::FromUserEmailGaiaId("email4", "444444"),
        false}};
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     ProfileAttributesInitParams params;
     params.profile_path = GetProfilePath(kTestCases[i].profile_path);
     params.profile_name = base::ASCIIToUTF16(kTestCases[i].profile_name);
@@ -513,7 +513,7 @@
       {"path.test2", "name_2"},
       {"path_test3", "name_3"},
   };
-  const size_t kNumProfiles = base::size(kTestCases);
+  const size_t kNumProfiles = std::size(kTestCases);
 
   for (auto test_case : kTestCases) {
     base::FilePath profile_path = GetProfilePath(test_case.profile_path);
@@ -1873,7 +1873,7 @@
       {"path_7", "Person 3", true},        {"path_8", "Person 1", true},
       {"path_9", "Person 2", true},        {"path_10", "Person 1", true},
       {"path_11", "Smith", false},         {"path_12", "Person 2", true}};
-  const size_t kNumProfiles = base::size(kTestCases);
+  const size_t kNumProfiles = std::size(kTestCases);
 
   ProfileAttributesEntry* entry = nullptr;
   for (size_t i = 0; i < kNumProfiles; ++i) {
@@ -1937,7 +1937,7 @@
                     {"path_2", "First user"},
                     {"path_3", "Lemonade"},
                     {"path_4", "Batman"}};
-  const size_t kNumProfiles = base::size(kTestCases);
+  const size_t kNumProfiles = std::size(kTestCases);
 
   for (size_t i = 0; i < kNumProfiles; ++i) {
     base::FilePath profile_path = GetProfilePath(kTestCases[i].profile_path);
diff --git a/chrome/browser/profiles/profile_avatar_icon_util.cc b/chrome/browser/profiles/profile_avatar_icon_util.cc
index 7b358fd..ebc9a3cc 100644
--- a/chrome/browser/profiles/profile_avatar_icon_util.cc
+++ b/chrome/browser/profiles/profile_avatar_icon_util.cc
@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
@@ -624,7 +623,7 @@
 
 #if BUILDFLAG(IS_WIN)
 int GetOldDefaultAvatar2xIconResourceIDAtIndex(size_t index) {
-  DCHECK_LT(index, base::size(kProfileAvatarIconResources2x));
+  DCHECK_LT(index, std::size(kProfileAvatarIconResources2x));
   return kProfileAvatarIconResources2x[index];
 }
 #endif  // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index c9cb4ade..36a05b5 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -121,7 +121,7 @@
   } else {
     application_server_key =
         std::string(kApplicationServerKey,
-                    kApplicationServerKey + base::size(kApplicationServerKey));
+                    kApplicationServerKey + std::size(kApplicationServerKey));
   }
 
   return application_server_key;
diff --git a/chrome/browser/push_messaging/push_messaging_service_unittest.cc b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
index 2ef2f19..08d6eae 100644
--- a/chrome/browser/push_messaging/push_messaging_service_unittest.cc
+++ b/chrome/browser/push_messaging/push_messaging_service_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/public/browser/push_messaging_service.h"
-
 #include <stdint.h>
 
 #include <string>
@@ -11,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -34,6 +31,7 @@
 #include "components/gcm_driver/fake_gcm_profile_service.h"
 #include "components/gcm_driver/gcm_profile_service.h"
 #include "components/permissions/permission_manager.h"
+#include "content/public/browser/push_messaging_service.h"
 #include "content/public/common/content_features.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -317,7 +315,7 @@
   PushMessagingServiceImpl* push_service = profile()->GetPushMessagingService();
   ASSERT_TRUE(push_service);
 
-  std::string p256dh(kTestP256Key, kTestP256Key + base::size(kTestP256Key));
+  std::string p256dh(kTestP256Key, kTestP256Key + std::size(kTestP256Key));
   ASSERT_EQ(65u, p256dh.size());
 
   // NIST P-256 public keys in uncompressed format will be encoded using the
diff --git a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc
index 7799ea5..aece0b2 100644
--- a/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc
+++ b/chrome/browser/reading_list/android/reading_list_manager_impl_unittest.cc
@@ -236,7 +236,7 @@
   // Use an invalid UTF8 string.
   std::u16string dummy;
   EXPECT_FALSE(
-      base::UTF8ToUTF16(kInvalidUTF8, base::size(kInvalidUTF8), &dummy));
+      base::UTF8ToUTF16(kInvalidUTF8, std::size(kInvalidUTF8), &dummy));
   const auto* new_node = Add(url, std::string(kInvalidUTF8));
   EXPECT_EQ(nullptr, new_node)
       << "Should return nullptr when failed to parse the title.";
diff --git a/chrome/browser/renderer_host/chrome_extension_message_filter.cc b/chrome/browser/renderer_host/chrome_extension_message_filter.cc
index bdc76a0..020d3c1f 100644
--- a/chrome/browser/renderer_host/chrome_extension_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_extension_message_filter.cc
@@ -10,7 +10,6 @@
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
 #include "base/containers/adapters.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/memory/ptr_util.h"
 #include "base/notreached.h"
@@ -58,7 +57,7 @@
 
 ChromeExtensionMessageFilter::ChromeExtensionMessageFilter(Profile* profile)
     : BrowserMessageFilter(kExtensionFilteredMessageClasses,
-                           base::size(kExtensionFilteredMessageClasses)),
+                           std::size(kExtensionFilteredMessageClasses)),
       profile_(profile),
       activity_log_(extensions::ActivityLog::GetInstance(profile)) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
index 308e7bff..2425ccd 100644
--- a/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_isolated_file_system_message_filter.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -67,7 +66,7 @@
     : render_process_id_(render_process_id),
       profile_directory_(profile_directory),
       document_url_(document_url) {
-  for (size_t i = 0; i < base::size(kPredefinedAllowedCrxFsOrigins); ++i)
+  for (size_t i = 0; i < std::size(kPredefinedAllowedCrxFsOrigins); ++i)
     allowed_crxfs_origins_.insert(kPredefinedAllowedCrxFsOrigins[i]);
 }
 
diff --git a/chrome/browser/resource_coordinator/decision_details.cc b/chrome/browser/resource_coordinator/decision_details.cc
index 800184b2..ec8f5aa 100644
--- a/chrome/browser/resource_coordinator/decision_details.cc
+++ b/chrome/browser/resource_coordinator/decision_details.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/resource_coordinator/decision_details.h"
 
-#include "base/cxx17_backports.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 
 namespace resource_coordinator {
@@ -40,7 +39,7 @@
     "Tab has notification permission ",
     "Tab is a web application window",
 };
-static_assert(base::size(kDecisionFailureReasonStrings) ==
+static_assert(std::size(kDecisionFailureReasonStrings) ==
                   static_cast<size_t>(DecisionFailureReason::MAX),
               "kDecisionFailureReasonStrings not up to date with enum");
 
@@ -49,7 +48,7 @@
     "Origin is in global allowlist",
     "Origin has locally been observed to be safe via heuristic logic",
 };
-static_assert(base::size(kDecisionSuccessReasonStrings) ==
+static_assert(std::size(kDecisionSuccessReasonStrings) ==
                   static_cast<size_t>(DecisionSuccessReason::MAX),
               "kDecisionSuccessReasonStrings not up to date with enum");
 
diff --git a/chrome/browser/resource_coordinator/session_restore_policy.cc b/chrome/browser/resource_coordinator/session_restore_policy.cc
index 8110df7..4e6e78f 100644
--- a/chrome/browser/resource_coordinator/session_restore_policy.cc
+++ b/chrome/browser/resource_coordinator/session_restore_policy.cc
@@ -49,14 +49,14 @@
   static constexpr char kInternalUrlPrefix[] = "chrome-extension://";
   const GURL& url = contents->GetLastCommittedURL();
   return strncmp(url.spec().c_str(), kInternalUrlPrefix,
-                 base::size(kInternalUrlPrefix));
+                 std::size(kInternalUrlPrefix));
 }
 
 bool IsInternalPage(content::WebContents* contents) {
   static constexpr char kInternalUrlPrefix[] = "chrome://";
   const GURL& url = contents->GetLastCommittedURL();
   return strncmp(url.spec().c_str(), kInternalUrlPrefix,
-                 base::size(kInternalUrlPrefix));
+                 std::size(kInternalUrlPrefix));
 }
 
 class SysInfoDelegate : public SessionRestorePolicy::Delegate {
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index f1748d0b..72b659cf 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -284,7 +284,7 @@
       chrome::kChromeUINewTabURL, chrome::kChromeUISettingsURL};
   // Prefix-match against the table above. Use strncmp to avoid allocating
   // memory to convert the URL prefix constants into std::strings.
-  for (size_t i = 0; i < base::size(kInternalPagePrefixes); ++i) {
+  for (size_t i = 0; i < std::size(kInternalPagePrefixes); ++i) {
     if (!strncmp(url.spec().c_str(), kInternalPagePrefixes[i],
                  strlen(kInternalPagePrefixes[i])))
       return true;
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js
index 9b697be..a68ce648 100644
--- a/chrome/browser/resources/about_sys/about_sys.js
+++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -51,7 +51,7 @@
  */
 function changeCollapsedStatus() {
   const valueDiv = getValueDivForButton(this);
-  if (valueDiv.parentNode.className == 'number-collapsed') {
+  if (valueDiv.parentNode.className === 'number-collapsed') {
     valueDiv.parentNode.className = 'number-expanded';
     this.textContent = loadTimeData.getString('collapseBtn');
   } else {
@@ -67,7 +67,7 @@
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; i++) {
     const button = getButtonForValueDiv(valueDivs[i]);
-    if (button && button.className != 'button-hidden') {
+    if (button && button.className !== 'button-hidden') {
       button.textContent = loadTimeData.getString('expandBtn');
       valueDivs[i].parentNode.className = 'number-collapsed';
     }
@@ -81,7 +81,7 @@
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; i++) {
     const button = getButtonForValueDiv(valueDivs[i]);
-    if (button && button.className != 'button-hidden') {
+    if (button && button.className !== 'button-hidden') {
       button.textContent = loadTimeData.getString('collapseBtn');
       valueDivs[i].parentNode.className = 'number-expanded';
     }
@@ -223,7 +223,7 @@
 
     const delimiter = lines[i].indexOf('=');
     if (delimiter <= 0) {
-      if (i == lines.length - 1) {
+      if (i === lines.length - 1) {
         break;
       }
       // If '=' is missing here, format is wrong.
@@ -240,16 +240,16 @@
     // Delimiters are based on kMultilineIndicatorString, kMultilineStartString,
     // and kMultilineEndString in components/feedback/feedback_data.cc.
     // If these change, we should check for both the old and new versions.
-    if (value == '<multiline>') {
+    if (value === '<multiline>') {
       // Skip start delimiter.
-      if (i == len - 1 || lines[++i].indexOf(DELIM_START) == -1) {
+      if (i === len - 1 || lines[++i].indexOf(DELIM_START) === -1) {
         return false;
       }
 
       ++i;
       value = '';
       // Append lines between start and end delimiters.
-      while (i < len && lines[i] != DELIM_END) {
+      while (i < len && lines[i] !== DELIM_END) {
         value += lines[i++] + '\n';
       }
 
diff --git a/chrome/browser/resources/accessibility/accessibility.js b/chrome/browser/resources/accessibility/accessibility.js
index bee1074..2c1bcf92 100644
--- a/chrome/browser/resources/accessibility/accessibility.js
+++ b/chrome/browser/resources/accessibility/accessibility.js
@@ -93,11 +93,11 @@
 }
 
 function getIdFromData(data) {
-  if (data.type == 'page') {
+  if (data.type === 'page') {
     return data.processId + '.' + data.routingId;
-  } else if (data.type == 'browser') {
+  } else if (data.type === 'browser') {
     return 'browser.' + data.sessionId;
-  } else if (data.type == 'widget') {
+  } else if (data.type === 'widget') {
     return 'widget.' + data.widgetId;
   } else {
     console.error('Unknown data type.', data);
@@ -113,7 +113,7 @@
   const id = getIdFromData(data);
   const tree = $(id + ':tree');
   // If the tree is visible, request a new tree with the updated mode.
-  const shouldRequestTree = !!tree && tree.style.display != 'none';
+  const shouldRequestTree = !!tree && tree.style.display !== 'none';
   browserProxy.toggleAccessibility(
       data.processId, data.routingId, mode, shouldRequestTree);
 }
@@ -131,13 +131,13 @@
   // 'copyTree'. Send the request type to C++ so is calls the corresponding
   // function with the result.
   const requestType = element.id.split(':')[1];
-  if (data.type == 'browser') {
+  if (data.type === 'browser') {
     const delay = $('native-ui-delay').value;
     setTimeout(() => {
       browserProxy.requestNativeUITree(
           data.sessionId, requestType, allow, allowEmpty, deny);
     }, delay);
-  } else if (data.type == 'widget') {
+  } else if (data.type === 'widget') {
     browserProxy.requestWidgetsTree(
         data.widgetId, requestType, allow, allowEmpty, deny);
   } else {
@@ -147,7 +147,7 @@
 }
 
 function requestEvents(data, element) {
-  const start = element.textContent == 'Start recording';
+  const start = element.textContent === 'Start recording';
   if (start) {
     element.textContent = 'Stop recording';
     element.setAttribute('aria-expanded', 'true');
@@ -156,7 +156,7 @@
     // there can only be one accessibility recorder at once.
     const buttons = document.getElementsByClassName('recordEventsButton');
     for (const button of buttons) {
-      if (button != element) {
+      if (button !== element) {
         button.disabled = true;
       }
     }
@@ -167,7 +167,7 @@
     // Enable all start recording buttons.
     const buttons = document.getElementsByClassName('recordEventsButton');
     for (const button of buttons) {
-      if (button != element) {
+      if (button !== element) {
         button.disabled = false;
       }
     }
@@ -233,10 +233,10 @@
 }
 
 function bindCheckbox(name, value) {
-  if (value == 'on') {
+  if (value === 'on') {
     $(name).checked = true;
   }
-  if (value == 'disabled') {
+  if (value === 'disabled') {
     $(name).disabled = true;
     $(name).labels[0].classList.add('disabled');
   }
@@ -291,7 +291,7 @@
     }
   }
 
-  if (data.type == 'page') {
+  if (data.type === 'page') {
     const siteInfo = document.createElement('div');
     const properties = ['faviconUrl', 'name', 'url'];
     for (let j = 0; j < properties.length; j++) {
@@ -325,7 +325,7 @@
   }
   // The accessibility event recorder currently only works for pages.
   // TODO(abigailbklein): Add event recording for native as well.
-  if (data.type == 'page') {
+  if (data.type === 'page') {
     row.appendChild(
         createStartStopAccessibilityEventRecordingElement(data, row.id));
   }
@@ -351,7 +351,7 @@
 function formatValue(data, property) {
   const value = data[property];
 
-  if (property == 'faviconUrl') {
+  if (property === 'faviconUrl') {
     const faviconElement = document.createElement('img');
     if (value) {
       faviconElement.src = value;
@@ -367,7 +367,7 @@
 
   const span = document.createElement('span');
   const content = ' ' + text + ' ';
-  if (property == 'name') {
+  if (property === 'name') {
     const id = getIdFromData(data);
     insertHeadingInline(span, content, id);
   } else {
@@ -405,7 +405,7 @@
   link.setAttribute('is', 'action-link');
   link.setAttribute('role', 'button');
 
-  const stateText = ((currentMode & mode) != 0) ? 'true' : 'false';
+  const stateText = ((currentMode & mode) !== 0) ? 'true' : 'false';
   const isEnabled = data[globalStateName];
   if (isEnabled) {
     link.textContent = getNameForAccessibilityMode(mode) + ': ' + stateText;
@@ -423,7 +423,7 @@
 function createShowAccessibilityTreeElement(
     data, id, requestType, opt_refresh) {
   const show = document.createElement('button');
-  if (requestType == 'showOrRefreshTree') {
+  if (requestType === 'showOrRefreshTree') {
     // Give feedback that the tree has loaded.
     show.textContent = 'Accessibility tree loaded';
     setTimeout(() => {
@@ -488,7 +488,7 @@
   closeLink.addEventListener('click', function() {
     const parentElement = errorMessageElement.parentElement;
     parentElement.removeChild(errorMessageElement);
-    if (parentElement.childElementCount == 0) {
+    if (parentElement.childElementCount === 0) {
       parentElement.parentElement.removeChild(parentElement);
     }
   });
@@ -548,7 +548,7 @@
 
   const tree = $(id + ':tree');
   // If the tree is currently shown, update it since it may have changed.
-  if (tree && tree.style.display != 'none') {
+  if (tree && tree.style.display !== 'none') {
     showOrRefreshTree(data);
     $(id + ':copyTree').focus();
   }
diff --git a/chrome/browser/resources/app_settings/web_app_settings.html b/chrome/browser/resources/app_settings/web_app_settings.html
index 3b3bd4a..a5ca054 100644
--- a/chrome/browser/resources/app_settings/web_app_settings.html
+++ b/chrome/browser/resources/app_settings/web_app_settings.html
@@ -3,8 +3,10 @@
 <head>
   <meta charset="utf-8">
   <style>
-    html {
-      background-color: var(--md-background-color);
+    @media (prefers-color-scheme: dark) {
+      body {
+        background-color: var(--md-background-color);
+      }
     }
 
     html,
diff --git a/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
index 2f80d16..10cbcfc 100644
--- a/chrome/browser/resources/bluetooth_internals/adapter_broker.js
+++ b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -103,7 +103,7 @@
    */
   connectToDevice(address) {
     return this.adapter_.connectToDevice(address).then(function(response) {
-      if (response.result != ConnectResult.SUCCESS) {
+      if (response.result !== ConnectResult.SUCCESS) {
         // TODO(crbug.com/663394): Replace with more descriptive error
         // messages.
         const errorString = Object.keys(ConnectResult).find(function(key) {
diff --git a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
index 18e44f4..4d149e2 100644
--- a/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
+++ b/chrome/browser/resources/bluetooth_internals/bluetooth_internals.js
@@ -168,7 +168,7 @@
         event.detail.value;
     adapterPage.redraw();
 
-    if (event.detail.property == AdapterProperty.DISCOVERING &&
+    if (event.detail.property === AdapterProperty.DISCOVERING &&
         !event.detail.value && !userRequestedScanStop && discoverySession) {
       updateStoppedDiscoverySession();
       Snackbar.show(
diff --git a/chrome/browser/resources/bluetooth_internals/device_collection.js b/chrome/browser/resources/bluetooth_internals/device_collection.js
index f7bf900..94a2de3 100644
--- a/chrome/browser/resources/bluetooth_internals/device_collection.js
+++ b/chrome/browser/resources/bluetooth_internals/device_collection.js
@@ -47,7 +47,7 @@
   getByAddress(address) {
     for (let i = 0; i < this.length; i++) {
       const device = this.item(i);
-      if (address == device.address) {
+      if (address === device.address) {
         return device;
       }
     }
diff --git a/chrome/browser/resources/bluetooth_internals/device_table.js b/chrome/browser/resources/bluetooth_internals/device_table.js
index c93f4d38..f7862ab 100644
--- a/chrome/browser/resources/bluetooth_internals/device_table.js
+++ b/chrome/browser/resources/bluetooth_internals/device_table.js
@@ -229,11 +229,11 @@
         obj = obj[part];
       }
 
-      if (propName == 'isGattConnected') {
+      if (propName === 'isGattConnected') {
         obj = obj ? 'Connected' : 'Not Connected';
-      } else if (propName == 'serviceUuids') {
+      } else if (propName === 'serviceUuids') {
         obj = formatServiceUuids(obj);
-      } else if (propName == 'manufacturerDataMap') {
+      } else if (propName === 'manufacturerDataMap') {
         obj = formatManufacturerDataMap(obj);
       }
 
diff --git a/chrome/browser/resources/bluetooth_internals/page.js b/chrome/browser/resources/bluetooth_internals/page.js
index f8e5da2..8a193ac 100644
--- a/chrome/browser/resources/bluetooth_internals/page.js
+++ b/chrome/browser/resources/bluetooth_internals/page.js
@@ -22,7 +22,7 @@
     const element = elements[i];
     element.focus();
     // .focus() isn't guaranteed to work. Continue until it does.
-    if (document.activeElement == element) {
+    if (document.activeElement === element) {
       return;
     }
   }
@@ -103,7 +103,7 @@
    *     should include the leading '#' if not empty.
    */
   setHash(hash) {
-    if (this.hash == hash) {
+    if (this.hash === hash) {
       return;
     }
     this.hash = hash;
@@ -134,7 +134,7 @@
     if (this.pageDiv.hidden) {
       return false;
     }
-    return this.pageDiv.page == this;
+    return this.pageDiv.page === this;
   }
 
   /**
diff --git a/chrome/browser/resources/bluetooth_internals/page_manager.js b/chrome/browser/resources/bluetooth_internals/page_manager.js
index af922f0..b3f1a87 100644
--- a/chrome/browser/resources/bluetooth_internals/page_manager.js
+++ b/chrome/browser/resources/bluetooth_internals/page_manager.js
@@ -113,7 +113,7 @@
 
     // Notify pages if they will be hidden.
     this.registeredPages.forEach(page => {
-      if (page.name != pageName && !this.isAncestorOfPage(page, targetPage)) {
+      if (page.name !== pageName && !this.isAncestorOfPage(page, targetPage)) {
         page.willHidePage();
       }
     });
@@ -124,7 +124,7 @@
     // Update visibilities to show only the hierarchy of the target page.
     this.registeredPages.forEach(page => {
       page.visible =
-          page.name == pageName || this.isAncestorOfPage(page, targetPage);
+          page.name === pageName || this.isAncestorOfPage(page, targetPage);
     });
 
     // Update the history and current location.
@@ -134,7 +134,7 @@
 
     // Update focus if any other control was focused on the previous page,
     // or the previous page is not known.
-    if (document.activeElement != document.body &&
+    if (document.activeElement !== document.body &&
         (!rootPage || rootPage.pageDiv.contains(document.activeElement))) {
       targetPage.focus();
     }
@@ -142,7 +142,7 @@
     // Notify pages if they were shown.
     this.registeredPages.forEach(page => {
       if (!targetPageWasVisible &&
-          (page.name == pageName || this.isAncestorOfPage(page, targetPage))) {
+          (page.name === pageName || this.isAncestorOfPage(page, targetPage))) {
         page.didShowPage();
       }
     });
@@ -198,7 +198,7 @@
   isAncestorOfPage(potentialAncestor, potentialDescendent) {
     let parent = potentialDescendent.parentPage;
     while (parent) {
-      if (parent == potentialAncestor) {
+      if (parent === potentialAncestor) {
         return true;
       }
       parent = parent.parentPage;
@@ -213,7 +213,7 @@
    */
   onPageHashChanged_(e) {
     const page = /** @type {!Page} */ (e.target);
-    if (page == this.getTopmostVisiblePage()) {
+    if (page === this.getTopmostVisiblePage()) {
       this.updateHistoryState_(false);
     }
   }
@@ -279,8 +279,8 @@
 
     // If the page is already in history (the user may have clicked the same
     // link twice, or this is the initial load), do nothing.
-    const newPath = (page == this.defaultPage_ ? '' : page.name) + page.hash;
-    if (path == newPath) {
+    const newPath = (page === this.defaultPage_ ? '' : page.name) + page.hash;
+    if (path === newPath) {
       return;
     }
 
diff --git a/chrome/browser/resources/bluetooth_internals/value_control.js b/chrome/browser/resources/bluetooth_internals/value_control.js
index 7d34fb4..36d571d 100644
--- a/chrome/browser/resources/bluetooth_internals/value_control.js
+++ b/chrome/browser/resources/bluetooth_internals/value_control.js
@@ -107,7 +107,7 @@
    * @private
    */
   toHex_() {
-    if (this.value_.length == 0) {
+    if (this.value_.length === 0) {
       return '';
     }
 
diff --git a/chrome/browser/resources/bookmarks/bookmarks.html b/chrome/browser/resources/bookmarks/bookmarks.html
index 251e3cb3..68f8694 100644
--- a/chrome/browser/resources/bookmarks/bookmarks.html
+++ b/chrome/browser/resources/bookmarks/bookmarks.html
@@ -15,12 +15,17 @@
 
     html,
     body {
-      background: var(--md-background-color);
       height: 100%;
       margin: 0;
       overflow: hidden;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     html.loading::before {
       background-color: var(--md-toolbar-color);
       border-bottom: var(--md-toolbar-border);
diff --git a/chrome/browser/resources/cryptotoken/appid.js b/chrome/browser/resources/cryptotoken/appid.js
index 485f264e..e94ee994 100644
--- a/chrome/browser/resources/cryptotoken/appid.js
+++ b/chrome/browser/resources/cryptotoken/appid.js
@@ -20,14 +20,14 @@
     if (trustedFacets) {
       var versionBlock;
       for (i = 0; versionBlock = trustedFacets[i]; i++) {
-        if (versionBlock['version'] && versionBlock['version']['major'] == 1 &&
-            versionBlock['version']['minor'] == 0) {
+        if (versionBlock['version'] && versionBlock['version']['major'] === 1 &&
+            versionBlock['version']['minor'] === 0) {
           urls = versionBlock['ids'];
           break;
         }
       }
     }
-    if (typeof urls == 'undefined') {
+    if (typeof urls === 'undefined') {
       throw Error('Could not find trustedFacets for version 1.0');
     }
     var origins = {};
@@ -162,14 +162,14 @@
  * @private
  */
 XhrAppIdChecker.prototype.checkAppId_ = function(appId) {
-  if (appId == this.origin_) {
+  if (appId === this.origin_) {
     // Trivially allowed
     return Promise.resolve(true);
   }
   var p = this.fetchAllowedOriginsForAppId_(appId);
   var self = this;
   return p.then(function(allowedOrigins) {
-    if (allowedOrigins.indexOf(self.origin_) == -1) {
+    if (allowedOrigins.indexOf(self.origin_) === -1) {
       console.warn(UTIL_fmt(
           'Origin ' + self.origin_ + ' not allowed by app id ' + appId));
       return false;
@@ -186,7 +186,7 @@
 XhrAppIdChecker.prototype.allAppIdsEqualOrigin_ = function() {
   var self = this;
   return this.distinctAppIds_.every(function(appId) {
-    return appId == self.origin_;
+    return appId === self.origin_;
   });
 };
 
@@ -202,7 +202,7 @@
     return Promise.resolve([]);
   }
 
-  if (appId.indexOf('http://') == 0 && !this.allowHttp_) {
+  if (appId.indexOf('http://') === 0 && !this.allowHttp_) {
     console.log(UTIL_fmt('http app ids disallowed, ' + appId + ' requested'));
     return Promise.resolve([]);
   }
diff --git a/chrome/browser/resources/cryptotoken/asn1.js b/chrome/browser/resources/cryptotoken/asn1.js
index efbd80be..67f0efa 100644
--- a/chrome/browser/resources/cryptotoken/asn1.js
+++ b/chrome/browser/resources/cryptotoken/asn1.js
@@ -40,7 +40,7 @@
    * @return {boolean} True if the buffer is empty.
    */
   get empty() {
-    return this.slice_.length == 0;
+    return this.slice_.length === 0;
   }
 
   /**
@@ -100,7 +100,7 @@
       throw Error('getASN1: empty slice, expected tag ' + expectedTag);
     }
     const v = this.getAnyASN1();
-    if (v.tag != expectedTag) {
+    if (v.tag !== expectedTag) {
       throw Error('getASN1: got tag ' + v.tag + ', want ' + expectedTag);
     }
     if (!opt_includeHeader) {
@@ -137,7 +137,7 @@
         break;
       }
     }
-    if (len == 0) {
+    if (len === 0) {
       throw Error('terminating byte not found');
     }
     var n = 0;
@@ -183,7 +183,7 @@
    * @return {ByteString}
    * */
   getOptionalASN1(expectedTag) {
-    if (this.slice_.length < 1 || this.slice_[0] != expectedTag) {
+    if (this.slice_.length < 1 || this.slice_[0] !== expectedTag) {
       return null;
     }
     return this.getASN1(expectedTag);
@@ -200,14 +200,14 @@
     const tag = header.getU8_();
     const lengthByte = header.getU8_();
 
-    if ((tag & 0x1f) == 0x1f) {
+    if ((tag & 0x1f) === 0x1f) {
       throw Error('getAnyASN1: long-form tag found');
     }
 
     var len = 0;
     var headerLen = 0;
 
-    if ((lengthByte & 0x80) == 0) {
+    if ((lengthByte & 0x80) === 0) {
       // Short form length.
       len = lengthByte + 2;
       headerLen = 2;
@@ -221,7 +221,7 @@
       // numbers.  This check ensures that we stay under this limit.  We could
       // do this in a better way, but there's no need to process very large
       // objects.
-      if (numBytes == 0 || numBytes > 3) {
+      if (numBytes === 0 || numBytes > 3) {
         throw Error('getAnyASN1: bad ASN.1 long-form length');
       }
       const lengthBytes = header.getBytes(numBytes);
@@ -230,7 +230,7 @@
         len |= lengthBytes[i];
       }
 
-      if (len < 128 || (len >> ((numBytes - 1) * 8)) == 0) {
+      if (len < 128 || (len >> ((numBytes - 1) * 8)) === 0) {
         throw Error('getAnyASN1: incorrectly encoded ASN.1 length');
       }
 
@@ -452,7 +452,7 @@
       // In the case of ASN.1 a single byte was reserved for
       // the length. The contents of the array may need to be
       // shifted along if the length needs more than that.
-      if (lenLen != 1) {
+      if (lenLen !== 1) {
         throw Error('internal error');
       }
 
@@ -492,7 +492,7 @@
       l >>= 8;
     }
 
-    if (l != 0) {
+    if (l !== 0) {
       throw Error('pending child length exceeds reserved space');
     }
 
@@ -548,19 +548,19 @@
    */
   addASN1BigInt(bytes) {
     // Zero is representated as a single zero byte, rather than no bytes.
-    if (bytes.length == 0) {
+    if (bytes.length === 0) {
       bytes = new Uint8Array(1);
     }
 
     // Leading zero bytes need to be removed, unless that would make the number
     // negative.
-    while (bytes.length >= 2 && bytes[0] == 0 && (bytes[1] & 0x80) == 0) {
+    while (bytes.length >= 2 && bytes[0] === 0 && (bytes[1] & 0x80) === 0) {
       bytes = bytes.slice(1);
     }
 
     // If the MSB is set, the number will be considered to be negative. Thus
     // a zero prefix is needed in that case.
-    if (bytes.length > 0 && (bytes[0] & 0x80) == 0x80) {
+    if (bytes.length > 0 && (bytes[0] & 0x80) === 0x80) {
       if (bytes.length > Number.MAX_SAFE_INTEGER - 1) {
         throw Error('bigint array too long');
       }
@@ -587,7 +587,7 @@
     }
 
     var length = 0;
-    if (n == 0) {
+    if (n === 0) {
       length = 1;
     } else {
       for (var i = n; i > 0; i >>= 7) {
@@ -597,7 +597,7 @@
 
     for (var i = length - 1; i >= 0; i--) {
       var octet = 0x7f & (n >> (7 * i));
-      if (i != 0) {
+      if (i !== 0) {
         octet |= 0x80;
       }
       this.addU8_(octet);
@@ -643,7 +643,7 @@
       const code = s.charCodeAt(i);
       if ((code < 97 && code > 122) &&  // a-z
           (code < 65 && code > 90) &&   // A-Z
-          ' \'()+,-/:=?'.indexOf(String.fromCharCode(code)) == -1) {
+          ' \'()+,-/:=?'.indexOf(String.fromCharCode(code)) === -1) {
         throw Error(
             'cannot encode \'' + String.fromCharCode(code) + '\' in' +
             ' PrintableString');
diff --git a/chrome/browser/resources/cryptotoken/cbor.js b/chrome/browser/resources/cryptotoken/cbor.js
index 369f6854..dea09bc 100644
--- a/chrome/browser/resources/cryptotoken/cbor.js
+++ b/chrome/browser/resources/cryptotoken/cbor.js
@@ -14,7 +14,7 @@
     return this.slice.length;
   }
   get empty() {
-    return this.slice.length == 0;
+    return this.slice.length === 0;
   }
   get hex() {
     const hexTable = '0123456789abcdef';
@@ -36,17 +36,17 @@
           chars[v & 0x3f]);
     }
     const remainder = this.slice.length - len3;
-    if (remainder == 1) {
+    if (remainder === 1) {
       const v = this.slice[len3];
       chunks.push(chars[v >> 2] + chars[(v << 4) & 0x3f]);
-      if (padding == 1 /* Include */) {
+      if (padding === 1 /* Include */) {
         chunks.push('==');
       }
-    } else if (remainder == 2) {
+    } else if (remainder === 2) {
       const v = (this.slice[len3] << 8) + this.slice[len3 + 1];
       chunks.push(
           chars[v >> 10] + chars[(v >> 4) & 0x3f] + chars[(v << 2) & 0x3f]);
-      if (padding == 1 /* Include */) {
+      if (padding === 1 /* Include */) {
         chunks.push('=');
       }
     }
@@ -119,7 +119,7 @@
       throw 'getASN1: empty slice, expected tag ' + expectedTag;
     }
     const v = this.getAnyASN1();
-    if (v.tag != expectedTag) {
+    if (v.tag !== expectedTag) {
       throw 'getASN1: got tag ' + v.tag + ', want ' + expectedTag;
     }
     if (!includeHeader) {
@@ -134,7 +134,7 @@
     return this.getASN1_(expectedTag, true);
   }
   getOptionalASN1(expectedTag) {
-    if (this.slice.length < 1 || this.slice[0] != expectedTag) {
+    if (this.slice.length < 1 || this.slice[0] !== expectedTag) {
       return null;
     }
     return this.getASN1(expectedTag);
@@ -143,12 +143,12 @@
     const header = new Cbor(this.slice);
     const tag = header.getU8();
     const lengthByte = header.getU8();
-    if ((tag & 0x1f) == 0x1f) {
+    if ((tag & 0x1f) === 0x1f) {
       throw 'getAnyASN1: long-form tag found';
     }
     let len = 0;
     let headerLen = 0;
-    if ((lengthByte & 0x80) == 0) {
+    if ((lengthByte & 0x80) === 0) {
       // Short form length.
       len = lengthByte + 2;
       headerLen = 2;
@@ -161,7 +161,7 @@
       // numbers.  This check ensures that we stay under this limit.  We could
       // do this in a better way, but there's no need to process very large
       // objects.
-      if (numBytes == 0 || numBytes > 3) {
+      if (numBytes === 0 || numBytes > 3) {
         throw 'getAnyASN1: bad ASN.1 long-form length';
       }
       const lengthBytes = header.getBytes(numBytes);
@@ -169,7 +169,7 @@
         len <<= 8;
         len |= lengthBytes[i];
       }
-      if (len < 128 || (len >> ((numBytes - 1) * 8)) == 0) {
+      if (len < 128 || (len >> ((numBytes - 1) * 8)) === 0) {
         throw 'getAnyASN1: incorrectly encoded ASN.1 length';
       }
       headerLen = 2 + numBytes;
@@ -194,13 +194,13 @@
         break;
       }
     }
-    if (len == 0) {
+    if (len === 0) {
       throw 'base128 value too large';
     }
     let n = 0;
     let octets = this.getBytes(len);
     for (let i = 0; i < len; i++) {
-      if ((n & 0xff000000) != 0) {
+      if ((n & 0xff000000) !== 0) {
         throw 'base128 value too large';
       }
       n <<= 7;
@@ -286,26 +286,26 @@
         return ret;
       }
       case 5:
-        if (value == 0) {
+        if (value === 0) {
           return {};
         }
         let copy = new Cbor(this.data);
         const [firstKeyMajor] = copy.getCBORHeader();
-        if (firstKeyMajor == 3) {
+        if (firstKeyMajor === 3) {
           // String-keyed map.
           let lastKeyHeader = new Cbor(new Uint8Array(0));
           let lastKeyBytes = new Cbor(new Uint8Array(0));
           let ret = {};
           for (let i = 0; i < value; i++) {
             const [keyMajor, keyLength, keyHeader] = this.getCBORHeader();
-            if (keyMajor != 3) {
+            if (keyMajor !== 3) {
               throw('Cbor: non-string in string-valued map');
             }
             const keyBytes = new Cbor(this.getBytes(keyLength));
             if (i > 0) {
               const headerCmp = lastKeyHeader.compare(keyHeader);
               if (headerCmp > 0 ||
-                  (headerCmp == 0 && lastKeyBytes.compare(keyBytes) >= 0)) {
+                  (headerCmp === 0 && lastKeyBytes.compare(keyBytes) >= 0)) {
                 throw(
                     'Cbor: map keys in wrong order: ' + lastKeyHeader.hex +
                     '/' + lastKeyBytes.hex + ' ' + keyHeader.hex + '/' +
@@ -317,13 +317,13 @@
             ret[keyBytes.parseUTF8()] = this.getCBOR();
           }
           return ret;
-        } else if (firstKeyMajor == 0 || firstKeyMajor == 1) {
+        } else if (firstKeyMajor === 0 || firstKeyMajor === 1) {
           // Number-keyed map.
           let lastKeyHeader = new Cbor(new Uint8Array(0));
           let ret = {};
           for (let i = 0; i < value; i++) {
             let [keyMajor, keyValue, keyHeader] = this.getCBORHeader();
-            if (keyMajor != 0 && keyMajor != 1) {
+            if (keyMajor !== 0 && keyMajor !== 1) {
               throw('Cbor: non-number in number-valued map');
             }
             if (i > 0 && lastKeyHeader.compare(keyHeader) >= 0) {
@@ -332,7 +332,7 @@
                   keyHeader.hex);
             }
             lastKeyHeader = keyHeader;
-            if (keyMajor == 1) {
+            if (keyMajor === 1) {
               keyValue = 0 - (1 + keyValue);
             }
             ret[keyValue] = this.getCBOR();
diff --git a/chrome/browser/resources/cryptotoken/cryptotokenapprovedorigins.js b/chrome/browser/resources/cryptotoken/cryptotokenapprovedorigins.js
index 9b3bc10..3394b21 100644
--- a/chrome/browser/resources/cryptotoken/cryptotokenapprovedorigins.js
+++ b/chrome/browser/resources/cryptotoken/cryptotokenapprovedorigins.js
@@ -50,7 +50,7 @@
           return;
         }
         var tabOrigin = getOriginFromUrl(tab.url);
-        resolve(tabOrigin == origin);
+        resolve(tabOrigin === origin);
       });
     });
   });
diff --git a/chrome/browser/resources/cryptotoken/cryptotokenbackground.js b/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
index b267ff2e..bb3d4ca 100644
--- a/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
+++ b/chrome/browser/resources/cryptotoken/cryptotokenbackground.js
@@ -73,7 +73,7 @@
   // UI after a timeout races with the error being returned here. Hence, skip
   // the focus check for all timeouts.
   if ((response.responseData &&
-       response.responseData.errorCode == ErrorCodes.TIMEOUT) ||
+       response.responseData.errorCode === ErrorCodes.TIMEOUT) ||
       foregroundAlreadyTested) {
     defaultResponseCallback(request, sendResponse, response);
     return;
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js
index ed75e75..a82f7c0e 100644
--- a/chrome/browser/resources/cryptotoken/enroller.js
+++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -72,12 +72,12 @@
   while (!extensions.empty) {
     const extension = extensions.getASN1(Tag.SEQUENCE);
     const oid = extension.getASN1ObjectIdentifier();
-    if (oid.length != transportTypeOID.length) {
+    if (oid.length !== transportTypeOID.length) {
       continue;
     }
     var matches = true;
     for (var i = 0; i < oid.length; i++) {
-      if (oid[i] != transportTypeOID[i]) {
+      if (oid[i] !== transportTypeOID[i]) {
         matches = false;
         break;
       }
@@ -224,7 +224,7 @@
   constructor(registrationData, appId, challenge, opt_clientData) {
     var data = new ByteString(decodeWebSafeBase64ToArray(registrationData));
     var magic = data.getBytes(1);
-    if (magic[0] != 5) {
+    if (magic[0] !== 5) {
       throw Error('bad magic number');
     }
     /** @private {!Uint8Array} */
@@ -245,7 +245,7 @@
     if (!opt_clientData) {
       // U2F_V1 - deprecated
       challengeHash = decodeWebSafeBase64ToArray(challenge);
-      if (challengeHash.length != 32) {
+      if (challengeHash.length !== 32) {
         throw Error('bad challenge length for U2F_V1');
       }
     } else {
@@ -369,8 +369,8 @@
  */
 function conveyancePreference(enrollChallenge) {
   if (enrollChallenge.hasOwnProperty('attestation') &&
-      (enrollChallenge['attestation'] == 'direct' ||
-       enrollChallenge['attestation'] == 'indirect')) {
+      (enrollChallenge['attestation'] === 'direct' ||
+       enrollChallenge['attestation'] === 'indirect')) {
     return ConveyancePreference.DIRECT;
   }
   return ConveyancePreference.NONE;
@@ -405,7 +405,7 @@
     var isDirect = true;
     var foregroundChecked = false;
 
-    if (conveyancePreference(enrollChallenge) == ConveyancePreference.NONE) {
+    if (conveyancePreference(enrollChallenge) === ConveyancePreference.NONE) {
       isDirect = false;
     } else if (chrome.cryptotokenPrivate != null) {
       // Requesting attestation permission may show a pop-up prompt, which will
@@ -427,7 +427,7 @@
     var decodedRegistrationData =
         new ByteString(decodeWebSafeBase64ToArray(registrationData));
     var magicValue = decodedRegistrationData.getBytes(1);
-    if (magicValue[0] == 4) {
+    if (magicValue[0] === 4) {
       // This is a gNubby with obsolete firmware. We can't parse the reply from
       // this device and users need to be guided to reflashing them. Therefore
       // let attestation data pass directly so that can happen on
@@ -490,7 +490,7 @@
     sendErrorResponse({errorCode: ErrorCodes.TIMEOUT});
   }
 
-  if (sender.origin.indexOf('http://') == 0 && !HTTP_ORIGINS_ALLOWED) {
+  if (sender.origin.indexOf('http://') === 0 && !HTTP_ORIGINS_ALLOWED) {
     sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
     return null;
   }
@@ -585,7 +585,7 @@
       // Version is implicitly V1 if not specified.
       version = 'U2F_V1';
     }
-    if (version != 'U2F_V1' && version != 'U2F_V2') {
+    if (version !== 'U2F_V1' && version !== 'U2F_V2') {
       return false;
     }
     if (seenVersions[version]) {
@@ -615,7 +615,7 @@
  */
 function findEnrollChallengeOfVersion(enrollChallenges, version) {
   for (var i = 0; i < enrollChallenges.length; i++) {
-    if (enrollChallenges[i]['version'] == version) {
+    if (enrollChallenges[i]['version'] === version) {
       return enrollChallenges[i];
     }
   }
@@ -639,7 +639,7 @@
   for (var k in enrollChallenge) {
     responseData[k] = enrollChallenge[k];
   }
-  if (u2fVersion == 'U2F_V2') {
+  if (u2fVersion === 'U2F_V2') {
     // For U2F_V2, the challenge sent to the gnubby is modified to be the
     // hash of the client data. Include the client data.
     responseData['clientData'] = opt_clientData;
@@ -709,8 +709,9 @@
   // Allow http appIds for http origins. (Broken, but the caller deserves
   // what they get.)
   /** @private {boolean} */
-  this.allowHttp_ =
-      this.sender_.origin ? this.sender_.origin.indexOf('http://') == 0 : false;
+  this.allowHttp_ = this.sender_.origin ?
+      this.sender_.origin.indexOf('http://') === 0 :
+      false;
   /** @private {RequestHandler} */
   this.handler_ = null;
 }
@@ -877,7 +878,7 @@
     return;
   }
 
-  if (appId == googleCorpAppId) {
+  if (appId === googleCorpAppId) {
     this.checkU2fApiPermission_(
         appId, encodedChallenge, request,
         WebAuthnAttestationConveyancePreference.ENTERPRISE);
@@ -924,7 +925,7 @@
   crypto.getRandomValues(randomId);
 
   const decodedChallenge = B64_decode(challenge);
-  if (decodedChallenge.length == 0) {
+  if (decodedChallenge.length === 0) {
     this.notifyError_({
       errorCode: ErrorCodes.BAD_REQUEST,
       errorMessage: 'challenge must be base64url encoded',
@@ -936,7 +937,7 @@
   for (let index = 0; index < request['signData'].length; index++) {
     const element = request['signData'][index];
     const decodedKeyHandle = B64_decode(element['keyHandle']);
-    if (decodedKeyHandle.length == 0) {
+    if (decodedKeyHandle.length === 0) {
       this.notifyError_({
         errorCode: ErrorCodes.BAD_REQUEST,
         errorMessage: 'keyHandle must be base64url encoded',
@@ -1167,7 +1168,7 @@
       version = 'U2F_V1';
     }
 
-    if (version == 'U2F_V2') {
+    if (version === 'U2F_V2') {
       var modifiedChallenge = {};
       for (var k in enrollChallenge) {
         modifiedChallenge[k] = enrollChallenge[k];
@@ -1282,7 +1283,7 @@
         'helper reported ' + reply.code.toString(16) + ', returning ' +
         reportedError.errorCode));
     // Log non-expected reply codes if we have url to send them.
-    if (reportedError.errorCode == ErrorCodes.OTHER_ERROR) {
+    if (reportedError.errorCode === ErrorCodes.OTHER_ERROR) {
       var logMsg = 'log=u2fenroll&rc=' + reply.code.toString(16);
       if (this.logMsgUrl_) {
         logMessage(logMsg, this.logMsgUrl_);
@@ -1293,7 +1294,7 @@
     console.log(UTIL_fmt('Gnubby enrollment succeeded!!!!!'));
     var browserData;
 
-    if (reply.version == 'U2F_V2') {
+    if (reply.version === 'U2F_V2') {
       // For U2F_V2, the challenge sent to the gnubby is modified to be the hash
       // of the browser data. Include the browser data.
       browserData = this.browserData_[reply.version];
diff --git a/chrome/browser/resources/cryptotoken/googlecorpindividualattest.js b/chrome/browser/resources/cryptotoken/googlecorpindividualattest.js
index 43420b49..410820d 100644
--- a/chrome/browser/resources/cryptotoken/googlecorpindividualattest.js
+++ b/chrome/browser/resources/cryptotoken/googlecorpindividualattest.js
@@ -22,7 +22,7 @@
  */
 GoogleCorpIndividualAttestation.prototype.requestIndividualAttestation =
     function(appIdHash) {
-  return appIdHash == GoogleCorpIndividualAttestation.GOOGLE_CORP_APP_ID_HASH;
+  return appIdHash === GoogleCorpIndividualAttestation.GOOGLE_CORP_APP_ID_HASH;
 };
 
 /**
diff --git a/chrome/browser/resources/cryptotoken/sha256.js b/chrome/browser/resources/cryptotoken/sha256.js
index e34146a..92b83c9 100644
--- a/chrome/browser/resources/cryptotoken/sha256.js
+++ b/chrome/browser/resources/cryptotoken/sha256.js
@@ -122,7 +122,7 @@
   this._total += opt_length;
   for (var n = 0; n < opt_length; ++n) {
     this._buf[this._inbuf++] = bytes[n];
-    if (this._inbuf == 64) {
+    if (this._inbuf === 64) {
       this._compress(this._buf);
       this._inbuf = 0;
     }
@@ -138,7 +138,7 @@
   this._total += (end - start);
   for (var n = start; n < end; ++n) {
     this._buf[this._inbuf++] = bytes[n];
-    if (this._inbuf == 64) {
+    if (this._inbuf === 64) {
       this._compress(this._buf);
       this._inbuf = 0;
     }
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js
index 5921de98c..e70571e 100644
--- a/chrome/browser/resources/cryptotoken/signer.js
+++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -51,7 +51,7 @@
     sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
     return null;
   }
-  if (sender.origin.indexOf('http://') == 0 && !HTTP_ORIGINS_ALLOWED) {
+  if (sender.origin.indexOf('http://') === 0 && !HTTP_ORIGINS_ALLOWED) {
     sendErrorResponse({errorCode: ErrorCodes.BAD_REQUEST});
     return null;
   }
@@ -326,8 +326,9 @@
   // Allow http appIds for http origins. (Broken, but the caller deserves
   // what they get.)
   /** @private {boolean} */
-  this.allowHttp_ =
-      this.sender_.origin ? this.sender_.origin.indexOf('http://') == 0 : false;
+  this.allowHttp_ = this.sender_.origin ?
+      this.sender_.origin.indexOf('http://') === 0 :
+      false;
   /** @private {RequestHandler} */
   this.handler_ = null;
 }
@@ -478,7 +479,7 @@
   }
 
   const decodedChallenge = B64_decode(challengeVal);
-  if (decodedChallenge.length == 0) {
+  if (decodedChallenge.length === 0) {
     this.notifyError_({
       errorCode: ErrorCodes.BAD_REQUEST,
       errorMessage: 'challenge must be base64url encoded',
@@ -489,7 +490,7 @@
   const credentialList = [];
   for (let i = 0; i < encodedChallenges.length; i++) {
     const decodedKeyHandle = B64_decode(encodedChallenges[i]['keyHandle']);
-    if (decodedKeyHandle.length == 0) {
+    if (decodedKeyHandle.length === 0) {
       this.notifyError_({
         errorCode: ErrorCodes.BAD_REQUEST,
         errorMessage: 'keyHandle must be base64url encoded',
@@ -708,7 +709,7 @@
  * @private
  */
 Signer.prototype.helperComplete_ = function(helperReply, opt_source) {
-  if (helperReply.type != 'sign_helper_reply') {
+  if (helperReply.type !== 'sign_helper_reply') {
     this.notifyError_({errorCode: ErrorCodes.OTHER_ERROR});
     return;
   }
@@ -720,7 +721,7 @@
         'helper reported ' + reply.code.toString(16) + ', returning ' +
         reportedError.errorCode));
     // Log non-expected reply codes if we have an url to send them
-    if ((reportedError.errorCode == ErrorCodes.OTHER_ERROR) &&
+    if ((reportedError.errorCode === ErrorCodes.OTHER_ERROR) &&
         this.logMsgUrl_) {
       logMessage('log=u2fsign&rc=' + reply.code.toString(16), this.logMsgUrl_);
     }
diff --git a/chrome/browser/resources/cryptotoken/textfetcher.js b/chrome/browser/resources/cryptotoken/textfetcher.js
index 471aa22..5695f39 100644
--- a/chrome/browser/resources/cryptotoken/textfetcher.js
+++ b/chrome/browser/resources/cryptotoken/textfetcher.js
@@ -43,7 +43,7 @@
     var method = opt_method || 'GET';
     xhr.open(method, url, true);
     xhr.onloadend = function() {
-      if (xhr.status != 200) {
+      if (xhr.status !== 200) {
         reject(xhr.status);
         return;
       }
diff --git a/chrome/browser/resources/cryptotoken/util.js b/chrome/browser/resources/cryptotoken/util.js
index a0a3a7f0..0b72c5b6 100644
--- a/chrome/browser/resources/cryptotoken/util.js
+++ b/chrome/browser/resources/cryptotoken/util.js
@@ -67,7 +67,7 @@
   var hexchars = '0123456789ABCDEFabcdef';
   var res = new Uint8Array(h.length / 2);
   for (var i = 0; i < h.length; i += 2) {
-    if (hexchars.indexOf(h.substring(i, i + 1)) == -1) {
+    if (hexchars.indexOf(h.substring(i, i + 1)) === -1) {
       break;
     }
     res[i / 2] = parseInt(h.substring(i, i + 2), 16);
@@ -79,7 +79,7 @@
   var hexchars = '0123456789ABCDEFabcdef';
   var res = new Array(h.length / 2);
   for (var i = 0; i < h.length; i += 2) {
-    if (hexchars.indexOf(h.substring(i, i + 1)) == -1) {
+    if (hexchars.indexOf(h.substring(i, i + 1)) === -1) {
       break;
     }
     res[i / 2] = parseInt(h.substring(i, i + 2), 16);
@@ -91,7 +91,7 @@
   if (!a || !b) {
     return false;
   }
-  if (a.length != b.length) {
+  if (a.length !== b.length) {
     return false;
   }
   var accu = 0;
@@ -164,7 +164,7 @@
   var links = head.getElementsByTagName('link');
   for (var i = 0; i < links.length; i++) {
     var link = links[i];
-    if (link.type == faviconLink.type && link.rel == faviconLink.rel) {
+    if (link.type === faviconLink.type && link.rel === faviconLink.rel) {
       head.removeChild(link);
     }
   }
@@ -197,19 +197,19 @@
   if (a.length < 6) {
     return null;
   }  // Too small to be valid
-  if (a[0] != UTIL_ASN_SEQUENCE) {
+  if (a[0] !== UTIL_ASN_SEQUENCE) {
     return null;
   }
   var l = a[1] & 255;
   if (l & 0x80) {
     return null;
   }  // SEQ.size too large
-  if (a.length != 2 + l) {
+  if (a.length !== 2 + l) {
     return null;
   }  // SEQ size does not match input
 
   function parseInt(off) {
-    if (a[off] != UTIL_ASN_INT) {
+    if (a[off] !== UTIL_ASN_INT) {
       return null;
     }
     var l = a[off + 1] & 255;
@@ -273,7 +273,7 @@
 }
 
 function UTIL_prepend_zero(s, n) {
-  if (s.length == n) {
+  if (s.length === n) {
     return s;
   }
   var l = s.length;
diff --git a/chrome/browser/resources/cryptotoken/webrequest.js b/chrome/browser/resources/cryptotoken/webrequest.js
index 1bd2c3d0..8b55cb4 100644
--- a/chrome/browser/resources/cryptotoken/webrequest.js
+++ b/chrome/browser/resources/cryptotoken/webrequest.js
@@ -26,10 +26,10 @@
     return originarray;
   }
   var origin = originarray[0];
-  while (origin.charAt(origin.length - 1) == '/') {
+  while (origin.charAt(origin.length - 1) === '/') {
     origin = origin.substring(0, origin.length - 1);
   }
-  if (origin == 'http:' || origin == 'https:') {
+  if (origin === 'http:' || origin === 'https:') {
     return null;
   }
   return origin;
@@ -50,8 +50,8 @@
     return false;
   }
   if (registeredKey['version']) {
-    if (registeredKey['version'] != 'U2F_V1' &&
-        registeredKey['version'] != 'U2F_V2') {
+    if (registeredKey['version'] !== 'U2F_V1' &&
+        registeredKey['version'] !== 'U2F_V2') {
       return false;
     }
   }
diff --git a/chrome/browser/resources/cryptotoken/webrequestsender.js b/chrome/browser/resources/cryptotoken/webrequestsender.js
index 88b21f75..8ea2d1c6 100644
--- a/chrome/browser/resources/cryptotoken/webrequestsender.js
+++ b/chrome/browser/resources/cryptotoken/webrequestsender.js
@@ -55,7 +55,7 @@
  */
 function tabMatchesOrigin(tab, origin) {
   // If the tab's origin matches, trust that the request came from this tab.
-  if (getOriginFromUrl(tab.url) == origin) {
+  if (getOriginFromUrl(tab.url) === origin) {
     return Promise.resolve(tab.id);
   }
   return Promise.reject(false);
@@ -95,7 +95,7 @@
                     },
                     function() {
                       // Didn't match? Check if the debugger is open.
-                      if (tab.url.indexOf('devtools://') != 0) {
+                      if (tab.url.indexOf('devtools://') !== 0) {
                         reject(false);
                         return;
                       }
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.js b/chrome/browser/resources/device_log_ui/device_log_ui.js
index 730cb20..983dc10c 100644
--- a/chrome/browser/resources/device_log_ui/device_log_ui.js
+++ b/chrome/browser/resources/device_log_ui/device_log_ui.js
@@ -107,7 +107,7 @@
   const container = $('log-container');
   try {
     createEventLog(JSON.parse(data));
-    if (container.textContent == '') {
+    if (container.textContent === '') {
       container.textContent = loadTimeData.getString('logNoEntriesText');
     }
   } catch (e) {
diff --git a/chrome/browser/resources/downloads/downloads.html b/chrome/browser/resources/downloads/downloads.html
index e46eff0..e8569f4f 100644
--- a/chrome/browser/resources/downloads/downloads.html
+++ b/chrome/browser/resources/downloads/downloads.html
@@ -9,11 +9,16 @@
   <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
   <style>
     html {
-      background: var(--md-background-color);
       /* Remove 300ms delay for 'click' event, when using touch interface. */
       touch-action: manipulation;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     html.loading::before {
       background-color: var(--md-toolbar-color);
       border-bottom: var(--md-toolbar-border);
diff --git a/chrome/browser/resources/engagement/site_engagement.js b/chrome/browser/resources/engagement/site_engagement.js
index 67bd7308..837d4af3 100644
--- a/chrome/browser/resources/engagement/site_engagement.js
+++ b/chrome/browser/resources/engagement/site_engagement.js
@@ -37,7 +37,7 @@
   for (let i = 0; i < headers.length; i++) {
     headers[i].addEventListener('click', (e) => {
       const newSortKey = e.target.getAttribute('sort-key');
-      if (sortKey == newSortKey) {
+      if (sortKey === newSortKey) {
         sortReverse = !sortReverse;
       } else {
         sortKey = newSortKey;
@@ -158,12 +158,12 @@
     const val2 = b[sortKey];
 
     // Compare the hosts of the origin ignoring schemes.
-    if (sortKey == 'origin') {
+    if (sortKey === 'origin') {
       return new URL(val1.url).host > new URL(val2.url).host ? 1 : -1;
     }
 
-    if (sortKey == 'baseScore' || sortKey == 'bonusScore' ||
-        sortKey == 'totalScore') {
+    if (sortKey === 'baseScore' || sortKey === 'bonusScore' ||
+        sortKey === 'totalScore') {
       return val1 - val2;
     }
 
diff --git a/chrome/browser/resources/extensions/extensions.html b/chrome/browser/resources/extensions/extensions.html
index ecc17a8..18c12cb 100644
--- a/chrome/browser/resources/extensions/extensions.html
+++ b/chrome/browser/resources/extensions/extensions.html
@@ -9,11 +9,16 @@
   <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
   <style>
     html {
-      background: var(--md-background-color);
       /* Remove 300ms delay for 'click' event, when using touch interface. */
       touch-action: manipulation;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     html.loading::before,
     html.loading body::before {
       box-sizing: border-box;
diff --git a/chrome/browser/resources/family_link_user_internals/family_link_user_internals.js b/chrome/browser/resources/family_link_user_internals/family_link_user_internals.js
index 09ed05d..27bb5ecc 100644
--- a/chrome/browser/resources/family_link_user_internals/family_link_user_internals.js
+++ b/chrome/browser/resources/family_link_user_internals/family_link_user_internals.js
@@ -40,7 +40,7 @@
 
   const oldStr = oldVal.toString();
   const newStr = newVal.toString();
-  if (oldStr != '' && oldStr != newStr) {
+  if (oldStr !== '' && oldStr !== newStr) {
     // Note the addListener function does not end up creating duplicate
     // listeners.  There can be only one listener per event at a time.
     // See https://developer.mozilla.org/en/DOM/element.addEventListener
@@ -83,7 +83,7 @@
  * @return {boolean} true if the element is scrolled to the bottom
  */
 function isScrolledToBottom(elem) {
-  return elem.scrollHeight - elem.scrollTop == elem.clientHeight;
+  return elem.scrollHeight - elem.scrollTop === elem.clientHeight;
 }
 
 /**
diff --git a/chrome/browser/resources/feed_internals/feed_internals.js b/chrome/browser/resources/feed_internals/feed_internals.js
index 7d393aa9..cbff9da 100644
--- a/chrome/browser/resources/feed_internals/feed_internals.js
+++ b/chrome/browser/resources/feed_internals/feed_internals.js
@@ -132,7 +132,7 @@
 
   $('feed-stream-data-override').addEventListener('click', function() {
     const file = $('feed-stream-data-file').files[0];
-    if (file && typeof pageHandler.overrideFeedStreamData == 'function') {
+    if (file && typeof pageHandler.overrideFeedStreamData === 'function') {
       const reader = new FileReader();
       reader.readAsArrayBuffer(file);
       reader.onload = function(e) {
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js
index 2032cc2e..987c83b 100644
--- a/chrome/browser/resources/feedback/js/event_handler.js
+++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -181,12 +181,12 @@
     /** @const */ const FLOW = this.feedbackInfo_.flow;
     chrome.feedbackPrivate.sendFeedback(
         this.feedbackInfo_, function(result, landingPageType) {
-          if (result == chrome.feedbackPrivate.Status.SUCCESS) {
+          if (result === chrome.feedbackPrivate.Status.SUCCESS) {
             console.log('Feedback: Report sent for request with ID ' + ID);
-            if (FLOW != chrome.feedbackPrivate.FeedbackFlow.LOGIN &&
-                landingPageType !=
+            if (FLOW !== chrome.feedbackPrivate.FeedbackFlow.LOGIN &&
+                landingPageType !==
                     chrome.feedbackPrivate.LandingPageType.NO_LANDING_PAGE) {
-              const landingPage = landingPageType ==
+              const landingPage = landingPageType ===
                       chrome.feedbackPrivate.LandingPageType.NORMAL ?
                   FEEDBACK_LANDING_PAGE :
                   FEEDBACK_LANDING_PAGE_TECHSTOP;
@@ -197,7 +197,7 @@
                 'Feedback: Report for request with ID ' + ID +
                 ' will be sent later.');
           }
-          if (FLOW == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+          if (FLOW === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
             chrome.feedbackPrivate.loginFeedbackComplete();
           }
         });
@@ -210,7 +210,7 @@
   onWindowClosed() {
     if (!this.reportIsBeingSent_) {
       this.isRequestCanceled_ = true;
-      if (this.feedbackInfo_.flow ==
+      if (this.feedbackInfo_.flow ===
           chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
         chrome.feedbackPrivate.loginFeedbackComplete();
       }
@@ -246,7 +246,7 @@
           hashString += n < 0x10 ? '0' : '';
           hashString += n.toString(16);
         }
-        if (feedbackCallerExtensions.indexOf(hashString.toUpperCase()) != -1) {
+        if (feedbackCallerExtensions.indexOf(hashString.toUpperCase()) !== -1) {
           startFeedbackCallback(feedbackInfo);
         }
       });
diff --git a/chrome/browser/resources/feedback/js/feedback.js b/chrome/browser/resources/feedback/js/feedback.js
index f2305e6..f1d8f57b 100644
--- a/chrome/browser/resources/feedback/js/feedback.js
+++ b/chrome/browser/resources/feedback/js/feedback.js
@@ -311,7 +311,7 @@
  * @return {boolean} True if the report was sent.
  */
 function sendReport() {
-  if ($('description-text').value.length == 0) {
+  if ($('description-text').value.length === 0) {
     updateDescription(false);
     return false;
   }
@@ -397,7 +397,7 @@
 function cancel(e) {
   e.preventDefault();
   scheduleWindowClose();
-  if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+  if (feedbackInfo.flow === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
     chrome.feedbackPrivate.loginFeedbackComplete();
   }
 }
@@ -439,7 +439,7 @@
                    .reduce((acc, el) => acc + el.scrollHeight, 0);
 
   let minHeight = FEEDBACK_MIN_HEIGHT;
-  if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+  if (feedbackInfo.flow === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
     minHeight = FEEDBACK_MIN_HEIGHT_LOGIN;
   }
   height = Math.max(height, minHeight);
@@ -493,7 +493,7 @@
 
       if (feedbackInfo.includeBluetoothLogs) {
         assert(
-            feedbackInfo.flow ==
+            feedbackInfo.flow ===
             chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL);
         $('description-text')
             .addEventListener('input', checkForSendBluetoothLogs);
@@ -501,14 +501,14 @@
 
       if (feedbackInfo.showQuestionnaire) {
         assert(
-            feedbackInfo.flow ==
+            feedbackInfo.flow ===
             chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL);
         $('description-text')
             .addEventListener('input', checkForShowQuestionnaire);
       }
 
       if ($('assistant-checkbox-container') != null &&
-          feedbackInfo.flow ==
+          feedbackInfo.flow ===
               chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL &&
           feedbackInfo.fromAssistant) {
         $('assistant-checkbox-container').hidden = false;
@@ -582,7 +582,7 @@
 
       // No URL, file attachment, or window minimizing for login screen
       // feedback.
-      if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+      if (feedbackInfo.flow === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
         $('page-url').hidden = true;
         $('attach-file-container').hidden = true;
         $('attach-file-note').hidden = true;
@@ -657,7 +657,7 @@
 
         // The following URLs don't open on login screen, so hide them.
         // TODO(crbug.com/1116383): Find a solution to display them properly.
-        if (feedbackInfo.flow != chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+        if (feedbackInfo.flow !== chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
           const legalHelpPageUrlElement = $('legal-help-page-url');
           if (legalHelpPageUrlElement) {
             setupLinkHandlers(
diff --git a/chrome/browser/resources/feedback/js/sys_info.js b/chrome/browser/resources/feedback/js/sys_info.js
index f3d7eaf..20b28af 100644
--- a/chrome/browser/resources/feedback/js/sys_info.js
+++ b/chrome/browser/resources/feedback/js/sys_info.js
@@ -70,7 +70,7 @@
  */
 function changeCollapsedStatus() {
   const valueDiv = getValueDivForButton(this);
-  if (valueDiv.parentNode.className == 'number-collapsed') {
+  if (valueDiv.parentNode.className === 'number-collapsed') {
     expand(this, valueDiv, 1);
   } else {
     collapse(this, valueDiv);
@@ -83,7 +83,7 @@
 function collapseAll() {
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; ++i) {
-    if (valueDivs[i].parentNode.className != 'number-expanded') {
+    if (valueDivs[i].parentNode.className !== 'number-expanded') {
       continue;
     }
     const button = getButtonForValueDiv(valueDivs[i]);
@@ -99,7 +99,7 @@
 function expandAll() {
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; ++i) {
-    if (valueDivs[i].parentNode.className != 'number-collapsed') {
+    if (valueDivs[i].parentNode.className !== 'number-collapsed') {
       continue;
     }
     const button = getButtonForValueDiv(valueDivs[i]);
diff --git a/chrome/browser/resources/feedback_webui/js/feedback.js b/chrome/browser/resources/feedback_webui/js/feedback.js
index 997a865..bc65434 100644
--- a/chrome/browser/resources/feedback_webui/js/feedback.js
+++ b/chrome/browser/resources/feedback_webui/js/feedback.js
@@ -65,11 +65,11 @@
     chrome.feedbackPrivate.sendFeedback(
         feedbackInfo, useSystemInfo, formOpenTime,
         function(result, landingPageType) {
-          if (result == chrome.feedbackPrivate.Status.SUCCESS) {
-            if (FLOW != chrome.feedbackPrivate.FeedbackFlow.LOGIN &&
-                landingPageType !=
+          if (result === chrome.feedbackPrivate.Status.SUCCESS) {
+            if (FLOW !== chrome.feedbackPrivate.FeedbackFlow.LOGIN &&
+                landingPageType !==
                     chrome.feedbackPrivate.LandingPageType.NO_LANDING_PAGE) {
-              const landingPage = landingPageType ==
+              const landingPage = landingPageType ===
                       chrome.feedbackPrivate.LandingPageType.NORMAL ?
                   FEEDBACK_LANDING_PAGE :
                   FEEDBACK_LANDING_PAGE_TECHSTOP;
@@ -80,7 +80,7 @@
                 'Feedback: Report for request with ID ' + ID +
                 ' will be sent later.');
           }
-          if (FLOW == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+          if (FLOW === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
             chrome.feedbackPrivate.loginFeedbackComplete();
           }
           scheduleWindowClose();
@@ -425,7 +425,7 @@
  * @return {boolean} True if the report was sent.
  */
 function sendReport() {
-  if ($('description-text').value.length == 0) {
+  if ($('description-text').value.length === 0) {
     updateDescription(false);
     return false;
   }
@@ -508,7 +508,7 @@
 function cancel(e) {
   e.preventDefault();
   scheduleWindowClose();
-  if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+  if (feedbackInfo.flow === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
     chrome.feedbackPrivate.loginFeedbackComplete();
   }
 }
@@ -562,7 +562,7 @@
   const applyData = function(feedbackInfo) {
     if (feedbackInfo.includeBluetoothLogs) {
       assert(
-          feedbackInfo.flow ==
+          feedbackInfo.flow ===
           chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL);
       $('description-text')
           .addEventListener('input', checkForSendBluetoothLogs);
@@ -570,14 +570,14 @@
 
     if (feedbackInfo.showQuestionnaire) {
       assert(
-          feedbackInfo.flow ==
+          feedbackInfo.flow ===
           chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL);
       $('description-text')
           .addEventListener('input', checkForShowQuestionnaire);
     }
 
     if ($('assistant-checkbox-container') != null &&
-        feedbackInfo.flow ==
+        feedbackInfo.flow ===
             chrome.feedbackPrivate.FeedbackFlow.GOOGLE_INTERNAL &&
         feedbackInfo.fromAssistant) {
       $('assistant-checkbox-container').hidden = false;
@@ -646,7 +646,7 @@
     }
 
     // No URL, file attachment for login screen feedback.
-    if (feedbackInfo.flow == chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+    if (feedbackInfo.flow === chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
       $('page-url').hidden = true;
       $('attach-file-container').hidden = true;
       $('attach-file-note').hidden = true;
@@ -693,7 +693,7 @@
     // TODO(crbug.com/1116383): Find a solution to display them properly.
     // Update: the bluetooth and assistant logs links will work on login
     // screen now. But to limit the scope of this CL, they are still hidden.
-    if (feedbackInfo.flow != chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
+    if (feedbackInfo.flow !== chrome.feedbackPrivate.FeedbackFlow.LOGIN) {
       const legalHelpPageUrlElement = $('legal-help-page-url');
       if (legalHelpPageUrlElement) {
         setupLinkHandlers(
diff --git a/chrome/browser/resources/feedback_webui/js/sys_info.js b/chrome/browser/resources/feedback_webui/js/sys_info.js
index 0f1010d..82c4808 100644
--- a/chrome/browser/resources/feedback_webui/js/sys_info.js
+++ b/chrome/browser/resources/feedback_webui/js/sys_info.js
@@ -74,7 +74,7 @@
  */
 function changeCollapsedStatus() {
   const valueDiv = getValueDivForButton(this);
-  if (valueDiv.parentNode.className == 'number-collapsed') {
+  if (valueDiv.parentNode.className === 'number-collapsed') {
     expand(this, valueDiv, 1);
   } else {
     collapse(this, valueDiv);
@@ -87,7 +87,7 @@
 function collapseAll() {
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; ++i) {
-    if (valueDivs[i].parentNode.className != 'number-expanded') {
+    if (valueDivs[i].parentNode.className !== 'number-expanded') {
       continue;
     }
     const button = getButtonForValueDiv(valueDivs[i]);
@@ -103,7 +103,7 @@
 function expandAll() {
   const valueDivs = document.getElementsByClassName('stat-value');
   for (let i = 0; i < valueDivs.length; ++i) {
-    if (valueDivs[i].parentNode.className != 'number-collapsed') {
+    if (valueDivs[i].parentNode.className !== 'number-collapsed') {
       continue;
     }
     const button = getButtonForValueDiv(valueDivs[i]);
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js
index aa198a5..ebf80ca0 100644
--- a/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -248,7 +248,7 @@
   const messageHandlers = {
     'attemptLogin'(msg) {
       this.email_ = msg.email;
-      if (this.authMode == AuthMode.DESKTOP) {
+      if (this.authMode === AuthMode.DESKTOP) {
         this.password_ = msg.password;
       }
       this.isSamlUserPasswordless_ = null;
@@ -284,7 +284,7 @@
     'userInfo'(msg) {
       this.services_ = msg.services;
       if (!this.authCompletedFired_) {
-        const metric = this.authFlow == AuthFlow.SAML ?
+        const metric = this.authFlow === AuthFlow.SAML ?
             GAIA_MESSAGE_SAML_USER_INFO :
             GAIA_MESSAGE_GAIA_USER_INFO;
         chrome.send('metricsHandler:recordBooleanHistogram', [metric, true]);
@@ -356,7 +356,7 @@
       }
 
       if (!this.authCompletedFired_) {
-        const metric = this.authFlow == AuthFlow.SAML ?
+        const metric = this.authFlow === AuthFlow.SAML ?
             GAIA_MESSAGE_SAML_CLOSE_VIEW :
             GAIA_MESSAGE_GAIA_CLOSE_VIEW;
         chrome.send('metricsHandler:recordBooleanHistogram', [metric, true]);
@@ -417,7 +417,7 @@
       /**
        * @private {WebView|undefined}
        */
-      this.webview_ = typeof webview == 'string' ?
+      this.webview_ = typeof webview === 'string' ?
           /** @type {WebView} */ ($(webview)) :
           webview;
       assert(this.webview_);
@@ -468,7 +468,7 @@
        * @type {boolean}
        * @private
        */
-      this.isDomLoaded_ = document.readyState != 'loading';
+      this.isDomLoaded_ = document.readyState !== 'loading';
       if (this.isDomLoaded_) {
         this.initializeAfterDomLoaded_();
       } else {
@@ -505,7 +505,7 @@
      * Resets the webview to the blank page.
      */
     resetWebview() {
-      if (this.webview_.src && this.webview_.src != BLANK_PAGE_URL) {
+      if (this.webview_.src && this.webview_.src !== BLANK_PAGE_URL) {
         this.webview_.src = BLANK_PAGE_URL;
       }
     }
@@ -629,7 +629,7 @@
         // We have not navigated anywhere yet. Note that a webview's src
         // attribute does not allow a change back to "".
         this.webview_.partition = newWebviewPartitionName;
-      } else if (this.webview_.partition != newWebviewPartitionName) {
+      } else if (this.webview_.partition !== newWebviewPartitionName) {
         // The webview has already navigated. We have to re-create it.
         const webivewParent = this.webview_.parentElement;
 
@@ -658,7 +658,7 @@
       // gaiaUrl parameter is used for testing. Once defined, it is never
       // changed.
       this.idpOrigin_ = data.gaiaUrl || IDP_ORIGIN;
-      this.isConstrainedWindow_ = data.constrained == '1';
+      this.isConstrainedWindow_ = data.constrained === '1';
       this.clientId_ = data.clientId;
       this.dontResizeNonEmbeddedPages = data.dontResizeNonEmbeddedPages;
       this.enableGaiaActionButtons_ = data.enableGaiaActionButtons;
@@ -678,7 +678,7 @@
       }
       // Don't block insecure content for desktop flow because it lands on
       // http. Otherwise, block insecure content as long as gaia is https.
-      this.samlHandler_.blockInsecureContent = authMode != AuthMode.DESKTOP &&
+      this.samlHandler_.blockInsecureContent = authMode !== AuthMode.DESKTOP &&
           this.idpOrigin_.startsWith('https://');
       this.samlHandler_.extractSamlPasswordAttributes =
           data.extractSamlPasswordAttributes;
@@ -843,10 +843,10 @@
 
       if (this.isConstrainedWindow_) {
         let isEmbeddedPage = false;
-        if (this.idpOrigin_ && currentUrl.lastIndexOf(this.idpOrigin_) == 0) {
+        if (this.idpOrigin_ && currentUrl.lastIndexOf(this.idpOrigin_) === 0) {
           const headers = details.responseHeaders;
           for (let i = 0; headers && i < headers.length; ++i) {
-            if (headers[i].name.toLowerCase() == EMBEDDED_FORM_HEADER) {
+            if (headers[i].name.toLowerCase() === EMBEDDED_FORM_HEADER) {
               isEmbeddedPage = true;
               break;
             }
@@ -873,7 +873,7 @@
      * @private
      */
     updateHistoryState_(url) {
-      if (history.state && history.state.url != url) {
+      if (history.state && history.state.url !== url) {
         history.pushState({url: url}, '');
       } else {
         history.replaceState({url: url}, '');
@@ -885,8 +885,8 @@
      * @private
      */
     onFocus_() {
-      if (this.authMode == AuthMode.DESKTOP &&
-          document.activeElement == document.body) {
+      if (this.authMode === AuthMode.DESKTOP &&
+          document.activeElement === document.body) {
         this.webview_.focus();
       }
     }
@@ -919,7 +919,7 @@
         return;
       }
       const currentUrl = details.url;
-      if (currentUrl.lastIndexOf(this.idpOrigin_, 0) != 0) {
+      if (currentUrl.lastIndexOf(this.idpOrigin_, 0) !== 0) {
         return;
       }
 
@@ -927,7 +927,7 @@
       for (let i = 0; headers && i < headers.length; ++i) {
         const header = headers[i];
         const headerName = header.name.toLowerCase();
-        if (headerName == SIGN_IN_HEADER) {
+        if (headerName === SIGN_IN_HEADER) {
           const headerValues = header.value.toLowerCase().split(',');
           const signinDetails = {};
           headerValues.forEach(function(e) {
@@ -939,7 +939,7 @@
           this.gaiaId_ = signinDetails['obfuscatedid'].slice(1, -1);
           this.sessionIndex_ = signinDetails['sessionindex'];
           this.isSamlUserPasswordless_ = null;
-        } else if (headerName == LOCATION_HEADER) {
+        } else if (headerName === LOCATION_HEADER) {
           // If the "choose what to sync" checkbox was clicked, then the
           // continue URL will contain a source=3 field.
           assert(header.value !== undefined);
@@ -959,13 +959,13 @@
       }
 
       // The event origin does not have a trailing slash.
-      if (e.origin !=
+      if (e.origin !==
           this.idpOrigin_.substring(0, this.idpOrigin_.length - 1)) {
         return false;
       }
 
       // Gaia messages must be an object with 'method' property.
-      if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
+      if (typeof e.data !== 'object' || !e.data.hasOwnProperty('method')) {
         return false;
       }
       return true;
@@ -980,7 +980,7 @@
         return false;
       }
 
-      if (typeof e.data != 'object' || !e.data.hasOwnProperty('method')) {
+      if (typeof e.data !== 'object' || !e.data.hasOwnProperty('method')) {
         return false;
       }
 
@@ -1093,7 +1093,7 @@
       }
 
       if (this.isSamlUserPasswordless_ === null &&
-          this.authFlow == AuthFlow.SAML && this.email_ && this.gaiaId_ &&
+          this.authFlow === AuthFlow.SAML && this.email_ && this.gaiaId_ &&
           this.getIsSamlUserPasswordlessCallback) {
         // Start a request to obtain the |isSamlUserPasswordless_| value for
         // the current user. Once the response arrives, maybeCompleteAuth_()
@@ -1105,13 +1105,13 @@
         return;
       }
 
-      if (this.recordSAMLProviderCallback && this.authFlow == AuthFlow.SAML) {
+      if (this.recordSAMLProviderCallback && this.authFlow === AuthFlow.SAML) {
         // Makes distinction between different SAML providers
         this.recordSAMLProviderCallback(
             this.samlHandler_.x509certificate || '');
       }
 
-      if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML &&
+      if (this.isSamlUserPasswordless_ && this.authFlow === AuthFlow.SAML &&
           this.email_ && this.gaiaId_) {
         // No password needed for this user, so complete immediately.
         this.onAuthCompleted_();
@@ -1122,14 +1122,14 @@
         if (this.samlApiUsedCallback) {
           // Makes distinction between Gaia and Chrome Credentials Passing API
           // login to properly fill ChromeOS.SAML.ApiLogin metrics.
-          this.samlApiUsedCallback(this.authFlow == AuthFlow.SAML);
+          this.samlApiUsedCallback(this.authFlow === AuthFlow.SAML);
         }
         this.password_ = this.samlHandler_.apiPasswordBytes;
         this.onAuthCompleted_();
         return;
       }
 
-      if (this.samlHandler_.scrapedPasswordCount == 0) {
+      if (this.samlHandler_.scrapedPasswordCount === 0) {
         if (this.noPasswordCallback) {
           this.noPasswordCallback(this.email_);
           return;
@@ -1140,7 +1140,7 @@
         // password when it is available but not a mandatory requirement.
         console.warn('Authenticator: No password scraped for SAML.');
       } else if (this.needPassword) {
-        if (this.samlHandler_.scrapedPasswordCount == 1) {
+        if (this.samlHandler_.scrapedPasswordCount === 1) {
           // If we scraped exactly one password, we complete the
           // authentication right away.
           this.password_ = this.samlHandler_.firstScrapedPassword;
@@ -1183,8 +1183,8 @@
     onGotIsSamlUserPasswordless_(email, gaiaId, isSamlUserPasswordless) {
       // Compare the request's user identifier with the currently set one, in
       // order to ignore responses to old requests.
-      if (this.email_ && this.email_ == email && this.gaiaId_ &&
-          this.gaiaId_ == gaiaId) {
+      if (this.email_ && this.email_ === email && this.gaiaId_ &&
+          this.gaiaId_ === gaiaId) {
         this.isSamlUserPasswordless_ = isSamlUserPasswordless;
         this.maybeCompleteAuth_();
       }
@@ -1208,7 +1208,7 @@
      */
     assertStringDict_(dict, nameOfDict) {
       console.assert(
-          typeof dict == 'object', 'FATAL: Bad %s type: %s', nameOfDict,
+          typeof dict === 'object', 'FATAL: Bad %s type: %s', nameOfDict,
           typeof dict);
       for (const key in dict) {
         this.assertStringElement_(dict[key], nameOfDict, key);
@@ -1218,7 +1218,7 @@
     /** Asserts an element |elem| in a certain collection is a string. */
     assertStringElement_(elem, nameOfCollection, index) {
       console.assert(
-          typeof elem == 'string', 'FATAL: Bad %s[%s] type: %s',
+          typeof elem === 'string', 'FATAL: Bad %s[%s] type: %s',
           nameOfCollection, index, typeof elem);
     }
 
@@ -1235,7 +1235,7 @@
       if (this.services_) {
         this.assertStringArray_(this.services_, 'services');
       }
-      if (this.isSamlUserPasswordless_ && this.authFlow == AuthFlow.SAML &&
+      if (this.isSamlUserPasswordless_ && this.authFlow === AuthFlow.SAML &&
           this.email_) {
         // In the passwordless case, the user data will be protected by non
         // password based mechanisms. Clear anything that got collected into
@@ -1243,7 +1243,7 @@
         this.password_ = '';
       }
       let passwordAttributes = {};
-      if (this.authFlow == AuthFlow.SAML &&
+      if (this.authFlow === AuthFlow.SAML &&
           this.samlHandler_.extractSamlPasswordAttributes &&
           !this.isSamlUserPasswordless_) {
         passwordAttributes = this.samlHandler_.passwordAttributes;
@@ -1257,7 +1257,7 @@
               email: this.email_ || '',
               gaiaId: this.gaiaId_ || '',
               password: this.password_ || '',
-              usingSAML: this.authFlow == AuthFlow.SAML,
+              usingSAML: this.authFlow === AuthFlow.SAML,
               publicSAML: this.samlAclUrl_ || false,
               chooseWhatToSync: this.chooseWhatToSync_,
               skipForNow: this.skipForNow_,
@@ -1371,7 +1371,7 @@
 
       // Posts a message to IdP pages to initiate communication.
       const currentUrl = this.webview_.src;
-      if (currentUrl.lastIndexOf(this.idpOrigin_) == 0) {
+      if (currentUrl.lastIndexOf(this.idpOrigin_) === 0) {
         const msg = {
           'method': 'handshake',
         };
@@ -1388,9 +1388,9 @@
         // Focus webview after dispatching event when webview is already
         // visible.
         this.webview_.focus();
-      } else if (currentUrl == BLANK_PAGE_URL) {
+      } else if (currentUrl === BLANK_PAGE_URL) {
         this.fireReadyEvent_();
-      } else if (currentUrl == this.samlAclUrl_) {
+      } else if (currentUrl === this.samlAclUrl_) {
         this.skipForNow_ = true;
         this.onAuthCompleted_();
       }
@@ -1450,7 +1450,7 @@
       if (!this.services_) {
         console.error('Gaia done timeout: Forcing empty services.');
         this.services_ = [];
-        const metric = this.authFlow == AuthFlow.SAML ?
+        const metric = this.authFlow === AuthFlow.SAML ?
             GAIA_MESSAGE_SAML_USER_INFO :
             GAIA_MESSAGE_GAIA_USER_INFO;
         chrome.send('metricsHandler:recordBooleanHistogram', [metric, false]);
@@ -1460,7 +1460,7 @@
         console.error('Gaia done timeout: closeView was not called.');
         this.closeViewReceived_ = true;
 
-        const metric = this.authFlow == AuthFlow.SAML ?
+        const metric = this.authFlow === AuthFlow.SAML ?
             GAIA_MESSAGE_SAML_CLOSE_VIEW :
             GAIA_MESSAGE_GAIA_CLOSE_VIEW;
         chrome.send('metricsHandler:recordBooleanHistogram', [metric, false]);
diff --git a/chrome/browser/resources/gaia_auth_host/channel.js b/chrome/browser/resources/gaia_auth_host/channel.js
index 50fc5377..c1c395eb 100644
--- a/chrome/browser/resources/gaia_auth_host/channel.js
+++ b/chrome/browser/resources/gaia_auth_host/channel.js
@@ -95,7 +95,7 @@
    */
   onMessage_(msg) {
     const name = msg.name;
-    if (name == Channel.INTERNAL_REQUEST_MESSAGE) {
+    if (name === Channel.INTERNAL_REQUEST_MESSAGE) {
       const payload = msg.payload;
       const result = this.invokeMessageCallbacks_(payload);
       this.send({
@@ -103,7 +103,7 @@
         requestId: msg.requestId,
         result: result
       });
-    } else if (name == Channel.INTERNAL_REPLY_MESSAGE) {
+    } else if (name === Channel.INTERNAL_REPLY_MESSAGE) {
       const callback = this.internalRequestCallbacks_[msg.requestId];
       delete this.internalRequestCallbacks_[msg.requestId];
       if (callback) {
diff --git a/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js b/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js
index d2b13e7..3ce1d1d 100644
--- a/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js
+++ b/chrome/browser/resources/gaia_auth_host/okta_detect_success_injected.js
@@ -12,7 +12,7 @@
 
   let messageFromParent;
   function onMessageReceived(event) {
-    if (event.origin == PARENT_ORIGIN) {
+    if (event.origin === PARENT_ORIGIN) {
       messageFromParent = event;
     }
   }
diff --git a/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js b/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
index 286b664..c73420848 100644
--- a/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
+++ b/chrome/browser/resources/gaia_auth_host/password_change_authenticator.js
@@ -114,19 +114,19 @@
     // that an otherwise unsupported IdP can also send it as a success message.
     // TODO(https://crbug.com/930109): Consider removing this entirely, or,
     // using a more self-documenting parameter like 'passwordChanged=1'.
-    if (redirectUrl.searchParams.get('status') == '0') {
+    if (redirectUrl.searchParams.get('status') === '0') {
       return true;
     }
 
     const pageProvider = detectProvider_(postUrl);
     // These heuristics work for the following SAML IdPs:
-    if (pageProvider == PasswordChangePageProvider.ADFS) {
-      return redirectUrl.searchParams.get('status') == '0';
+    if (pageProvider === PasswordChangePageProvider.ADFS) {
+      return redirectUrl.searchParams.get('status') === '0';
     }
-    if (pageProvider == PasswordChangePageProvider.AZURE) {
-      return redirectUrl.searchParams.get('ReturnCode') == '0';
+    if (pageProvider === PasswordChangePageProvider.AZURE) {
+      return redirectUrl.searchParams.get('ReturnCode') === '0';
     }
-    if (pageProvider == PasswordChangePageProvider.PING) {
+    if (pageProvider === PasswordChangePageProvider.PING) {
       // The returnurl is always preserved until password change succeeds - then
       // it is no longer needed.
       return (!!postUrl.searchParams.get('returnurl') &&
@@ -171,7 +171,7 @@
      * Resets the webview to the blank page.
      */
     resetWebview() {
-      if (this.webview_.src && this.webview_.src != BLANK_PAGE_URL) {
+      if (this.webview_.src && this.webview_.src !== BLANK_PAGE_URL) {
         this.webview_.src = BLANK_PAGE_URL;
       }
     }
@@ -186,7 +186,7 @@
       assert(!this.webview_);
       assert(!this.samlHandler_);
 
-      this.webview_ = typeof webview == 'string' ? $(webview) : webview;
+      this.webview_ = typeof webview === 'string' ? $(webview) : webview;
 
       this.samlHandler_ =
           new cr.login.SamlHandler(this.webview_, true /* startsOnSamlPage */);
@@ -296,7 +296,7 @@
         const verifyPasswords =
             this.samlHandler_.getPasswordsWithPropertyScrapedTimes(
                 1, 'verifyPassword');
-        if (newPasswords.length == 1 && verifyPasswords.length == 1 &&
+        if (newPasswords.length === 1 && verifyPasswords.length === 1 &&
             newPasswords[0] === verifyPasswords[0]) {
           passwordsTwice = Array.from(newPasswords);
         } else {
@@ -332,7 +332,7 @@
      * @private
      */
     onBeforeRedirect_(details) {
-      if (details.method == 'POST') {
+      if (details.method === 'POST') {
         const message = {
           name: 'detectPasswordChangeSuccess',
           url: details.url,
@@ -379,7 +379,7 @@
      * @private
      */
     onMessageReceived_(event) {
-      if (event.data == 'passwordChangeSuccess') {
+      if (event.data === 'passwordChangeSuccess') {
         const message = {name: 'detectProvider', url: event.origin};
         sendMessage_(extensionId, message, (provider) => {
           // SAML change password extension will be used to detect provider
@@ -387,9 +387,9 @@
           // 'provider' will be equal to undefined in case
           // extension isn't installed or disabled, In this case normal flow
           // will be used.
-          if (provider == PasswordChangePageProvider.OKTA ||
+          if (provider === PasswordChangePageProvider.OKTA ||
               (typeof provider === 'undefined' &&
-               detectProvider_(safeParseUrl_(event.origin)) ==
+               detectProvider_(safeParseUrl_(event.origin)) ===
                    PasswordChangePageProvider.OKTA)) {
             this.onPasswordChangeSuccess_(true /* isOkta */);
           }
diff --git a/chrome/browser/resources/gaia_auth_host/post_message_channel.js b/chrome/browser/resources/gaia_auth_host/post_message_channel.js
index c8bbd4a..7c31171 100644
--- a/chrome/browser/resources/gaia_auth_host/post_message_channel.js
+++ b/chrome/browser/resources/gaia_auth_host/post_message_channel.js
@@ -222,7 +222,7 @@
      * Window 'message' handler.
      */
     onMessage_(e) {
-      if (typeof e.data != 'object' || !e.data.hasOwnProperty('type')) {
+      if (typeof e.data !== 'object' || !e.data.hasOwnProperty('type')) {
         return;
       }
 
@@ -249,7 +249,7 @@
           this.postToUpperWindow(e.data);
         }
       } else if (e.data.type === CHANNEL_INIT_MESSAGE) {
-        if (ALLOWED_ORIGINS.indexOf(e.origin) == -1) {
+        if (ALLOWED_ORIGINS.indexOf(e.origin) === -1) {
           return;
         }
 
diff --git a/chrome/browser/resources/gaia_auth_host/saml_handler.js b/chrome/browser/resources/gaia_auth_host/saml_handler.js
index 26799eec..d59b43b 100644
--- a/chrome/browser/resources/gaia_auth_host/saml_handler.js
+++ b/chrome/browser/resources/gaia_auth_host/saml_handler.js
@@ -333,8 +333,8 @@
      */
     get apiPasswordBytes() {
       if (this.confirmToken_ != null &&
-          typeof (this.apiTokenStore_[this.confirmToken_]) == 'object' &&
-          typeof (this.apiTokenStore_[this.confirmToken_]['passwordBytes']) ==
+          typeof (this.apiTokenStore_[this.confirmToken_]) === 'object' &&
+          typeof (this.apiTokenStore_[this.confirmToken_]['passwordBytes']) ===
               'string') {
         return this.apiTokenStore_[this.confirmToken_]['passwordBytes'];
       }
@@ -372,7 +372,7 @@
         const key = this.passwordStore_[property];
         passwords[key] = (passwords[key] + 1) || 1;
       }
-      return Object.keys(passwords).filter(key => passwords[key] == times);
+      return Object.keys(passwords).filter(key => passwords[key] === times);
     }
 
     /**
@@ -451,7 +451,7 @@
      * @return {boolean}
      */
     isIntentionalAbort() {
-      return this.deviceAttestationStage_ ==
+      return this.deviceAttestationStage_ ===
           SamlHandler.DeviceAttestationStage.ORIGINAL_REDIRECT_CANCELED;
     }
 
@@ -531,7 +531,7 @@
       const parser = new DOMParser();
       const xmlDoc = parser.parseFromString(samlResponse, 'text/xml');
       let certificate = xmlDoc.getElementsByTagName('ds:X509Certificate');
-      if (!certificate || certificate.length == 0) {
+      if (!certificate || certificate.length === 0) {
         // tag 'ds:X509Certificate' doesn't exist
         certificate = xmlDoc.getElementsByTagName('X509Certificate');
       }
@@ -555,7 +555,7 @@
       if (!this.extractSamlPasswordAttributes) {
         return;
       }
-      if (!this.isSamlPage_ || details.method != 'POST') {
+      if (!this.isSamlPage_ || details.method !== 'POST') {
         return;
       }
 
@@ -593,7 +593,7 @@
      * @private
      */
     continueDelayedRedirect_(url, challengeResponse) {
-      if (this.deviceAttestationStage_ !=
+      if (this.deviceAttestationStage_ !==
           SamlHandler.DeviceAttestationStage.ORIGINAL_REDIRECT_CANCELED) {
         console.error(
             'SamlHandler.continueDelayedRedirect_: incorrect attestation stage');
@@ -622,17 +622,17 @@
      */
     onBeforeRequest_(details) {
       // Default case without Verified Access.
-      if (this.deviceAttestationStage_ ==
+      if (this.deviceAttestationStage_ ===
           SamlHandler.DeviceAttestationStage.NONE) {
         return {};
       }
 
-      if (this.deviceAttestationStage_ ==
+      if (this.deviceAttestationStage_ ===
           SamlHandler.DeviceAttestationStage.NAVIGATING_TO_REDIRECT_PAGE) {
         return {};
       }
 
-      if ((this.deviceAttestationStage_ ==
+      if ((this.deviceAttestationStage_ ===
            SamlHandler.DeviceAttestationStage.CHALLENGE_RECEIVED) &&
           (this.verifiedAccessChallenge_ !== null)) {
         // Ask backend to compute response for device attestation challenge.
@@ -669,12 +669,12 @@
      */
     onBeforeSendHeaders_(details) {
       // Default case without Verified Access.
-      if (this.deviceAttestationStage_ ==
+      if (this.deviceAttestationStage_ ===
           SamlHandler.DeviceAttestationStage.NONE) {
         return {};
       }
 
-      if (this.deviceAttestationStage_ ==
+      if (this.deviceAttestationStage_ ===
           SamlHandler.DeviceAttestationStage.NAVIGATING_TO_REDIRECT_PAGE) {
         // Send extra header only if no error was encountered during challenge
         // key procedure.
@@ -715,11 +715,11 @@
         const header = headers[i];
         const headerName = header.name.toLowerCase();
 
-        if (headerName == SAML_HEADER) {
+        if (headerName === SAML_HEADER) {
           const action = header.value.toLowerCase();
-          if (action == 'start') {
+          if (action === 'start') {
             this.pendingIsSamlPage_ = true;
-          } else if (action == 'end') {
+          } else if (action === 'end') {
             this.pendingIsSamlPage_ = false;
           }
         }
@@ -730,7 +730,7 @@
         // |SAML_VERIFIED_ACCESS_CHALLENGE_HEADER| name contains challenge from
         // Verified Access Web API.
         if ((details.statusCode >= 300) && (details.statusCode <= 399) &&
-            (headerName == SAML_VERIFIED_ACCESS_CHALLENGE_HEADER)) {
+            (headerName === SAML_VERIFIED_ACCESS_CHALLENGE_HEADER)) {
           this.deviceAttestationStage_ =
               SamlHandler.DeviceAttestationStage.CHALLENGE_RECEIVED;
           this.verifiedAccessChallenge_ = header.value;
@@ -744,7 +744,7 @@
      * Invoked when the injected JS makes a connection.
      */
     onConnected_(port) {
-      if (port.targetWindow != this.webview_.contentWindow) {
+      if (port.targetWindow !== this.webview_.contentWindow) {
         return;
       }
 
@@ -786,7 +786,7 @@
      */
     onAPICall_(channel, msg) {
       const call = msg.call;
-      if (call.method == 'initialize') {
+      if (call.method === 'initialize') {
         if (!Number.isInteger(call.requestedVersion) ||
             call.requestedVersion < MIN_API_VERSION_VERSION) {
           this.sendInitializationFailure_(channel);
@@ -800,8 +800,8 @@
         return;
       }
 
-      if (call.method == 'add') {
-        if (API_KEY_TYPES.indexOf(call.keyType) == -1) {
+      if (call.method === 'add') {
+        if (API_KEY_TYPES.indexOf(call.keyType) === -1) {
           console.error('SamlHandler.onAPICall_: unsupported key type');
           return;
         }
@@ -811,7 +811,7 @@
         this.lastApiPasswordBytes_ = call.passwordBytes;
 
         this.dispatchEvent(new CustomEvent('apiPasswordAdded'));
-      } else if (call.method == 'confirm') {
+      } else if (call.method === 'confirm') {
         if (!(call.token in this.apiTokenStore_)) {
           console.error('SamlHandler.onAPICall_: token mismatch');
         } else {
diff --git a/chrome/browser/resources/gaia_auth_host/saml_injected.js b/chrome/browser/resources/gaia_auth_host/saml_injected.js
index 56d99d87..ac61f27 100644
--- a/chrome/browser/resources/gaia_auth_host/saml_injected.js
+++ b/chrome/browser/resources/gaia_auth_host/saml_injected.js
@@ -40,9 +40,9 @@
   },
 
   onMessage_(event) {
-    if (event.source != window || typeof event.data != 'object' ||
+    if (event.source !== window || typeof event.data !== 'object' ||
         !event.data.hasOwnProperty('type') ||
-        event.data.type != 'gaia_saml_api') {
+        event.data.type !== 'gaia_saml_api') {
       return;
     }
     // Forward API calls to the background script.
@@ -99,7 +99,7 @@
     this.passwordFieldsObserver = new MutationObserver(function(mutations) {
       mutations.forEach(function(mutation) {
         Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
-          if (addedNode.nodeType != Node.ELEMENT_NODE) {
+          if (addedNode.nodeType !== Node.ELEMENT_NODE) {
             return;
           }
 
@@ -135,7 +135,7 @@
     const existing = this.passwordFields_.filter(function(element) {
       return element === passwordField;
     });
-    if (existing.length != 0) {
+    if (existing.length !== 0) {
       return;
     }
 
@@ -153,7 +153,7 @@
    */
   maybeSendUpdatedPassword(index, fieldId) {
     const newValue = this.passwordFields_[index].value;
-    if (newValue == this.passwordValues_[index]) {
+    if (newValue === this.passwordValues_[index]) {
       return;
     }
 
@@ -192,9 +192,9 @@
     passwordScraper.init(channel, pageURL, document.documentElement);
   };
 
-  if (document.readyState == 'loading') {
+  if (document.readyState === 'loading') {
     window.addEventListener('readystatechange', function listener(event) {
-      if (document.readyState == 'loading') {
+      if (document.readyState === 'loading') {
         return;
       }
       initPasswordScraper();
diff --git a/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js b/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js
index 4fecfd13..a8c7221 100644
--- a/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js
+++ b/chrome/browser/resources/gaia_auth_host/saml_password_attributes.js
@@ -71,7 +71,7 @@
     // Don't throw any exception that could cause login to fail - extracting
     // these attributes can fail, but login should not be interrupted.
     try {
-      if (!xmlStr || typeof xmlStr != 'string') {
+      if (!xmlStr || typeof xmlStr !== 'string') {
         return PasswordAttributes.EMPTY;
       }
       if (xmlStr.length < MIN_SANE_XML_LENGTH ||
diff --git a/chrome/browser/resources/gaia_auth_host/saml_timestamps.js b/chrome/browser/resources/gaia_auth_host/saml_timestamps.js
index a15a7101..d3f397e 100644
--- a/chrome/browser/resources/gaia_auth_host/saml_timestamps.js
+++ b/chrome/browser/resources/gaia_auth_host/saml_timestamps.js
@@ -46,7 +46,7 @@
    */
   /* #export */ function decodeTimestamp(str) {
     str = str.trim();
-    if (str.length == 0 || str.length > MAX_SANE_LENGTH) {
+    if (str.length === 0 || str.length > MAX_SANE_LENGTH) {
       return null;
     }
 
diff --git a/chrome/browser/resources/hangout_services/thunk.js b/chrome/browser/resources/hangout_services/thunk.js
index 40b5f380..9990e9da 100644
--- a/chrome/browser/resources/hangout_services/thunk.js
+++ b/chrome/browser/resources/hangout_services/thunk.js
@@ -54,39 +54,39 @@
       origin = getHost(sender.url);
     }
 
-    if (method == 'cpu.getInfo') {
+    if (method === 'cpu.getInfo') {
       chrome.system.cpu.getInfo(doSendResponse);
       return true;
-    } else if (method == 'logging.setMetadata') {
+    } else if (method === 'logging.setMetadata') {
       const metaData = message['metaData'];
       chrome.webrtcLoggingPrivate.setMetaData(
           requestInfo, origin, metaData, doSendResponse);
       return true;
-    } else if (method == 'logging.start') {
+    } else if (method === 'logging.start') {
       chrome.webrtcLoggingPrivate.start(requestInfo, origin, doSendResponse);
       return true;
-    } else if (method == 'logging.uploadOnRenderClose') {
+    } else if (method === 'logging.uploadOnRenderClose') {
       chrome.webrtcLoggingPrivate.setUploadOnRenderClose(
           requestInfo, origin, true);
       doSendResponse();
       return false;
-    } else if (method == 'logging.noUploadOnRenderClose') {
+    } else if (method === 'logging.noUploadOnRenderClose') {
       chrome.webrtcLoggingPrivate.setUploadOnRenderClose(
           requestInfo, origin, false);
       doSendResponse();
       return false;
-    } else if (method == 'logging.stop') {
+    } else if (method === 'logging.stop') {
       chrome.webrtcLoggingPrivate.stop(requestInfo, origin, doSendResponse);
       return true;
-    } else if (method == 'logging.upload') {
+    } else if (method === 'logging.upload') {
       chrome.webrtcLoggingPrivate.upload(requestInfo, origin, doSendResponse);
       return true;
-    } else if (method == 'logging.uploadStored') {
+    } else if (method === 'logging.uploadStored') {
       const logId = message['logId'];
       chrome.webrtcLoggingPrivate.uploadStored(
           requestInfo, origin, logId, doSendResponse);
       return true;
-    } else if (method == 'logging.stopAndUpload') {
+    } else if (method === 'logging.stopAndUpload') {
       // Stop everything and upload. This is allowed to be called even if
       // logs have already been stopped or not started. Therefore, ignore
       // any errors along the way, but store them, so that if upload fails
@@ -121,23 +121,23 @@
                 });
           });
       return true;
-    } else if (method == 'logging.store') {
+    } else if (method === 'logging.store') {
       const logId = message['logId'];
       chrome.webrtcLoggingPrivate.store(
           requestInfo, origin, logId, doSendResponse);
       return true;
-    } else if (method == 'logging.discard') {
+    } else if (method === 'logging.discard') {
       chrome.webrtcLoggingPrivate.discard(requestInfo, origin, doSendResponse);
       return true;
-    } else if (method == 'getSinks') {
+    } else if (method === 'getSinks') {
       chrome.webrtcAudioPrivate.getSinks(doSendResponse);
       return true;
-    } else if (method == 'getAssociatedSink') {
+    } else if (method === 'getAssociatedSink') {
       const sourceId = message['sourceId'];
       chrome.webrtcAudioPrivate.getAssociatedSink(
           origin, sourceId, doSendResponse);
       return true;
-    } else if (method == 'isExtensionEnabled') {
+    } else if (method === 'isExtensionEnabled') {
       // This method is necessary because there may be more than one
       // version of this extension, under different extension IDs. By
       // first calling this method on the extension ID, the client can
@@ -146,33 +146,33 @@
       // chrome.runtime.lastError.
       doSendResponse();
       return false;
-    } else if (method == 'getNaclArchitecture') {
+    } else if (method === 'getNaclArchitecture') {
       chrome.runtime.getPlatformInfo(function(obj) {
         doSendResponse(obj.nacl_arch);
       });
       return true;
-    } else if (method == 'logging.startRtpDump') {
+    } else if (method === 'logging.startRtpDump') {
       const incoming = message['incoming'] || false;
       const outgoing = message['outgoing'] || false;
       chrome.webrtcLoggingPrivate.startRtpDump(
           requestInfo, origin, incoming, outgoing, doSendResponse);
       return true;
-    } else if (method == 'logging.stopRtpDump') {
+    } else if (method === 'logging.stopRtpDump') {
       const incoming = message['incoming'] || false;
       const outgoing = message['outgoing'] || false;
       chrome.webrtcLoggingPrivate.stopRtpDump(
           requestInfo, origin, incoming, outgoing, doSendResponse);
       return true;
-    } else if (method == 'logging.startAudioDebugRecordings') {
+    } else if (method === 'logging.startAudioDebugRecordings') {
       const seconds = message['seconds'] || 0;
       chrome.webrtcLoggingPrivate.startAudioDebugRecordings(
           requestInfo, origin, seconds, doSendResponse);
       return true;
-    } else if (method == 'logging.stopAudioDebugRecordings') {
+    } else if (method === 'logging.stopAudioDebugRecordings') {
       chrome.webrtcLoggingPrivate.stopAudioDebugRecordings(
           requestInfo, origin, doSendResponse);
       return true;
-    } else if (method == 'logging.startEventLogging') {
+    } else if (method === 'logging.startEventLogging') {
       const sessionId = message['sessionId'] || '';
       const maxLogSizeBytes = message['maxLogSizeBytes'] || 0;
       const outputPeriodMs = message['outputPeriodMs'] || -1;
@@ -181,7 +181,7 @@
           requestInfo, origin, sessionId, maxLogSizeBytes, outputPeriodMs,
           webAppId, doSendResponse);
       return true;
-    } else if (method == 'getHardwarePlatformInfo') {
+    } else if (method === 'getHardwarePlatformInfo') {
       chrome.enterprise.hardwarePlatform.getHardwarePlatformInfo(
           doSendResponse);
       return true;
@@ -220,7 +220,7 @@
 
   port.onMessage.addListener(function(message) {
     const method = message['method'];
-    if (method == 'chooseDesktopMedia') {
+    if (method === 'chooseDesktopMedia') {
       const sources = message['sources'];
       let cancelId = null;
       const tab = port.sender.tab;
@@ -256,7 +256,7 @@
 function onProcessCpu(port) {
   let tabPid = port.sender.guestProcessId || undefined;
   function processListener(processes) {
-    if (tabPid == undefined) {
+    if (tabPid === undefined) {
       // getProcessIdForTab sometimes fails, and does not call the callback.
       // (Tracked at https://crbug.com/368855.)
       // This call retries it on each process update until it succeeds.
@@ -273,9 +273,9 @@
     let browserProcessCpu, gpuProcessCpu;
     for (const pid in processes) {
       const process = processes[pid];
-      if (process.type == 'browser') {
+      if (process.type === 'browser') {
         browserProcessCpu = process.cpu;
-      } else if (process.type == 'gpu') {
+      } else if (process.type === 'gpu') {
         gpuProcessCpu = process.cpu;
       }
       if (browserProcessCpu && gpuProcessCpu) {
@@ -307,11 +307,11 @@
 }
 
 chrome.runtime.onConnectExternal.addListener(function(port) {
-  if (port.name == 'onSinksChangedListener') {
+  if (port.name === 'onSinksChangedListener') {
     onSinksChangedPort(port);
-  } else if (port.name == 'chooseDesktopMedia') {
+  } else if (port.name === 'chooseDesktopMedia') {
     onChooseDesktopMediaPort(port);
-  } else if (port.name == 'processCpu') {
+  } else if (port.name === 'processCpu') {
     onProcessCpu(port);
   } else {
     // Unknown port type.
diff --git a/chrome/browser/resources/history/history.html b/chrome/browser/resources/history/history.html
index 1d2d7cb..5d1f83e 100644
--- a/chrome/browser/resources/history/history.html
+++ b/chrome/browser/resources/history/history.html
@@ -23,10 +23,15 @@
     }
 
     body {
-      background: var(--md-background-color);
       cursor: default;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     /* Minimal styling required to display app shim. TODO(dbeam): do we really
      * need all this HTML/CSS just to show "History"? Other pages just show 56px
      * of [blue] border on top without text and this seems fine (maybe even
diff --git a/chrome/browser/resources/history/history_list.ts b/chrome/browser/resources/history/history_list.ts
index 2ff431c..4c4a8ba1 100644
--- a/chrome/browser/resources/history/history_list.ts
+++ b/chrome/browser/resources/history/history_list.ts
@@ -338,6 +338,10 @@
     this.notifySplices('historyData_', splices);
   }
 
+  removeItemsByIndexForTesting(indices: Array<number>) {
+    this.removeItemsByIndex_(indices);
+  }
+
   /**
    * Closes the overflow menu.
    */
diff --git a/chrome/browser/resources/history/synced_device_card.ts b/chrome/browser/resources/history/synced_device_card.ts
index 000b6273f..3b8ded8 100644
--- a/chrome/browser/resources/history/synced_device_card.ts
+++ b/chrome/browser/resources/history/synced_device_card.ts
@@ -36,6 +36,7 @@
   $: {
     'card-heading': HTMLDivElement,
     'collapse': IronCollapseElement,
+    'collapse-button': HTMLElement,
     'menu-button': HTMLElement,
   };
 }
diff --git a/chrome/browser/resources/history/synced_device_manager.ts b/chrome/browser/resources/history/synced_device_manager.ts
index 4c79264..5f971f1 100644
--- a/chrome/browser/resources/history/synced_device_manager.ts
+++ b/chrome/browser/resources/history/synced_device_manager.ts
@@ -102,8 +102,8 @@
   private guestSession_: boolean = loadTimeData.getBoolean('isGuestSession');
   private signInAllowed_: boolean = loadTimeData.getBoolean('isSignInAllowed');
   private debouncer_: Debouncer|null = null;
-  private signInState: boolean;
 
+  signInState: boolean;
   searchTerm: string;
   sessionList: Array<ForeignSession>;
 
diff --git a/chrome/browser/resources/identity_internals/identity_internals.js b/chrome/browser/resources/identity_internals/identity_internals.js
index beae30a..e02d674 100644
--- a/chrome/browser/resources/identity_internals/identity_internals.js
+++ b/chrome/browser/resources/identity_internals/identity_internals.js
@@ -163,7 +163,7 @@
   removeTokenNode_(accessToken) {
     let tokenIndex;
     for (let index = 0; index < this.data_.length; index++) {
-      if (this.data_[index].accessToken == accessToken) {
+      if (this.data_[index].accessToken === accessToken) {
         tokenIndex = index;
         break;
       }
diff --git a/chrome/browser/resources/identity_scope_approval_dialog/background.js b/chrome/browser/resources/identity_scope_approval_dialog/background.js
index 785ff085..ae6f3b0b 100644
--- a/chrome/browser/resources/identity_scope_approval_dialog/background.js
+++ b/chrome/browser/resources/identity_scope_approval_dialog/background.js
@@ -18,7 +18,7 @@
       'scope_approval_dialog.html', options, function(win) {
         win.contentWindow.addEventListener('load', function(event) {
           let windowParam;
-          if (mode == 'interactive') {
+          if (mode === 'interactive') {
             windowParam = win;
           }
           win.contentWindow.loadAuthUrlAndShowWindow(
diff --git a/chrome/browser/resources/inline_login/inline_login_util.js b/chrome/browser/resources/inline_login/inline_login_util.js
index c39b0d9..210a88d 100644
--- a/chrome/browser/resources/inline_login/inline_login_util.js
+++ b/chrome/browser/resources/inline_login/inline_login_util.js
@@ -27,7 +27,7 @@
     return null;
   }
 
-  assert(args.isAvailableInArc != undefined);
-  assert(args.showArcAvailabilityPicker != undefined);
+  assert(args.isAvailableInArc !== undefined);
+  assert(args.showArcAvailabilityPicker !== undefined);
   return args;
 }
diff --git a/chrome/browser/resources/inspect/inspect.js b/chrome/browser/resources/inspect/inspect.js
index d818a20..8e91e3a 100644
--- a/chrome/browser/resources/inspect/inspect.js
+++ b/chrome/browser/resources/inspect/inspect.js
@@ -71,7 +71,7 @@
 
 function onload() {
   const tabContents = document.querySelectorAll('#content > div');
-  for (let i = 0; i != tabContents.length; i++) {
+  for (let i = 0; i !== tabContents.length; i++) {
     const tabContent = tabContents[i];
     const tabName = tabContent.querySelector('.content-header').textContent;
 
@@ -105,10 +105,10 @@
   const tabContents = document.querySelectorAll('#content > div');
   const tabHeaders = $('navigation').querySelectorAll('.tab-header');
   let found = false;
-  for (let i = 0; i != tabContents.length; i++) {
+  for (let i = 0; i !== tabContents.length; i++) {
     const tabContent = tabContents[i];
     const tabHeader = tabHeaders[i];
-    if (tabContent.id == id) {
+    if (tabContent.id === id) {
       tabContent.classList.add('selected');
       tabHeader.classList.add('selected');
       found = true;
@@ -125,9 +125,9 @@
 }
 
 function populateTargets(source, data) {
-  if (source == 'local') {
+  if (source === 'local') {
     populateLocalTargets(data);
-  } else if (source == 'remote') {
+  } else if (source === 'remote') {
     populateRemoteTargets(data);
   } else {
     console.error('Unknown source type: ' + source);
@@ -183,7 +183,7 @@
 
 function alreadyDisplayed(element, data) {
   const json = JSON.stringify(data);
-  if (element.cachedJSON == json) {
+  if (element.cachedJSON === json) {
     return true;
   }
   element.cachedJSON = json;
@@ -229,10 +229,10 @@
   }
 
   function browserCompare(a, b) {
-    if (a.adbBrowserName != b.adbBrowserName) {
+    if (a.adbBrowserName !== b.adbBrowserName) {
       return a.adbBrowserName < b.adbBrowserName;
     }
-    if (a.adbBrowserVersion != b.adbBrowserVersion) {
+    if (a.adbBrowserVersion !== b.adbBrowserVersion) {
       return a.adbBrowserVersion < b.adbBrowserVersion;
     }
     return a.id < b.id;
@@ -385,7 +385,7 @@
             input.value = '';
           }.bind(null, browser.source, browser.id, newPageUrl);
           newPageUrl.addEventListener('keyup', function(handler, event) {
-            if (event.key == 'Enter' && event.target.value) {
+            if (event.key === 'Enter' && event.target.value) {
               handler();
             }
           }.bind(null, openHandler), true);
@@ -522,7 +522,7 @@
 function formatValue(data, property) {
   let value = data[property];
 
-  if (property == 'name' && value == '') {
+  if (property === 'name' && value === '') {
     value = 'untitled';
   }
 
@@ -699,7 +699,7 @@
   link.textContent = text;
   link.addEventListener('click', handler, true);
   function handleKey(e) {
-    if (e.key == 'Enter' || e.key == ' ') {
+    if (e.key === 'Enter' || e.key === ' ') {
       e.preventDefault();
       handler();
     }
@@ -739,7 +739,7 @@
   switch (event.keyCode) {
     case 13:  // Enter
       const dialog = $('config-dialog');
-      if (event.target.nodeName == 'INPUT') {
+      if (event.target.nodeName === 'INPUT') {
         const line = event.target.parentNode;
         if (!line.classList.contains('fresh') ||
             line.classList.contains('empty')) {
@@ -859,7 +859,7 @@
 
 function filterList(fieldSelectors, callback) {
   const lines = $('config-dialog').querySelectorAll('.config-list-row');
-  for (let i = 0; i != lines.length; i++) {
+  for (let i = 0; i !== lines.length; i++) {
     const line = lines[i];
     const values = [];
     for (const selector of fieldSelectors) {
@@ -871,7 +871,7 @@
       }
       values.push(value);
     }
-    if (values.length == fieldSelectors.length) {
+    if (values.length === fieldSelectors.length) {
       callback.apply(null, values);
     }
   }
@@ -910,7 +910,7 @@
 function appendRow(list, lineFactory, key, value) {
   const line = lineFactory(key, value);
   line.lastElementChild.addEventListener('keydown', function(e) {
-    if (e.key == 'Tab' && !hasKeyModifiers(e) &&
+    if (e.key === 'Tab' && !hasKeyModifiers(e) &&
         line.classList.contains('fresh') && !line.classList.contains('empty')) {
       // Tabbing forward on the fresh line, try create a new empty one.
       if (commitFreshLineIfValid(true)) {
@@ -951,11 +951,11 @@
   }
 
   const inputs = document.querySelectorAll('input.port:not(.invalid)');
-  for (let i = 0; i != inputs.length; ++i) {
-    if (inputs[i] == input) {
+  for (let i = 0; i !== inputs.length; ++i) {
+    if (inputs[i] === input) {
       break;
     }
-    if (parseInt(inputs[i].value) == port) {
+    if (parseInt(inputs[i].value) === port) {
       return false;
     }
   }
@@ -1008,8 +1008,8 @@
 function checkEmptyLine(line) {
   const inputs = line.querySelectorAll('input');
   let empty = true;
-  for (let i = 0; i != inputs.length; i++) {
-    if (inputs[i].value != '') {
+  for (let i = 0; i !== inputs.length; i++) {
+    if (inputs[i].value !== '') {
       empty = false;
     }
   }
diff --git a/chrome/browser/resources/internals/lens/lens_internals.js b/chrome/browser/resources/internals/lens/lens_internals.js
index 7884f93..1b4b5c3 100644
--- a/chrome/browser/resources/internals/lens/lens_internals.js
+++ b/chrome/browser/resources/internals/lens/lens_internals.js
@@ -16,7 +16,7 @@
  *     form.
  */
 function onDebugDataRefreshed(data) {
-  if (data.length == 0) {
+  if (data.length === 0) {
     toggleDebugModeButton(/*showEnableButton=*/ true);
   } else {
     toggleDebugModeButton(/*showEnableButton=*/ false);
@@ -73,4 +73,4 @@
   browserProxy.refreshDebugData().then(onDebugDataRefreshed);
 }
 
-document.addEventListener('DOMContentLoaded', initialize);
\ No newline at end of file
+document.addEventListener('DOMContentLoaded', initialize);
diff --git a/chrome/browser/resources/management/management.html b/chrome/browser/resources/management/management.html
index 0b6722f..235f539 100644
--- a/chrome/browser/resources/management/management.html
+++ b/chrome/browser/resources/management/management.html
@@ -11,11 +11,16 @@
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
   <style>
     html {
-      background: var(--md-background-color);
       height: 100%;
       overflow: hidden;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     html.loading::before {
       background-color: var(--md-toolbar-color);
       border-bottom: var(--md-toolbar-border);
diff --git a/chrome/browser/resources/media/media_engagement.js b/chrome/browser/resources/media/media_engagement.js
index c70048b..feec1fd 100644
--- a/chrome/browser/resources/media/media_engagement.js
+++ b/chrome/browser/resources/media/media_engagement.js
@@ -35,9 +35,9 @@
   const td = template.content.querySelectorAll('td');
 
   td[0].textContent = rowInfo.origin.scheme + '://' + rowInfo.origin.host;
-  if (rowInfo.origin.scheme == 'http' && rowInfo.origin.port != '80') {
+  if (rowInfo.origin.scheme === 'http' && rowInfo.origin.port !== 80) {
     td[0].textContent += ':' + rowInfo.origin.port;
-  } else if (rowInfo.origin.scheme == 'https' && rowInfo.origin.port != '443') {
+  } else if (rowInfo.origin.scheme === 'https' && rowInfo.origin.port !== 443) {
     td[0].textContent += ':' + rowInfo.origin.port;
   }
 
@@ -83,15 +83,15 @@
   const val2 = b[sortKey];
 
   // Compare the hosts of the origin ignoring schemes.
-  if (sortKey == 'origin') {
+  if (sortKey === 'origin') {
     return val1.host > val2.host ? 1 : -1;
   }
 
-  if (sortKey == 'visits' || sortKey == 'mediaPlaybacks' ||
-      sortKey == 'lastMediaPlaybackTime' || sortKey == 'totalScore' ||
-      sortKey == 'audiblePlaybacks' || sortKey == 'significantPlaybacks' ||
-      sortKey == 'highScoreChanges' || sortKey == 'mediaElementPlaybacks' ||
-      sortKey == 'audioContextPlaybacks' || sortKey == 'isHigh') {
+  if (sortKey === 'visits' || sortKey === 'mediaPlaybacks' ||
+      sortKey === 'lastMediaPlaybackTime' || sortKey === 'totalScore' ||
+      sortKey === 'audiblePlaybacks' || sortKey === 'significantPlaybacks' ||
+      sortKey === 'highScoreChanges' || sortKey === 'mediaElementPlaybacks' ||
+      sortKey === 'audioContextPlaybacks' || sortKey === 'isHigh') {
     return val1 - val2;
   }
 
@@ -204,7 +204,7 @@
   for (let i = 0; i < headers.length; i++) {
     headers[i].addEventListener('click', (e) => {
       const newSortKey = e.target.getAttribute('sort-key');
-      if (sortKey == newSortKey) {
+      if (sortKey === newSortKey) {
         sortReverse = !sortReverse;
       } else {
         sortKey = newSortKey;
diff --git a/chrome/browser/resources/media/webrtc_logs.js b/chrome/browser/resources/media/webrtc_logs.js
index e4029e5d8..9b2cac7 100644
--- a/chrome/browser/resources/media/webrtc_logs.js
+++ b/chrome/browser/resources/media/webrtc_logs.js
@@ -43,7 +43,7 @@
     logBlock.appendChild(title);
 
     const localFileLine = document.createElement('p');
-    if (textLog['local_file'].length == 0) {
+    if (textLog['local_file'].length === 0) {
       localFileLine.textContent =
           loadTimeData.getString('noLocalLogFileMessage');
     } else {
@@ -57,7 +57,7 @@
     logBlock.appendChild(localFileLine);
 
     const uploadLine = document.createElement('p');
-    if (textLog['id'].length == 0) {
+    if (textLog['id'].length === 0) {
       uploadLine.textContent =
           loadTimeData.getString('webrtcLogNotUploadedMessage');
     } else {
@@ -99,7 +99,7 @@
     textLogSection.appendChild(logBlock);
   }
 
-  $('text-no-logs').hidden = (textLogsList.length != 0);
+  $('text-no-logs').hidden = (textLogsList.length !== 0);
 }
 
 function updateWebRtcEventLogsList(eventLogsList) {
@@ -120,7 +120,7 @@
   $('event-log-banner').textContent =
       loadTimeData.getStringF('webrtcEventLogCountFormat', entries);
 
-  $('event-no-logs').hidden = (entries != 0);
+  $('event-no-logs').hidden = (entries !== 0);
 }
 
 function createEventLogEntryElement(eventLogEntry) {
@@ -130,13 +130,13 @@
   if (!state) {
     console.error('Unknown state.');
     return;
-  } else if (state == 'pending' || state == 'actively_uploaded') {
+  } else if (state === 'pending' || state === 'actively_uploaded') {
     return createPendingOrActivelyUploadedEventLogEntryElement(eventLogEntry);
-  } else if (state == 'not_uploaded') {
+  } else if (state === 'not_uploaded') {
     return createNotUploadedEventLogEntryElement(eventLogEntry);
-  } else if (state == 'upload_unsuccessful') {
+  } else if (state === 'upload_unsuccessful') {
     return createUploadUnsuccessfulEventLogEntryElement(eventLogEntry);
-  } else if (state == 'upload_successful') {
+  } else if (state === 'upload_successful') {
     return createUploadSuccessfulEventLogEntryElement(eventLogEntry);
   } else {
     console.error('Unrecognized state.');
@@ -155,7 +155,7 @@
   appendLocalFile(logBlock, eventLogEntry);
 
   const uploadLine = document.createElement('p');
-  if (eventLogEntry['state'] == 'pending') {
+  if (eventLogEntry['state'] === 'pending') {
     uploadLine.textContent = loadTimeData.getString('webrtcLogPendingMessage');
   } else {
     uploadLine.textContent =
diff --git a/chrome/browser/resources/media_router/cast_feedback_ui.js b/chrome/browser/resources/media_router/cast_feedback_ui.js
index ab828b65..3a1bb62 100644
--- a/chrome/browser/resources/media_router/cast_feedback_ui.js
+++ b/chrome/browser/resources/media_router/cast_feedback_ui.js
@@ -315,7 +315,7 @@
     setTimeout(() => {
       const sendStartTime = Date.now();
       this.browserProxy_.sendFeedback(feedback).then(status => {
-        if (status == chrome.feedbackPrivate.Status.SUCCESS) {
+        if (status === chrome.feedbackPrivate.Status.SUCCESS) {
           this.feedbackSent = true;
           this.updateSendDialog_(FeedbackEvent.SUCCEEDED, 'sendSuccess', true);
         } else if (failureCount < this.maxResendAttempts) {
diff --git a/chrome/browser/resources/memory_internals/memory_internals.js b/chrome/browser/resources/memory_internals/memory_internals.js
index 903ce4c2..c10e06c 100644
--- a/chrome/browser/resources/memory_internals/memory_internals.js
+++ b/chrome/browser/resources/memory_internals/memory_internals.js
@@ -42,7 +42,7 @@
   proclist.innerText = '';  // Clear existing contents.
 
   const processes = data['processes'];
-  if (processes.length == 0) {
+  if (processes.length === 0) {
     return;
   }  // No processes to dump, don't make the table.
 
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.js b/chrome/browser/resources/nearby_share/nearby_discovery_page.js
index 96d2801..a2675ad 100644
--- a/chrome/browser/resources/nearby_share/nearby_discovery_page.js
+++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.js
@@ -497,8 +497,8 @@
    * @private
    */
   getTabIndexOfShareTarget_(shareTarget) {
-    if ((!this.selectedShareTarget && shareTarget == this.shareTargets_[0]) ||
-        (shareTarget == this.selectedShareTarget)) {
+    if ((!this.selectedShareTarget && shareTarget === this.shareTargets_[0]) ||
+        (shareTarget === this.selectedShareTarget)) {
       return '0';
     }
     return '-1';
@@ -523,7 +523,7 @@
     tempEl.childNodes.forEach((node, index) => {
       // Text nodes should be aria-hidden and associated with an element id
       // that the anchor element can be aria-labelledby.
-      if (node.nodeType == Node.TEXT_NODE) {
+      if (node.nodeType === Node.TEXT_NODE) {
         const spanNode = document.createElement('span');
         spanNode.textContent = node.textContent;
         spanNode.id = `helpText${index}`;
@@ -534,7 +534,7 @@
       }
       // The single element node with anchor tags should also be aria-labelledby
       // itself in-order with respect to the entire string.
-      if (node.nodeType == Node.ELEMENT_NODE && node.nodeName == 'A') {
+      if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'A') {
         node.id = `helpLink`;
         ariaLabelledByIds.push(node.id);
         return;
@@ -547,12 +547,12 @@
     const anchorTags = tempEl.getElementsByTagName('a');
     // In the event the localizedString contains only text nodes, populate the
     // contents with the localizedString.
-    if (anchorTags.length == 0) {
+    if (anchorTags.length === 0) {
       return localizedString;
     }
 
     assert(
-        anchorTags.length == 1,
+        anchorTags.length === 1,
         'nearbyShareDiscoveryPageInfo should contain exactly one anchor tag');
     const anchorTag = anchorTags[0];
     anchorTag.setAttribute('aria-labelledby', ariaLabelledByIds.join(' '));
diff --git a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js
index b386b262..bf2c324 100644
--- a/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js
+++ b/chrome/browser/resources/nearby_share/shared/nearby_contact_visibility.js
@@ -430,7 +430,7 @@
     contactsFailedMessage.childNodes.forEach((node, index) => {
       // Text nodes should be aria-hidden and associated with an element id
       // that the anchor element can be aria-labelledby.
-      if (node.nodeType == Node.TEXT_NODE) {
+      if (node.nodeType === Node.TEXT_NODE) {
         const spanNode = document.createElement('span');
         spanNode.textContent = node.textContent;
         spanNode.id = `contactsFailedMessage${index}`;
@@ -441,7 +441,7 @@
       }
       // The single element node with anchor tags should also be aria-labelledby
       // itself in-order with respect to the entire string.
-      if (node.nodeType == Node.ELEMENT_NODE && node.nodeName == 'A') {
+      if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'A') {
         node.id = `tryAgainLink`;
         ariaLabelledByIds.push(node.id);
         return;
@@ -455,13 +455,14 @@
     const anchorTags = contactsFailedMessage.getElementsByTagName('a');
     // In the event the localizedString contains only text nodes, populate the
     // contents with the localizedString.
-    if (anchorTags.length == 0) {
+    if (anchorTags.length === 0) {
       contactsFailedMessage.innerHTML = localizedString;
       return;
     }
 
     assert(
-        anchorTags.length == 1, 'string should contain exactly one anchor tag');
+        anchorTags.length === 1,
+        'string should contain exactly one anchor tag');
     const anchorTag = anchorTags[0];
     anchorTag.setAttribute('aria-labelledby', ariaLabelledByIds.join(' '));
     anchorTag.href = '#';
@@ -492,7 +493,7 @@
     tempEl.childNodes.forEach((node, index) => {
       // Text nodes should be aria-hidden and associated with an element id
       // that the anchor element can be aria-labelledby.
-      if (node.nodeType == Node.TEXT_NODE) {
+      if (node.nodeType === Node.TEXT_NODE) {
         const spanNode = document.createElement('span');
         spanNode.textContent = node.textContent;
         spanNode.id = `zeroStateText${index}`;
@@ -503,7 +504,7 @@
       }
       // The single element node with anchor tags should also be aria-labelledby
       // itself in-order with respect to the entire string.
-      if (node.nodeType == Node.ELEMENT_NODE && node.nodeName == 'A') {
+      if (node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'A') {
         node.id = `zeroStateHelpLink`;
         ariaLabelledByIds.push(node.id);
         return;
@@ -517,12 +518,12 @@
     const anchorTags = tempEl.getElementsByTagName('a');
     // In the event the localizedString contains only text nodes, populate the
     // contents with the localizedString.
-    if (anchorTags.length == 0) {
+    if (anchorTags.length === 0) {
       return localizedString;
     }
 
     assert(
-        anchorTags.length == 1,
+        anchorTags.length === 1,
         'nearbyShareContactVisibilityZeroStateText should contain exactly' +
             ' one anchor tag');
     const anchorTag = anchorTags[0];
diff --git a/chrome/browser/resources/net_internals/domain_security_policy_view.js b/chrome/browser/resources/net_internals/domain_security_policy_view.js
index 503a072..6cbc4439 100644
--- a/chrome/browser/resources/net_internals/domain_security_policy_view.js
+++ b/chrome/browser/resources/net_internals/domain_security_policy_view.js
@@ -113,11 +113,11 @@
 
   onHSTSQueryResult_(result) {
     this.queryStsOutputDiv_.innerHTML = trustedTypes.emptyHTML;
-    if (result.error != undefined) {
+    if (result.error !== undefined) {
       const s = addNode(this.queryStsOutputDiv_, 'span');
       s.textContent = result.error;
       s.style.color = '#e00';
-    } else if (result.result == false) {
+    } else if (result.result === false) {
       const notFound = document.createElement('b');
       notFound.textContent = 'Not found';
       this.queryStsOutputDiv_.appendChild(notFound);
@@ -150,7 +150,7 @@
       const staticHashes = [];
       for (let i = 0; i < kStaticHashKeys.length; ++i) {
         const staticHashValue = result[kStaticHashKeys[i]];
-        if (staticHashValue != undefined && staticHashValue != '') {
+        if (staticHashValue !== undefined && staticHashValue !== '') {
           staticHashes.push(staticHashValue);
         }
 
@@ -161,7 +161,7 @@
 
           // If there are no static_hashes, do not make it seem like there is a
           // static PKP policy in place.
-          if (staticHashes.length == 0 && key.startsWith('static_pkp_')) {
+          if (staticHashes.length === 0 && key.startsWith('static_pkp_')) {
             addNode(this.queryStsOutputDiv_, 'br');
             continue;
           }
@@ -173,7 +173,8 @@
             addNodeWithText(this.queryStsOutputDiv_, 'tt', modeToString(value));
           } else {
             addNodeWithText(
-                this.queryStsOutputDiv_, 'tt', value == undefined ? '' : value);
+                this.queryStsOutputDiv_, 'tt',
+                value === undefined ? '' : value);
           }
           addNode(this.queryStsOutputDiv_, 'br');
         }
@@ -212,11 +213,11 @@
 
   onExpectCTQueryResult_(result) {
     this.queryExpectCTOutputDiv_.innerHTML = trustedTypes.emptyHTML;
-    if (result.error != undefined) {
+    if (result.error !== undefined) {
       const s = addNode(this.queryExpectCTOutputDiv_, 'span');
       s.textContent = result.error;
       s.style.color = '#e00';
-    } else if (result.result == false) {
+    } else if (result.result === false) {
       const notFound = document.createElement('b');
       notFound.textContent = 'Not found';
       this.queryExpectCTOutputDiv_.appendChild(notFound);
@@ -241,7 +242,7 @@
         addTextNode(this.queryExpectCTOutputDiv_, ' ' + key + ': ');
         addNodeWithText(
             this.queryExpectCTOutputDiv_, 'tt',
-            value == undefined ? '' : value);
+            value === undefined ? '' : value);
         addNode(this.queryExpectCTOutputDiv_, 'br');
       }
     }
@@ -278,9 +279,9 @@
 function modeToString(m) {
   // These numbers must match those in
   // TransportSecurityState::STSState::UpgradeMode.
-  if (m == 0) {
+  if (m === 0) {
     return 'FORCE_HTTPS';
-  } else if (m == 1) {
+  } else if (m === 1) {
     return 'DEFAULT';
   } else {
     return 'UNKNOWN';
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index e532614..d23425e 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -66,7 +66,7 @@
         throw Error('Invalid view class for tab');
       }
 
-      if (tabHash.charAt(0) != '#') {
+      if (tabHash.charAt(0) !== '#') {
         throw Error('Tab hashes must start with a #');
       }
 
@@ -95,7 +95,7 @@
     // Change the URL to match the new tab.
     const newTabHash = this.tabIdToHash_[newTabId];
     const parsed = parseUrlHash_(window.location.hash);
-    if (parsed.tabHash != newTabHash) {
+    if (parsed.tabHash !== newTabHash) {
       window.location.hash = newTabHash;
     }
   }
@@ -119,7 +119,7 @@
 
     // <if expr="not chromeos">
     // Don't switch to the chromeos view if not on chromeos.
-    if (parsed.tabHash == '#chromeos') {
+    if (parsed.tabHash === '#chromeos') {
       parsed.tabHash = EventsView.TAB_HASH;
     }
     // </if>
@@ -153,7 +153,7 @@
   const parameters = hash.split('&');
 
   let tabHash = parameters[0];
-  if (tabHash == '' || tabHash == '#') {
+  if (tabHash === '' || tabHash === '#') {
     tabHash = undefined;
   }
 
@@ -161,7 +161,7 @@
   let paramDict = null;
   for (let i = 1; i < parameters.length; i++) {
     const paramStrings = parameters[i].split('=');
-    if (paramStrings.length != 2) {
+    if (paramStrings.length !== 2) {
       continue;
     }
     if (paramDict == null) {
diff --git a/chrome/browser/resources/net_internals/view.js b/chrome/browser/resources/net_internals/view.js
index 490e32c..b7db694 100644
--- a/chrome/browser/resources/net_internals/view.js
+++ b/chrome/browser/resources/net_internals/view.js
@@ -109,7 +109,7 @@
     // Initialize the default values to those of the DIV.
     this.width_ = this.node_.offsetWidth;
     this.height_ = this.node_.offsetHeight;
-    this.isVisible_ = this.node_.style.display != 'none';
+    this.isVisible_ = this.node_.style.display !== 'none';
   }
 
   setGeometry(left, top, width, height) {
diff --git a/chrome/browser/resources/network_speech_synthesis/tts_extension.js b/chrome/browser/resources/network_speech_synthesis/tts_extension.js
index 37908805..088a7ad 100644
--- a/chrome/browser/resources/network_speech_synthesis/tts_extension.js
+++ b/chrome/browser/resources/network_speech_synthesis/tts_extension.js
@@ -114,7 +114,7 @@
   onSpeak_(utterance, options, callback) {
     // Ignore the utterance if it is empty. Continue such processing causes no
     // speech and fails all subsequent calls to process additional utterances.
-    if (utterance.length == 0) {
+    if (utterance.length === 0) {
       callback({'type': 'end', 'charIndex': 0});
       return;
     }
diff --git a/chrome/browser/resources/new_tab_page_instant/most_visited_title.js b/chrome/browser/resources/new_tab_page_instant/most_visited_title.js
index b81529b..614fe03 100644
--- a/chrome/browser/resources/new_tab_page_instant/most_visited_title.js
+++ b/chrome/browser/resources/new_tab_page_instant/most_visited_title.js
@@ -24,7 +24,7 @@
 function convertToHexColor(color) {
   // Color must be a number, finite, with no fractional part, in the correct
   // range for an RGB hex color.
-  if (isFinite(color) && Math.floor(color) == color && color >= 0 &&
+  if (isFinite(color) && Math.floor(color) === color && color >= 0 &&
       color <= 0xffffff) {
     const hexColor = color.toString(16);
     // Pads with initial zeros and # (e.g. for 'ff' yields '#0000ff').
@@ -142,13 +142,13 @@
   });
 
   link.addEventListener('keydown', function(event) {
-    if (event.keyCode == 46 /* DELETE */ ||
-        event.keyCode == 8 /* BACKSPACE */) {
+    if (event.keyCode === 46 /* DELETE */ ||
+        event.keyCode === 8 /* BACKSPACE */) {
       event.preventDefault();
       window.parent.postMessage(
           'tileBlacklisted,' + params['pos'], MV_DOMAIN_ORIGIN);
     } else if (
-        event.keyCode == 13 /* ENTER */ || event.keyCode == 32 /* SPACE */) {
+        event.keyCode === 13 /* ENTER */ || event.keyCode === 32 /* SPACE */) {
       // Event target is the <a> tag. Send a click event on it, which will
       // trigger the 'click' event registered above.
       event.preventDefault();
diff --git a/chrome/browser/resources/ntp4/apps_page.js b/chrome/browser/resources/ntp4/apps_page.js
index d5c72ba..bf98437 100644
--- a/chrome/browser/resources/ntp4/apps_page.js
+++ b/chrome/browser/resources/ntp4/apps_page.js
@@ -180,12 +180,12 @@
     let hasLaunchType = false;
     this.forAllLaunchTypes_(function(launchTypeButton, id) {
       launchTypeButton.disabled = false;
-      launchTypeButton.checked = app.appData.launch_type == id;
+      launchTypeButton.checked = app.appData.launch_type === id;
       // There are two cases when a launch type is hidden:
       //  1. if the launch type can't be changed.
       //  2. type is anything except launchTypeWindow
       launchTypeButton.hidden = !app.appData.mayChangeLaunchType ||
-          launchTypeButton != launchTypeWindow;
+          launchTypeButton !== launchTypeWindow;
       if (!launchTypeButton.hidden) {
         hasLaunchType = true;
       }
@@ -221,7 +221,7 @@
     this.runOnOsLogin_.hidden = !app.appData.mayShowRunOnOsLoginMode;
     this.runOnOsLogin_.disabled = !app.appData.mayToggleRunOnOsLoginMode;
     this.runOnOsLogin_.checked =
-        app.appData.runOnOsLoginMode != RUN_ON_OS_LOGIN_MODE.NOT_RUN;
+        app.appData.runOnOsLoginMode !== RUN_ON_OS_LOGIN_MODE.NOT_RUN;
 
 
   },
@@ -244,7 +244,7 @@
     targetLaunchType = this.launchNewWindow_.checked ? this.launchRegularTab_ :
                                                        this.launchNewWindow_;
     this.forAllLaunchTypes_(function(launchTypeButton, id) {
-      if (launchTypeButton == targetLaunchType) {
+      if (launchTypeButton === targetLaunchType) {
         chrome.send('setLaunchType', [app.appId, id]);
         // Manually update the launch type. We will only get
         // appsPrefChangeCallback calls after changes to other NTP instances.
@@ -291,7 +291,7 @@
     const app = this.app_;
     let mode = RUN_ON_OS_LOGIN_MODE.NOT_RUN;
 
-    if (pressed == this.runOnOsLogin_ && !pressed.checked) {
+    if (pressed === this.runOnOsLogin_ && !pressed.checked) {
       mode = RUN_ON_OS_LOGIN_MODE.WINDOWED;
     }
 
@@ -515,7 +515,7 @@
       this.appContents_.dispatchEvent(new MouseEvent('contextmenu'));
       e.preventDefault();
       e.stopPropagation();
-    } else if (e.key == 'Enter') {
+    } else if (e.key === 'Enter') {
       chrome.send('launchApp', [
         this.appId, APP_LAUNCH.NTP_APPS_MAXIMIZED, '', 0, e.altKey, e.ctrlKey,
         e.metaKey, e.shiftKey
@@ -551,11 +551,11 @@
   onMousedown_(e) {
     // If the current platform uses middle click to autoscroll and this
     // mousedown isn't handled, onClick_() will never fire. crbug.com/142939
-    if (e.button == 1) {
+    if (e.button === 1) {
       e.preventDefault();
     }
 
-    if (e.button == 2 ||
+    if (e.button === 2 ||
         !findAncestorByClass(
             /** @type {Element} */ (e.target), 'launch-click-target')) {
       this.appContents_.classList.add('suppress-active');
@@ -723,7 +723,7 @@
    * @private
    */
   onTileAdded_(e) {
-    assert(e.currentTarget == this);
+    assert(e.currentTarget === this);
     assert(e.addedTile.firstChild instanceof App);
     if (this.classList.contains('selected-card')) {
       e.addedTile.firstChild.loadIcon();
@@ -766,7 +766,7 @@
       return false;
     }
     return Array.prototype.indexOf.call(
-               e.dataTransfer.types, 'text/uri-list') != -1;
+               e.dataTransfer.types, 'text/uri-list') !== -1;
   },
 
   /** @override */
@@ -777,7 +777,7 @@
       const tileContents = currentlyDraggingTile.firstChild;
       if (tileContents.classList.contains('app')) {
         const originalPage = currentlyDraggingTile.tilePage;
-        const samePageDrag = originalPage == this;
+        const samePageDrag = originalPage === this;
         sourceId = samePageDrag ? DRAG_SOURCE.SAME_APPS_PANE :
                                   DRAG_SOURCE.OTHER_APPS_PANE;
         this.tileGrid_.insertBefore(
@@ -793,7 +793,7 @@
       sourceId = DRAG_SOURCE.OUTSIDE_NTP;
     }
 
-    assert(sourceId != -1);
+    assert(sourceId !== -1);
     chrome.send(
         'metricsHandler:recordInHistogram',
         ['NewTabPage.AppsPageDragSource', sourceId, DRAG_SOURCE_LIMIT]);
@@ -840,8 +840,8 @@
    *     and |title| members.
    */
   generateAppForLink(data) {
-    assert(data.url != undefined);
-    assert(data.title != undefined);
+    assert(data.url !== undefined);
+    assert(data.title !== undefined);
     const pageIndex = getAppsPageIndex(this);
     chrome.send('generateAppForLink', [data.url, data.title, pageIndex]);
   },
diff --git a/chrome/browser/resources/ntp4/dot_list.js b/chrome/browser/resources/ntp4/dot_list.js
index 4cf79d05..8078573f6 100644
--- a/chrome/browser/resources/ntp4/dot_list.js
+++ b/chrome/browser/resources/ntp4/dot_list.js
@@ -49,9 +49,9 @@
     }
 
     let direction = 0;
-    if (e.key == 'ArrowLeft') {
+    if (e.key === 'ArrowLeft') {
       direction = -1;
-    } else if (e.key == 'ArrowRight') {
+    } else if (e.key === 'ArrowRight') {
       direction = 1;
     } else {
       return;
@@ -63,7 +63,7 @@
     }
     const focusIndex = Array.prototype.indexOf.call(navDots, focusDot);
     let newFocusIndex = focusIndex + direction;
-    if (focusIndex == newFocusIndex) {
+    if (focusIndex === newFocusIndex) {
       return;
     }
 
diff --git a/chrome/browser/resources/ntp4/nav_dot.js b/chrome/browser/resources/ntp4/nav_dot.js
index 15608ec..4272a327 100644
--- a/chrome/browser/resources/ntp4/nav_dot.js
+++ b/chrome/browser/resources/ntp4/nav_dot.js
@@ -119,7 +119,7 @@
    * @param {Event} e The KeyboardEvent.
    */
   onKeyDown_(e) {
-    if (e.key == 'Enter') {
+    if (e.key === 'Enter') {
       this.onClick_(e);
       e.stopPropagation();
     }
@@ -134,7 +134,7 @@
     this.switchToPage();
     // The explicit focus call is necessary because of overriding the default
     // handling in onInputMouseDown_.
-    if (this.ownerDocument.activeElement != this.input_) {
+    if (this.ownerDocument.activeElement !== this.input_) {
       this.focus();
     }
 
@@ -160,7 +160,7 @@
    * @private
    */
   onInputMouseDown_(e) {
-    if (this.ownerDocument.activeElement != this.input_) {
+    if (this.ownerDocument.activeElement !== this.input_) {
       e.preventDefault();
     }
   },
@@ -224,7 +224,7 @@
   doDrop(e) {
     e.stopPropagation();
     const tile = getCurrentlyDraggingTile();
-    if (tile && tile.tilePage != this.page_) {
+    if (tile && tile.tilePage !== this.page_) {
       this.page_.appendDraggingTile();
     }
     // TODO(estade): handle non-tile drags.
diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js
index 9d37b239..52a84b3 100644
--- a/chrome/browser/resources/ntp4/new_tab.js
+++ b/chrome/browser/resources/ntp4/new_tab.js
@@ -158,7 +158,7 @@
  * @param {Function} callback The work to be done when ready.
  */
 function doWhenAllSectionsReady(callback) {
-  assert(typeof callback == 'function');
+  assert(typeof callback === 'function');
   if (sectionsToWaitFor > 0) {
     readyCallbacks.push(callback);
   } else {
diff --git a/chrome/browser/resources/ntp4/page_list_view.js b/chrome/browser/resources/ntp4/page_list_view.js
index f039247..6c13ce3 100644
--- a/chrome/browser/resources/ntp4/page_list_view.js
+++ b/chrome/browser/resources/ntp4/page_list_view.js
@@ -233,7 +233,7 @@
     this.dotList.insertBefore(
         newDot, opt_refNode ? opt_refNode.navigationDot : null);
     // Set a tab index on the first dot.
-    if (this.dotList.dots.length == 1) {
+    if (this.dotList.dots.length === 1) {
       newDot.tabIndex = 3;
     }
 
@@ -349,7 +349,7 @@
         Array.prototype.indexOf.call(this.tilePages, lastAppsPage) :
         -1;
     const nextPageAfterApps =
-        lastAppsPageIndex != -1 ? this.tilePages[lastAppsPageIndex + 1] : null;
+        lastAppsPageIndex !== -1 ? this.tilePages[lastAppsPageIndex + 1] : null;
 
     // Add the apps, creating pages as necessary
     for (let i = 0; i < apps.length; i++) {
@@ -365,10 +365,11 @@
         this.appendTilePage(new AppsPage(), pageName, true, nextPageAfterApps);
         // Confirm that appsPages is a live object, updated when a new page is
         // added (otherwise we'd have an infinite loop)
-        assert(this.appsPages.length == origPageCount + 1, 'expected new page');
+        assert(
+            this.appsPages.length === origPageCount + 1, 'expected new page');
       }
 
-      if (app.id == this.highlightAppId) {
+      if (app.id === this.highlightAppId) {
         highlightApp = app;
       } else {
         this.appsPages[pageIndex].insertApp(app, false);
@@ -400,7 +401,7 @@
    *     be highlighted.
    */
   appAdded(appData, opt_highlight) {
-    if (appData.id == this.highlightAppId) {
+    if (appData.id === this.highlightAppId) {
       opt_highlight = true;
       this.highlightAppId = null;
     }
@@ -484,7 +485,8 @@
         document.querySelector('.tile-page.temporary'));
     if (tempPage) {
       const dot = tempPage.navigationDot;
-      if (!tempPage.tileCount && tempPage != this.cardSlider.currentCardValue) {
+      if (!tempPage.tileCount &&
+          tempPage !== this.cardSlider.currentCardValue) {
         this.removeTilePageAndDot_(tempPage, true);
       } else {
         tempPage.classList.remove('temporary');
@@ -503,7 +505,7 @@
    * @param {Event} e The event.
    */
   onPageLayout_(e) {
-    if (Array.prototype.indexOf.call(this.tilePages, e.currentTarget) !=
+    if (Array.prototype.indexOf.call(this.tilePages, e.currentTarget) !==
         this.cardSlider.currentCard) {
       return;
     }
@@ -524,9 +526,10 @@
     const page =
         /** @type {?TilePage} */ (this.cardSlider.currentCardValue);
 
-    this.pageSwitcherStart.hidden = !page || (this.cardSlider.currentCard == 0);
-    this.pageSwitcherEnd.hidden =
-        !page || (this.cardSlider.currentCard == this.cardSlider.cardCount - 1);
+    this.pageSwitcherStart.hidden =
+        !page || (this.cardSlider.currentCard === 0);
+    this.pageSwitcherEnd.hidden = !page ||
+        (this.cardSlider.currentCard === this.cardSlider.cardCount - 1);
 
     if (!page) {
       return;
@@ -647,7 +650,7 @@
    */
   saveAppPageName(appPage, name) {
     const index = this.getAppsPageIndex(appPage);
-    assert(index != -1);
+    assert(index !== -1);
     chrome.send('saveAppPageName', [name, index]);
   },
 
@@ -688,9 +691,9 @@
     }
 
     let direction = 0;
-    if (e.key == 'ArrowLeft') {
+    if (e.key === 'ArrowLeft') {
       direction = -1;
-    } else if (e.key == 'ArrowRight') {
+    } else if (e.key === 'ArrowRight') {
       direction = 1;
     } else {
       return;
diff --git a/chrome/browser/resources/ntp4/page_switcher.js b/chrome/browser/resources/ntp4/page_switcher.js
index 2ece809..253e01d 100644
--- a/chrome/browser/resources/ntp4/page_switcher.js
+++ b/chrome/browser/resources/ntp4/page_switcher.js
@@ -51,7 +51,7 @@
   updateButtonAccessibleLabel(dots) {
     const currentIndex = getCardSlider().currentCard;
     const nextCardIndex = this.nextCardIndex_();
-    if (nextCardIndex == currentIndex) {
+    if (nextCardIndex === currentIndex) {
       this.setAttribute('aria-label', '');  // No next card.
       return;
     }
@@ -65,7 +65,7 @@
 
     const currentPageTitle = currentDot.displayTitle;
     const nextPageTitle = nextDot.displayTitle;
-    const msgName = (currentPageTitle == nextPageTitle) ?
+    const msgName = (currentPageTitle === nextPageTitle) ?
         'page_switcher_same_title' :
         'page_switcher_change_title';
     const ariaLabel = loadTimeData.getStringF(msgName, nextPageTitle);
@@ -107,7 +107,7 @@
 
     const sourcePage = tile.tilePage;
     const targetPage = getCardSlider().currentCardValue;
-    if (targetPage == sourcePage || !targetPage.shouldAcceptDrag(e)) {
+    if (targetPage === sourcePage || !targetPage.shouldAcceptDrag(e)) {
       return;
     }
 
@@ -153,7 +153,7 @@
 
   el.addEventListener('click', el.activate_);
 
-  el.direction_ = el.id == 'page-switcher-start' ? -1 : 1;
+  el.direction_ = el.id === 'page-switcher-start' ? -1 : 1;
 
   el.dragWrapper_ = new DragWrapper(el, el);
 }
diff --git a/chrome/browser/resources/ntp4/tile_page.js b/chrome/browser/resources/ntp4/tile_page.js
index 42c285a..1ffd95f3 100644
--- a/chrome/browser/resources/ntp4/tile_page.js
+++ b/chrome/browser/resources/ntp4/tile_page.js
@@ -154,7 +154,7 @@
    * @private
    */
   onDragMove_(e) {
-    if (e.view != window || (e.x == 0 && e.y == 0)) {
+    if (e.view !== window || (e.x === 0 && e.y === 0)) {
       this.dragClone.hidden = true;
       return;
     }
@@ -188,7 +188,7 @@
       // TODO(dbeam): Until we fix dropEffect to the correct behavior it will
       // differ on windows - crbug.com/39399.  That's why we use the custom
       // this.lastDropEffect instead of e.dataTransfer.dropEffect.
-      if (tilePage.selected && this.lastDropEffect != 'copy') {
+      if (tilePage.selected && this.lastDropEffect !== 'copy') {
         // The drag clone can still be hidden from the last drag move event.
         this.dragClone.hidden = false;
         // The tile's contents may have moved following the respositioning;
@@ -299,8 +299,8 @@
    */
   onDragCloneTransitionEnd_(e) {
     if (this.classList.contains('dragging') &&
-        (e.propertyName == 'left' || e.propertyName == 'top' ||
-         e.propertyName == 'transform')) {
+        (e.propertyName === 'left' || e.propertyName === 'top' ||
+         e.propertyName === 'transform')) {
       this.finalizeDrag_();
     }
   },
@@ -501,7 +501,7 @@
   },
 
   get selected() {
-    return Array.prototype.indexOf.call(this.parentNode.children, this) ==
+    return Array.prototype.indexOf.call(this.parentNode.children, this) ===
         getCardSlider().currentCard;
   },
 
@@ -528,7 +528,7 @@
    * @type {number}
    */
   get contentPadding() {
-    if (typeof this.contentPadding_ == 'undefined') {
+    if (typeof this.contentPadding_ === 'undefined') {
       this.contentPadding_ =
           parseInt(window.getComputedStyle(this.content_).paddingTop, 10);
     }
@@ -546,7 +546,7 @@
     // removing a tilePage. Selecting a different card in an animated way and
     // deleting the card afterward is probably a better choice.
     assert(
-        typeof arguments[0] != 'boolean',
+        typeof arguments[0] !== 'boolean',
         'This function takes no |opt_animate| argument.');
     this.tearDown_();
     this.parentNode.removeChild(this);
@@ -599,7 +599,7 @@
     this.repositionTiles_();
 
     // If this is the first tile being added, make it focusable after add.
-    if (this.focusableElements_.length == 1) {
+    if (this.focusableElements_.length === 1) {
       this.updateFocusableElement();
     }
     this.fireAddedEvent(wrapperDiv, index, animate);
@@ -696,7 +696,7 @@
    * @private
    */
   handleFocus_(e) {
-    if (this.focusableElements_.length == 0) {
+    if (this.focusableElements_.length === 0) {
       return;
     }
 
@@ -740,14 +740,14 @@
     switch (e.key) {
       case 'ArrowRight':
       case 'ArrowLeft':
-        direction = e.key == 'ArrowRight' ? 1 : -1;
+        direction = e.key === 'ArrowRight' ? 1 : -1;
         this.focusElementIndex_ = wrap(this.focusElementIndex_ + direction);
         break;
       case 'ArrowUp':
       case 'ArrowDown':
         // Look through all focusable elements. Find the first one that is
         // in the same column.
-        direction = e.key == 'ArrowUp' ? -1 : 1;
+        direction = e.key === 'ArrowUp' ? -1 : 1;
         const currentIndex = Array.prototype.indexOf.call(
             this.focusableElements_, this.currentFocusElement_);
         let newFocusIdx = wrap(currentIndex + direction);
@@ -755,7 +755,7 @@
         for (;; newFocusIdx = wrap(newFocusIdx + direction)) {
           const newTile = this.focusableElements_[newFocusIdx].parentNode;
           const rowTiles = this.layoutValues_.numRowTiles;
-          if ((newTile.index - tile.index) % rowTiles == 0) {
+          if ((newTile.index - tile.index) % rowTiles === 0) {
             break;
           }
         }
@@ -780,7 +780,7 @@
    * @protected
    */
   updateFocusableElement() {
-    if (this.focusableElements_.length == 0 || !this.selected) {
+    if (this.focusableElements_.length === 0 || !this.selected) {
       this.focusElementIndex_ = -1;
       return;
     }
@@ -791,7 +791,7 @@
 
     const newFocusElement = this.focusableElements_[this.focusElementIndex_];
     const lastFocusElement = this.currentFocusElement_;
-    if (lastFocusElement && lastFocusElement != newFocusElement) {
+    if (lastFocusElement && lastFocusElement !== newFocusElement) {
       lastFocusElement.tabIndex = -1;
     }
 
@@ -922,9 +922,9 @@
 
     // This code calculates whether the tile needs to show a clone of itself
     // wrapped around the other side of the tile grid.
-    const offTheRight = col == layout.numRowTiles ||
-        (col == layout.numRowTiles - 1 && tile.hasDoppleganger());
-    const offTheLeft = col == -1 || (col == 0 && tile.hasDoppleganger());
+    const offTheRight = col === layout.numRowTiles ||
+        (col === layout.numRowTiles - 1 && tile.hasDoppleganger());
+    const offTheLeft = col === -1 || (col === 0 && tile.hasDoppleganger());
     if (this.isCurrentDragTarget && (offTheRight || offTheLeft)) {
       const sign = offTheRight ? 1 : -1;
       tile.showDoppleganger(
@@ -934,7 +934,7 @@
       tile.clearDoppleganger();
     }
 
-    if (index == this.tileElements_.length - 1) {
+    if (index === this.tileElements_.length - 1) {
       this.tileGrid_.style.height = (realY + layout.rowHeight) + 'px';
       this.queueUpdateScrollbars_();
     }
@@ -976,8 +976,8 @@
    * @param {Object} e The resize event.
    */
   onResize_(e) {
-    if (this.lastWidth_ == this.clientWidth &&
-        this.lastHeight_ == this.clientHeight) {
+    if (this.lastWidth_ === this.clientWidth &&
+        this.lastHeight_ === this.clientHeight) {
       return;
     }
 
@@ -1049,10 +1049,10 @@
     // calculations may come out to be negative, so we use margins as the
     // css property.
 
-    if (typeof this.topMarginIsForWide_ == 'undefined') {
+    if (typeof this.topMarginIsForWide_ === 'undefined') {
       this.topMarginIsForWide_ = layout.wide;
     }
-    if (this.topMarginIsForWide_ != layout.wide) {
+    if (this.topMarginIsForWide_ !== layout.wide) {
       this.animatedTopMarginPx_ += newMargin - this.topMarginPx_;
       this.topMargin_.style.marginBottom = toCssPx(this.animatedTopMarginPx_);
     }
@@ -1100,7 +1100,7 @@
   handleMouseWheel(e) {
     // The ctrl-wheel should triggle the zoom in/out actions in Chromium for
     // all pages.
-    if (e.wheelDeltaY == 0 || e.ctrlKey) {
+    if (e.wheelDeltaY === 0 || e.ctrlKey) {
       return false;
     }
 
@@ -1229,7 +1229,7 @@
 
     const index = this.currentDropIndex_;
     // Only change data if this was not a 'null drag'.
-    if (!((index == this.dragItemIndex_) && this.withinPageDrag_)) {
+    if (!((index === this.dragItemIndex_) && this.withinPageDrag_)) {
       const adjustedIndex =
           this.currentDropIndex_ + (index > this.dragItemIndex_ ? 1 : 0);
       if (this.withinPageDrag_) {
@@ -1261,7 +1261,7 @@
    */
   appendDraggingTile() {
     const originalPage = currentlyDraggingTile.tilePage;
-    if (originalPage == this) {
+    if (originalPage === this) {
       return;
     }
 
@@ -1300,7 +1300,7 @@
    */
   updateDropIndicator_(newDragIndex) {
     const oldDragIndex = this.currentDropIndex_;
-    if (newDragIndex == oldDragIndex) {
+    if (newDragIndex === oldDragIndex) {
       return;
     }
 
@@ -1308,7 +1308,7 @@
     const repositionEnd = Math.max(newDragIndex, oldDragIndex);
 
     for (let i = repositionStart; i <= repositionEnd; i++) {
-      if (i == this.dragItemIndex_) {
+      if (i === this.dragItemIndex_) {
         continue;
       }
 
diff --git a/chrome/browser/resources/offline_pages/offline_internals.js b/chrome/browser/resources/offline_pages/offline_internals.js
index f6a3ae4d..1cc937c 100644
--- a/chrome/browser/resources/offline_pages/offline_internals.js
+++ b/chrome/browser/resources/offline_pages/offline_internals.js
@@ -296,7 +296,7 @@
               saveUrls[i] + ' has been added to queue.\n';
           $('url').value = '';
           counter--;
-          if (counter == 0) {
+          if (counter === 0) {
             browserProxy.getRequestQueue().then(fillRequestQueue);
           }
         } else {
diff --git a/chrome/browser/resources/predictors/resource_prefetch_predictor.js b/chrome/browser/resources/predictors/resource_prefetch_predictor.js
index a4db0936..d706cf6 100644
--- a/chrome/browser/resources/predictors/resource_prefetch_predictor.js
+++ b/chrome/browser/resources/predictors/resource_prefetch_predictor.js
@@ -93,7 +93,7 @@
       const origin = main.origins[j];
       const row = document.createElement('tr');
 
-      if (j == 0) {
+      if (j === 0) {
         const t = document.createElement('td');
         t.rowSpan = main.origins.length;
         t.textContent = truncateString(main.main_frame_host);
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
index a7ebdfc..0473ed0 100644
--- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
+++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
@@ -6,7 +6,7 @@
 
   #destinationDropdown:focus {
     border-radius: 4px;
-    box-shadow: 0 0 0 2px rgba(var(--cros-focus-ring-color-rgb), .4);
+    box-shadow: 0 0 0 2px rgba(var(--google-blue-600-rgb), .4);
   }
 
   #destinationDropdown,
@@ -15,13 +15,13 @@
   }
 
   iron-dropdown {
-    border: none;
+    border: 0.5px solid rgba(0, 0, 0, 0.5);
     max-height: 270px;
   }
 
   iron-dropdown [slot='dropdown-content'] {
-    background-color: var(--cros-bg-color-elevation-2);
-    box-shadow: var(--cros-elevation-2-shadow);
+    background-color: white;
+    box-shadow: 0 2px 6px var(--google-grey-600);
     padding: 8px 0;
   }
 
@@ -66,17 +66,8 @@
     outline: none;
   }
 
-  /* Highlight colors align with highlight in other dropdowns. */
   .list-item.highlighted {
-    background-color: rgb(203, 228, 250);
-  }
-
-  @media (prefers-color-scheme: dark) {
-    .list-item.highlighted {
-      --iron-icon-fill-color: currentColor;
-      background-color: rgb(153, 200, 254);
-      color: var(--cros-color-primary-inverted);
-    }
+    background-color: var(--google-blue-100);
   }
 
   #destination-icon-box,
@@ -86,7 +77,7 @@
 
   #destination-display-container {
     align-items: center;
-    background-color: var(--cros-textfield-background-color);
+    background-color: var(--google-grey-100);
     border-radius: 4px;
     cursor: pointer;
     display: flex;
diff --git a/chrome/browser/resources/print_preview/ui/destination_select_cros.html b/chrome/browser/resources/print_preview/ui/destination_select_cros.html
index c46ecc97b..b0c137c 100644
--- a/chrome/browser/resources/print_preview/ui/destination_select_cros.html
+++ b/chrome/browser/resources/print_preview/ui/destination_select_cros.html
@@ -1,6 +1,6 @@
 <style include="print-preview-shared throbber destination-select cr-hidden-style">
   :host([is-current-destination-cros-local_]) #statusText {
-    color: var(--cros-text-color-alert);
+    color: var(--google-red-600);
     font-size: calc(10 / 13 * 1em);
     overflow: hidden;
     padding: 0;
diff --git a/chrome/browser/resources/sandbox_internals/sandbox_internals.js b/chrome/browser/resources/sandbox_internals/sandbox_internals.js
index 4fa81a01..564ce08 100644
--- a/chrome/browser/resources/sandbox_internals/sandbox_internals.js
+++ b/chrome/browser/resources/sandbox_internals/sandbox_internals.js
@@ -78,7 +78,7 @@
 
     addStatusRow('PID', status.pid, StatusClass.INFO);
     addStatusRow('UID', status.uid, StatusClass.INFO);
-    isIsolated = status.secontext.indexOf(':isolated_app:') != -1;
+    isIsolated = status.secontext.indexOf(':isolated_app:') !== -1;
     addStatusRow(
         'SELinux Context', status.secontext,
         isIsolated ? StatusClass.GOOD : StatusClass.BAD);
@@ -88,11 +88,11 @@
       if (line.startsWith('Seccomp')) {
         let value = line.split(':')[1].trim();
         let cssClass = StatusClass.BAD;
-        if (value == '2') {
+        if (value === '2') {
           value = 'Yes - TSYNC (' + line + ')';
           cssClass = StatusClass.GOOD;
           isTsync = true;
-        } else if (value == '1') {
+        } else if (value === '1') {
           value = 'Yes (' + line + ')';
         } else {
           value = line;
@@ -123,7 +123,7 @@
     }
     addStatusRow(
         'Seccomp-BPF Enabled (Chrome)', seccompStatus,
-        status.seccompStatus == 4 ? StatusClass.GOOD : StatusClass.BAD);
+        status.seccompStatus === 4 ? StatusClass.GOOD : StatusClass.BAD);
 
     addStatusRow('Android Build ID', status.androidBuildId, StatusClass.INFO);
 
diff --git a/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js b/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js
index ad7e592..48798b2 100644
--- a/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js
+++ b/chrome/browser/resources/sandbox_internals/sandbox_internals_win.js
@@ -94,7 +94,7 @@
    * @return {boolean}
    */
   isFieldSet(bytes) {
-    if (bytes.length != 4 && bytes.length != 8 && bytes.length != 16) {
+    if (bytes.length !== 4 && bytes.length !== 8 && bytes.length !== 16) {
       throw ('Platform mitigations has unexpected size');
     }
     const subfield = this.getFieldData(bytes);
@@ -103,7 +103,7 @@
     }
     const idx = subfield.length - 1 - Math.floor(this.offset / 8);
     const ibit = this.offset % 8;
-    return (subfield[idx] & (this.mask << ibit)) == (this.value << ibit);
+    return (subfield[idx] & (this.mask << ibit)) === (this.value << ibit);
   }
 }
 
@@ -116,10 +116,10 @@
    * @return {Uint8Array} chunk containing this field or null.
    */
   getFieldData(bytes) {
-    if (bytes.length == 4) {
+    if (bytes.length === 4) {
       // Win32 only 4 bytes of fields.
       return bytes;
-    } else if (bytes.length == 8) {
+    } else if (bytes.length === 8) {
       return bytes;
     } else {
       return bytes.slice(0, 8);
@@ -133,9 +133,9 @@
 class PC1Field extends MitigationField {
   /** @override */
   getFieldData(bytes) {
-    if (bytes.length == 8) {
+    if (bytes.length === 8) {
       return bytes;
-    } else if (bytes.length == 16) {
+    } else if (bytes.length === 16) {
       return bytes.slice(0, 8);
     }
     return null;
@@ -148,9 +148,9 @@
 class PC2Field extends MitigationField {
   /** @override */
   getFieldData(bytes) {
-    if (bytes.length == 8) {
+    if (bytes.length === 8) {
       return null;
-    } else if (bytes.length == 16) {
+    } else if (bytes.length === 16) {
       return bytes.slice(8, 16);
     }
     return null;
@@ -266,7 +266,7 @@
    * @return {Uint8Array} bytes Decoded bytes.
    */
   parseHexString(str) {
-    assert((str.length % 2 == 0), 'str must have even length');
+    assert((str.length % 2 === 0), 'str must have even length');
     const bytes = new Uint8Array(str.length / 2);
     for (let idx = 0; idx < str.length / 2; idx++) {
       bytes[idx] = parseInt(str.slice(idx * 2, idx * 2 + 2), 16);
diff --git a/chrome/browser/resources/segmentation_internals/segmentation_internals.ts b/chrome/browser/resources/segmentation_internals/segmentation_internals.ts
index a7ad7b2..6a0c0ff 100644
--- a/chrome/browser/resources/segmentation_internals/segmentation_internals.ts
+++ b/chrome/browser/resources/segmentation_internals/segmentation_internals.ts
@@ -72,7 +72,8 @@
   dataDiv.className = 'hidden-meta';
   div.setAttribute('simple', '');
   div.addEventListener('click', (e) => {
-    if (e.target != targetDiv && e.target != resultDiv && e.target != dataDiv) {
+    if (e.target !== targetDiv && e.target !== resultDiv &&
+        e.target !== dataDiv) {
       return;
     }
     if (div.hasAttribute('simple')) {
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
index 0072a80..fc15372 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/internet_page/BUILD.gn
@@ -138,6 +138,7 @@
     "//ui/webui/resources/cr_elements/cr_icon_button:cr_icon_button.m",
     "//ui/webui/resources/cr_elements/cr_link_row:cr_link_row",
     "//ui/webui/resources/js:assert.m",
+    "//ui/webui/resources/js:i18n_behavior.m",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
index f1c21688..d7b30f0a 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.html
@@ -28,7 +28,8 @@
           deep-link-focus-id$="[[Setting.kForgetWifiNetwork]]">
         <template is="dom-if" if="[[isPolicySource(item.source))]]">
           <cr-policy-indicator on-click="doNothing_"
-              indicator-type="[[getIndicatorTypeForSource(item.source)]]">
+              indicator-type="[[getIndicatorTypeForSource(item.source)]]"
+              icon-aria-label="[[getEnterpriseIconAriaLabel_(item)]]">
           </cr-policy-indicator>
         </template>
       </cr-link-row>
@@ -55,7 +56,8 @@
               [[Setting.kForgetWifiNetwork]]">
         <template is="dom-if" if="[[isPolicySource(item.source))]]">
           <cr-policy-indicator on-click="doNothing_"
-              indicator-type="[[getIndicatorTypeForSource(item.source)]]">
+              indicator-type="[[getIndicatorTypeForSource(item.source)]]"
+              icon-aria-label="[[getEnterpriseIconAriaLabel_(item)]]">
           </cr-policy-indicator>
         </template>
       </cr-link-row>
diff --git a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
index 4356d52c..4c6ad1b 100644
--- a/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
+++ b/chrome/browser/resources/settings/chromeos/internet_page/internet_known_networks_page.js
@@ -20,6 +20,7 @@
 import {OncMojo} from '//resources/cr_components/chromeos/network/onc_mojo.m.js';
 import {CrActionMenuElement} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
 import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Route, Router} from '../../router.js';
@@ -37,6 +38,7 @@
     NetworkListenerBehavior,
     CrPolicyNetworkBehaviorMojo,
     RouteObserverBehavior,
+    I18nBehavior,
   ],
 
   properties: {
@@ -217,6 +219,17 @@
   },
 
   /**
+   * @param {!OncMojo.NetworkStateProperties} networkState
+   * @return {string}
+   * @private
+   */
+  getEnterpriseIconAriaLabel_(networkState) {
+    return this.i18n(
+        'networkA11yManagedByAdministrator',
+        this.getNetworkDisplayName_(networkState));
+  },
+
+  /**
    * @param {!Event} event
    * @private
    */
diff --git a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js
index b395f3f..d2918e6 100644
--- a/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js
+++ b/chrome/browser/resources/settings/chromeos/nearby_share_page/nearby_share_subpage.js
@@ -426,6 +426,10 @@
       this.showDeviceNameDialog_ = true;
     }
 
+    if (queryParams.has('visibility')) {
+      this.showVisibilityDialog_ = true;
+    }
+
     if (queryParams.has('receive')) {
       this.showHighVisibilityPage_(Number(queryParams.get('timeout')));
     }
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
index 16c5b51..4f207acf 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.html
@@ -81,49 +81,47 @@
         deep-link-focus-id$="[[Setting.kVerifiedAccess]]">
     </settings-toggle-button>
     <template is="dom-if" if="[[isThunderboltSupported_]]">
-      <template is="dom-if" if="[[isPciguardUiEnabled_]]">
-        <div class="hr"></div>
-        <!-- This toggle is always disabled. The underlying pref state is
-             handled by the JS impl. This is to prevent toggling the pref
-             before the user confirms the action. -->
-        <div id="dataAccessProtectionWrapper"
-            tabindex="0"
-            on-focus="onDataAccessToggleFocus_"
-            on-keypress="onDataAccessToggleKeyPress_">
-          <settings-toggle-button
-              id="crosSettingDataAccessToggle"
-              class="peripheral-data-access-protection"
-              pref="{{prefs.cros.device.peripheral_data_access_enabled}}"
-              label="$i18n{peripheralDataAccessProtectionToggleTitle}"
-              sub-label=
-                  "$i18n{peripheralDataAccessProtectionToggleDescription}"
-              deep-link-focus-id$=
-                  "[[Setting.kPeripheralDataAccessProtection]]"
-              on-click="onPeripheralProtectionClick_"
-              learn-more-url="$i18n{peripheralDataAccessLearnMoreURL}"
-              hidden$="[[isLocalStateDataAccessPref_(
-                  dataAccessProtectionPrefName_)]]"
-              disabled
-              inverted>
-          </settings-toggle-button>
-          <settings-toggle-button
-              id="localStateDataAccessToggle"
-              class="peripheral-data-access-protection"
-              pref="{{prefs.settings.local_state_device_pci_data_access_enabled}}"
-              label="$i18n{peripheralDataAccessProtectionToggleTitle}"
-              sub-label=
-                  "$i18n{peripheralDataAccessProtectionToggleDescription}"
-              deep-link-focus-id$=
-                  "[[Setting.kPeripheralDataAccessProtection]]"
-              on-click="onPeripheralProtectionClick_"
-              learn-more-url="$i18n{peripheralDataAccessLearnMoreURL}"
-              hidden$="[[isCrosSettingDataAccessPref_(
-                  dataAccessProtectionPrefName_)]]"
-              disabled
-              inverted>
-          </settings-toggle-button>
-        </div>
-      </template>
+      <div class="hr"></div>
+      <!-- This toggle is always disabled. The underlying pref state is
+            handled by the JS impl. This is to prevent toggling the pref
+            before the user confirms the action. -->
+      <div id="dataAccessProtectionWrapper"
+          tabindex="0"
+          on-focus="onDataAccessToggleFocus_"
+          on-keypress="onDataAccessToggleKeyPress_">
+        <settings-toggle-button
+            id="crosSettingDataAccessToggle"
+            class="peripheral-data-access-protection"
+            pref="{{prefs.cros.device.peripheral_data_access_enabled}}"
+            label="$i18n{peripheralDataAccessProtectionToggleTitle}"
+            sub-label=
+                "$i18n{peripheralDataAccessProtectionToggleDescription}"
+            deep-link-focus-id$=
+                "[[Setting.kPeripheralDataAccessProtection]]"
+            on-click="onPeripheralProtectionClick_"
+            learn-more-url="$i18n{peripheralDataAccessLearnMoreURL}"
+            hidden$="[[isLocalStateDataAccessPref_(
+                dataAccessProtectionPrefName_)]]"
+            disabled
+            inverted>
+        </settings-toggle-button>
+        <settings-toggle-button
+            id="localStateDataAccessToggle"
+            class="peripheral-data-access-protection"
+            pref="{{prefs.settings.local_state_device_pci_data_access_enabled}}"
+            label="$i18n{peripheralDataAccessProtectionToggleTitle}"
+            sub-label=
+                "$i18n{peripheralDataAccessProtectionToggleDescription}"
+            deep-link-focus-id$=
+                "[[Setting.kPeripheralDataAccessProtection]]"
+            on-click="onPeripheralProtectionClick_"
+            learn-more-url="$i18n{peripheralDataAccessLearnMoreURL}"
+            hidden$="[[isCrosSettingDataAccessPref_(
+                dataAccessProtectionPrefName_)]]"
+            disabled
+            inverted>
+        </settings-toggle-button>
+      </div>
     </template>
     <template is="dom-if" if="[[showSecureDnsSetting_]]">
       <div class="hr"></div>
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.js b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.js
index c0cb6b2..cf88b8d 100644
--- a/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.js
+++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/os_privacy_page.js
@@ -119,18 +119,6 @@
     },
 
     /**
-     * True if Pciguard UI is enabled.
-     * @private
-     */
-    isPciguardUiEnabled_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('pciguardUiEnabled');
-      },
-      readOnly: true,
-    },
-
-    /**
      * True if snooping protection or screen lock is enabled.
      * @private
      */
@@ -255,7 +243,7 @@
 
     this.browserProxy_.isThunderboltSupported().then(enabled => {
       this.isThunderboltSupported_ = enabled;
-      if (this.isPciguardUiEnabled_ && this.isThunderboltSupported_) {
+      if (this.isThunderboltSupported_) {
         this.supportedSettingIds.add(
             chromeos.settings.mojom.Setting.kPeripheralDataAccessProtection);
       }
@@ -514,7 +502,7 @@
    * @private
    */
   onDataAccessFlagsSet_() {
-    if (this.isThunderboltSupported_ && this.isPciguardUiEnabled_) {
+    if (this.isThunderboltSupported_) {
       this.browserProxy_.getPolicyState()
           .then(policy => {
             this.dataAccessProtectionPrefName_ = policy.prefName;
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html
index da9d882..38f9b4c 100644
--- a/chrome/browser/resources/settings/settings.html
+++ b/chrome/browser/resources/settings/settings.html
@@ -9,12 +9,17 @@
   <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
   <style>
     html {
-      background: var(--md-background-color);
       overflow: hidden;
       /* Remove 300ms delay for 'click' event, when using touch interface. */
       touch-action: manipulation;
     }
 
+    @media (prefers-color-scheme: dark) {
+      html {
+        background: var(--md-background-color);
+      }
+    }
+
     html.loading::before {
       background-color: var(--md-toolbar-color);
       border-bottom: var(--md-toolbar-border);
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_app.ts b/chrome/browser/resources/signin/profile_picker/profile_picker_app.ts
index 7f72fef3..bc0e687 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_picker_app.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_picker_app.ts
@@ -65,9 +65,9 @@
       return;
     }
 
-    if (step == ProfileCreationSteps.LOAD_FORCE_SIGNIN) {
+    if (step === ProfileCreationSteps.LOAD_FORCE_SIGNIN) {
       assert(
-          route == Routes.NEW_PROFILE,
+          route === Routes.NEW_PROFILE,
           'LOAD_FORCE_SIGNIN step must be a part of NEW_PROFILE route');
       assert(
           isForceSigninEnabled(),
diff --git a/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation_app.ts b/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation_app.ts
index 2d122ad..84c9ccd7 100644
--- a/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation_app.ts
+++ b/chrome/browser/resources/signin/sync_confirmation/sync_disabled_confirmation_app.ts
@@ -72,7 +72,7 @@
     // If the currently focused element isn't something that performs an action
     // on "enter" being pressed and the user hits "enter", perform the default
     // action of the dialog, which is "OK, Got It".
-    if (e.key == 'Enter' &&
+    if (e.key === 'Enter' &&
         !/^(A|PAPER-(BUTTON|CHECKBOX))$/.test(
             document.activeElement!.tagName)) {
       this.$.confirmButton.click();
diff --git a/chrome/browser/resources/sync_file_system_internals/file_metadata.js b/chrome/browser/resources/sync_file_system_internals/file_metadata.js
index 95455a2af..81db152e 100644
--- a/chrome/browser/resources/sync_file_system_internals/file_metadata.js
+++ b/chrome/browser/resources/sync_file_system_internals/file_metadata.js
@@ -43,7 +43,7 @@
     select.options.add(new Option(title, originEntry.extensionID));
 
     // If option was the previously only selected, make it selected again.
-    if (originEntry.extensionID != oldSelectedExtension) {
+    if (originEntry.extensionID !== oldSelectedExtension) {
       continue;
     }
     select.options[select.options.length - 1].selected = true;
@@ -118,9 +118,9 @@
 function createFileIconCell(type) {
   const img = document.createElement('div');
   const lowerType = type.toLowerCase();
-  if (lowerType == 'file') {
+  if (lowerType === 'file') {
     img.style.content = getImage('chrome://theme/IDR_DEFAULT_FAVICON');
-  } else if (lowerType == 'folder') {
+  } else if (lowerType === 'folder') {
     img.style.content = getImage('chrome://theme/IDR_FOLDER_CLOSED');
     img.className = 'folder-image';
   }
diff --git a/chrome/browser/resources/tab_search/app.ts b/chrome/browser/resources/tab_search/app.ts
index b40424d..24d20d16 100644
--- a/chrome/browser/resources/tab_search/app.ts
+++ b/chrome/browser/resources/tab_search/app.ts
@@ -333,11 +333,11 @@
     let text;
     if (this.searchText_.length > 0) {
       text = loadTimeData.getStringF(
-          itemCount == 1 ? 'a11yFoundTabFor' : 'a11yFoundTabsFor', itemCount,
+          itemCount === 1 ? 'a11yFoundTabFor' : 'a11yFoundTabsFor', itemCount,
           this.searchText_);
     } else {
       text = loadTimeData.getStringF(
-          itemCount == 1 ? 'a11yFoundTab' : 'a11yFoundTabs', itemCount);
+          itemCount === 1 ? 'a11yFoundTab' : 'a11yFoundTabs', itemCount);
     }
     return text;
   }
diff --git a/chrome/browser/resources/tab_search/tab_data.ts b/chrome/browser/resources/tab_search/tab_data.ts
index 92bc4e3..09f0808 100644
--- a/chrome/browser/resources/tab_search/tab_data.ts
+++ b/chrome/browser/resources/tab_search/tab_data.ts
@@ -62,7 +62,7 @@
 
 function titleAndAlertAriaLabel(tabData: TabData): string {
   const tabTitle = tabData.tab.title;
-  if (tabData.type == TabItemType.OPEN_TAB &&
+  if (tabData.type === TabItemType.OPEN_TAB &&
       tabHasMediaAlerts(tabData.tab as Tab)) {
     // GetTabAlertStatesForContents adds alert indicators in the order of their
     // priority. Only relevant media alerts are sent over mojo so the first
@@ -88,7 +88,7 @@
       itemData.type === TabItemType.RECENTLY_CLOSED_TAB_GROUP) {
     const tabGroup = itemData.tabGroup as RecentlyClosedTabGroup;
     const tabCountText = loadTimeData.getStringF(
-        tabGroup.tabCount == 1 ? 'oneTab' : 'tabCount', tabGroup.tabCount);
+        tabGroup.tabCount === 1 ? 'oneTab' : 'tabCount', tabGroup.tabCount);
     return `${tabGroup.title} ${tabCountText} ${
         tabGroup.lastActiveElapsedText} ${itemData.a11yTypeText}`;
   }
diff --git a/chrome/browser/resources/tab_search/tab_search_group_item.ts b/chrome/browser/resources/tab_search/tab_search_group_item.ts
index 189e912..de961da 100644
--- a/chrome/browser/resources/tab_search/tab_search_group_item.ts
+++ b/chrome/browser/resources/tab_search/tab_search_group_item.ts
@@ -64,7 +64,7 @@
 
   private tabCountText_(tabCount: number): string {
     return loadTimeData.getStringF(
-        tabCount == 1 ? 'oneTab' : 'tabCount', tabCount);
+        tabCount === 1 ? 'oneTab' : 'tabCount', tabCount);
   }
 }
 
diff --git a/chrome/browser/resources/tab_search/tab_search_item.ts b/chrome/browser/resources/tab_search/tab_search_item.ts
index fa819be..c5333d39 100644
--- a/chrome/browser/resources/tab_search/tab_search_item.ts
+++ b/chrome/browser/resources/tab_search/tab_search_item.ts
@@ -100,7 +100,7 @@
   }
 
   private isOpenTabAndHasMediaAlert_(tabData: TabData): boolean {
-    return tabData.type == TabItemType.OPEN_TAB &&
+    return tabData.type === TabItemType.OPEN_TAB &&
         tabHasMediaAlerts(tabData.tab as Tab);
   }
 
diff --git a/chrome/browser/resources/usb_internals/descriptor_panel.js b/chrome/browser/resources/usb_internals/descriptor_panel.js
index 0a02ce7..c8a6d85 100644
--- a/chrome/browser/resources/usb_internals/descriptor_panel.js
+++ b/chrome/browser/resources/usb_internals/descriptor_panel.js
@@ -435,21 +435,21 @@
       offset += length;
     }
 
-    if (expectNumInterfaces != indexInterface) {
+    if (expectNumInterfaces !== indexInterface) {
       showError(
           `Expected to find ${expectNumInterfaces} interface descriptors ` +
               `but only encountered ${indexInterface}.`,
           this.rootElement_);
     }
 
-    if (expectNumEndpoints != indexEndpoint) {
+    if (expectNumEndpoints !== indexEndpoint) {
       showError(
           `Expected to find ${expectNumEndpoints} interface descriptors ` +
               `but only encountered ${indexEndpoint}.`,
           this.rootElement_);
     }
 
-    if (expectNumDevCapabilities != indexDevCapability) {
+    if (expectNumDevCapabilities !== indexDevCapability) {
       showError(
           `Expected to find ${expectNumDevCapabilities} ` +
               `device capability descriptors but only encountered ${
@@ -2756,7 +2756,7 @@
     });
 
     el.addEventListener('click', (event) => {
-      if (event.target.className != 'expand-icon') {
+      if (event.target.className !== 'expand-icon') {
         // Clears all the selected elements before select another.
         rawDataByteElement.querySelectorAll('.raw-data-byte-view span')
             .forEach((el) => el.classList.remove('selected-field'));
diff --git a/chrome/browser/resources/webapks/about_webapks.js b/chrome/browser/resources/webapks/about_webapks.js
index f4e2c07..663d257 100644
--- a/chrome/browser/resources/webapks/about_webapks.js
+++ b/chrome/browser/resources/webapks/about_webapks.js
@@ -126,7 +126,7 @@
       webApkInfo.updateStatus);
 
   // TODO(ckitagawa): Convert to an enum using mojom handlers.
-  if (webApkInfo.updateStatus == 'Not updatable' ||
+  if (webApkInfo.updateStatus === 'Not updatable' ||
       !webApkInfo.isBackingBrowser) {
     return;
   }
diff --git a/chrome/browser/resources_util_unittest.cc b/chrome/browser/resources_util_unittest.cc
index 6c4a0b46..2e9c160 100644
--- a/chrome/browser/resources_util_unittest.cc
+++ b/chrome/browser/resources_util_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "components/grit/components_scaled_resources.h"
@@ -35,6 +34,6 @@
     {"backstar", -1},
   };
 
-  for (size_t i = 0; i < base::size(kCases); ++i)
+  for (size_t i = 0; i < std::size(kCases); ++i)
     EXPECT_EQ(kCases[i].id, ResourcesUtil::GetThemeResourceId(kCases[i].name));
 }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index 2b5cef2..68f5356 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -918,7 +918,9 @@
                           PasswordType::SAVED_PASSWORD, credentials,
                           LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
                           true);
-    DCHECK_EQ(service->get_pending_requests_for_testing().size(), 1ul);
+    if (service->get_pending_requests_for_testing().size() != 1ul)
+      return nullptr;
+
     return *service->get_pending_requests_for_testing().begin();
   }
 
@@ -933,8 +935,9 @@
       PasswordProtectionRequest* request) {
     auto* request_content =
         static_cast<PasswordProtectionRequestContent*>(request);
-    DCHECK_EQ(request_content->get_deferred_navigations_for_testing().size(),
-              1ul);
+    if (request_content->get_deferred_navigations_for_testing().size() != 1ul)
+      return nullptr;
+
     return *request_content->get_deferred_navigations_for_testing().begin();
   }
 
@@ -947,6 +950,59 @@
                        LoginReputationClientResponse::PHISHING, "unused_token",
                        WarningUIType::MODAL_DIALOG, action);
   }
+
+  bool RunUntilRequestDefersCommit(
+      PasswordProtectionRequest* request,
+      content::TestNavigationManager& navigation_manager) {
+    DCHECK(navigation_manager.WaitForResponse());
+
+    // This will run until the first yield point of the navigation which could
+    // be the PasswordProtectionCommitDeferringCondition but it may also be some
+    // other condition, or if no conditions defer it will run until the
+    // navigation finish.
+    navigation_manager.ResumeNavigation();
+
+    // If the navigation finished, fail the test.
+    EXPECT_TRUE(navigation_manager.GetNavigationHandle());
+    if (!navigation_manager.GetNavigationHandle())
+      return false;
+
+    // We must be blocked on a CommitDeferringCondition, otherwise, some new
+    // yield point was added after the response but before
+    // CommitDeferringConditions.
+    DCHECK(navigation_manager.GetNavigationHandle()
+               ->IsCommitDeferringConditionDeferredForTesting());
+
+    // A PasswordProtectionCommitDeferringCondition should have been created.
+    PasswordProtectionCommitDeferringCondition* condition =
+        GetDeferringCondition(request);
+    DCHECK(condition);
+
+    // If the navigation is blocked on the PasswordProtection condition then
+    // we're already done.
+    if (navigation_manager.GetNavigationHandle()
+            ->GetCommitDeferringConditionForTesting() == condition) {
+      return true;
+    }
+
+    // There could be other CommitDeferringConditions before the
+    // PasswordProtection one. Continue past them until we get to it.
+    base::RunLoop run_loop(base::RunLoop::Type::kDefault);
+    condition->register_invoke_callback_for_testing(run_loop.QuitClosure());
+    run_loop.Run();
+
+    // If the navigation finished, fail the test.
+    EXPECT_TRUE(navigation_manager.GetNavigationHandle());
+    if (!navigation_manager.GetNavigationHandle())
+      return false;
+
+    // Ensure the navigation is deferred on the condition we expect.
+    EXPECT_EQ(navigation_manager.GetNavigationHandle()
+                  ->GetCommitDeferringConditionForTesting(),
+              condition);
+    return navigation_manager.GetNavigationHandle()
+               ->GetCommitDeferringConditionForTesting() == condition;
+  }
 };
 
 // Tests that a navigation started while a modal warning is showing is deferred
@@ -962,6 +1018,7 @@
   // Start a request for a PASSWORD_REUSE_EVENT.
   scoped_refptr<PasswordProtectionRequest> request =
       StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
   // Finish the request so that it results in a modal warning being shown.
   FinishRequest(request.get(), LoginReputationClientResponse::PHISHING);
@@ -972,25 +1029,14 @@
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
   ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
-  ASSERT_TRUE(navigation.WaitForResponse());
 
-  // The deferral happens in a CommitDeferringCondition just before commit.
-  // Resume past the response and we should be blocked in the
+  // Run the navigation until it defers on the
   // PasswordProtectionCommitDeferringCondition.
-  navigation.ResumeNavigation();
-  ASSERT_TRUE(navigation.GetNavigationHandle()
-                  ->IsCommitDeferringConditionDeferredForTesting());
-
-  // Make sure it's the PasswordProtection condition that's causing deferral.
-  PasswordProtectionCommitDeferringCondition* condition =
-      GetDeferringCondition(request.get());
-  ASSERT_TRUE(condition->is_deferred_for_testing());
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), navigation));
 
   // Simulate the user dismissing the dialog. The navigation should be resumed.
   DismissModalDialog(WarningAction::IGNORE_WARNING);
 
-  ASSERT_FALSE(navigation.GetNavigationHandle()
-                   ->IsCommitDeferringConditionDeferredForTesting());
   navigation.WaitForNavigationFinished();
   ASSERT_TRUE(navigation.was_successful());
 }
@@ -1010,32 +1056,22 @@
   // Start a request for a PASSWORD_REUSE_EVENT.
   scoped_refptr<PasswordProtectionRequest> request =
       StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
   // Start a renderer-initiated navigation away from the current page. The
   // navigation should be deferred.
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
   ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
-  ASSERT_TRUE(navigation.WaitForResponse());
 
-  // The deferral happens in a CommitDeferringCondition just before commit.
-  // Resume past the response and we should be blocked in the
+  // Run the navigation until it defers on the
   // PasswordProtectionCommitDeferringCondition.
-  navigation.ResumeNavigation();
-  ASSERT_TRUE(navigation.GetNavigationHandle()
-                  ->IsCommitDeferringConditionDeferredForTesting());
-
-  // Make sure it's the PasswordProtection condition that's causing deferral.
-  PasswordProtectionCommitDeferringCondition* condition =
-      GetDeferringCondition(request.get());
-  ASSERT_TRUE(condition->is_deferred_for_testing());
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), navigation));
 
   // Finish the request so that the modal warning is not shown.
   FinishRequest(request.get(), LoginReputationClientResponse::SAFE);
   ASSERT_FALSE(request->is_modal_warning_showing());
 
-  ASSERT_FALSE(navigation.GetNavigationHandle()
-                   ->IsCommitDeferringConditionDeferredForTesting());
   navigation.WaitForNavigationFinished();
   ASSERT_TRUE(navigation.was_successful());
 }
@@ -1055,50 +1091,38 @@
   // Start a request for a PASSWORD_REUSE_EVENT.
   scoped_refptr<PasswordProtectionRequest> request =
       StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
   // Start a renderer-initiated navigation away from the current page. The
   // navigation should be deferred.
   content::TestNavigationManager navigation(GetWebContents(), kNextPage);
   ASSERT_TRUE(content::ExecJs(GetWebContents()->GetMainFrame(),
                               content::JsReplace("location = $1", kNextPage)));
-  ASSERT_TRUE(navigation.WaitForResponse());
-
-  // The deferral happens in a CommitDeferringCondition just before commit.
-  // Resume past the response and we should be blocked in the
+  // Run the navigation until it defers on the
   // PasswordProtectionCommitDeferringCondition.
-  navigation.ResumeNavigation();
-  ASSERT_TRUE(navigation.GetNavigationHandle()
-                  ->IsCommitDeferringConditionDeferredForTesting());
-
-  // Make sure it's the PasswordProtection condition that's causing deferral.
-  PasswordProtectionCommitDeferringCondition* condition =
-      GetDeferringCondition(request.get());
-  ASSERT_TRUE(condition->is_deferred_for_testing());
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), navigation));
 
   // Finish the request so that a modal warning is shown
   FinishRequest(request.get(), LoginReputationClientResponse::PHISHING);
   ASSERT_TRUE(request->is_modal_warning_showing());
-
   ASSERT_TRUE(navigation.GetNavigationHandle()
                   ->IsCommitDeferringConditionDeferredForTesting());
 
   // Simulate the user dismissing the dialog. The navigation should be resumed.
   DismissModalDialog(WarningAction::IGNORE_WARNING);
 
-  ASSERT_FALSE(navigation.GetNavigationHandle()
-                   ->IsCommitDeferringConditionDeferredForTesting());
   navigation.WaitForNavigationFinished();
   ASSERT_TRUE(navigation.was_successful());
 }
 
 // Extends the test fixture with support for testing prerendered and
 // back/forward cached pages.
-class ChromePasswordProtectionServiceBrowserTestWithActivation
-    : public ChromePasswordProtectionServiceBrowserTest {
+class ChromePasswordProtectionServiceDeferActivationBrowserTest
+    : public ChromePasswordProtectionServiceNavigationDeferralBrowserTest {
  public:
-  ChromePasswordProtectionServiceBrowserTestWithActivation()
+  ChromePasswordProtectionServiceDeferActivationBrowserTest()
       : prerender_helper_(base::BindRepeating(
-            &ChromePasswordProtectionServiceBrowserTestWithActivation::
+            &ChromePasswordProtectionServiceDeferActivationBrowserTest::
                 GetWebContents,
             base::Unretained(this))) {
     scoped_feature_list_.InitWithFeaturesAndParameters(
@@ -1111,7 +1135,54 @@
 
   void SetUp() override {
     prerender_helper_.SetUp(embedded_test_server());
-    ChromePasswordProtectionServiceBrowserTest::SetUp();
+    ChromePasswordProtectionServiceNavigationDeferralBrowserTest::SetUp();
+  }
+
+  // This is almost the same as the base class version but is slightly
+  // different as it must use a TestActivationManager which has different
+  // navigation timing.
+  bool RunUntilRequestDefersCommit(
+      PasswordProtectionRequest* request,
+      content::TestActivationManager& prerender_manager) {
+    DCHECK(prerender_manager.WaitForBeforeChecks());
+
+    // A PasswordProtectionCommitDeferringCondition should have been created
+    // for commit checks.
+    PasswordProtectionCommitDeferringCondition* condition =
+        GetDeferringCondition(request);
+    DCHECK(condition);
+
+    base::RunLoop run_loop(base::RunLoop::Type::kDefault);
+    condition->register_invoke_callback_for_testing(run_loop.QuitClosure());
+
+    // This will run until the first yield point of the navigation which could
+    // be the PasswordProtectionCommitDeferringCondition but it may also be some
+    // other condition, or if no conditions defer it will run until the
+    // navigation finish.
+    prerender_manager.ResumeActivation();
+
+    // If the navigation finished, fail the test.
+    EXPECT_TRUE(prerender_manager.GetNavigationHandle());
+    if (!prerender_manager.GetNavigationHandle())
+      return false;
+
+    // If the navigation yielded on a condition before the
+    // PasswordProtectionCommitDeferringCondition, continue until it is
+    // invoked.  If ResumeActivation yielded due to the PasswordProtection
+    // condition, this will be a no-op.
+    run_loop.Run();
+
+    // If the navigation finished, fail the test.
+    EXPECT_TRUE(prerender_manager.GetNavigationHandle());
+    if (!prerender_manager.GetNavigationHandle())
+      return false;
+
+    // Ensure the navigation is deferred on the condition we expect.
+    EXPECT_EQ(prerender_manager.GetNavigationHandle()
+                  ->GetCommitDeferringConditionForTesting(),
+              condition);
+    return prerender_manager.GetNavigationHandle()
+               ->GetCommitDeferringConditionForTesting() == condition;
   }
 
  protected:
@@ -1119,102 +1190,140 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-// Tests that activation of prerendered pages is disabled when there is a
+// Tests that activation of a prerendered page is deferred when there is a
 // pending PasswordProtectionRequest which might trigger a modal warning.
 // This tests the case where the prerender starts before the
 // PasswordProtectionRequest.
-// TODO(https://crbug.com/1234857): The activation should be deferred rather
-// than disallowed, like other navigations.
-IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTestWithActivation,
-                       DoNotActivatePrerenderStartedBeforeRequest) {
-  SetUpPrimaryAccountWithHostedDomain(kNoHostedDomainFound);
-  // Prepare sync account will trigger a password change.
-  ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false);
-  ASSERT_TRUE(service);
+IN_PROC_BROWSER_TEST_F(
+    ChromePasswordProtectionServiceDeferActivationBrowserTest,
+    DeferActivatePrerenderStartedBeforeRequest) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(kLoginPageUrl)));
 
   // Start a prerender.
-  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
-  prerender_helper_.AddPrerender(prerender_url);
+  const GURL kPrerenderUrl = embedded_test_server()->GetURL("/simple.html");
+  prerender_helper_.AddPrerender(kPrerenderUrl);
 
-  // Start a request for a PASSWORD_REUSE_EVENT. This disables activation
-  // navigations because the throttle responsible for deferring while the
-  // request is pending cannot see the activation navigation.
-  service->StartRequest(
-      GetWebContents(), GURL(), GURL(), GURL(), "",
-      PasswordType::PASSWORD_TYPE_UNKNOWN,
-      std::vector<password_manager::MatchingReusedCredential>(),
-      LoginReputationClientRequest::PASSWORD_REUSE_EVENT, true);
+  // Start a request that could lead to showing a modal warning.
+  scoped_refptr<PasswordProtectionRequest> request =
+      StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
-  // Navigate to the prerendered URL. It will be loaded anew without an
-  // activation.
-  content::TestNavigationManager prerender_manager(GetWebContents(),
-                                                   prerender_url);
+  // Navigate to the prerendered URL. Ensure the activation navigation is
+  // deferred until the request finishes without showing a modal.
+  content::TestActivationManager prerender_manager(GetWebContents(),
+                                                   kPrerenderUrl);
+
   ASSERT_TRUE(
       content::ExecJs(GetWebContents()->GetMainFrame(),
-                      content::JsReplace("location = $1", prerender_url)));
+                      content::JsReplace("location = $1", kPrerenderUrl)));
+
+  // Run the navigation until it defers on the
+  // PasswordProtectionCommitDeferringCondition.
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), prerender_manager));
+
+  // Simulate a response arriving that doesn't show the warning dialog. The
+  // activating navigation should now be allowed to complete.
+  FinishRequest(request.get(), LoginReputationClientResponse::SAFE);
+  ASSERT_FALSE(request->is_modal_warning_showing());
   prerender_manager.WaitForNavigationFinished();
-  EXPECT_FALSE(prerender_manager.was_prerendered_page_activation());
-  EXPECT_TRUE(prerender_manager.was_successful());
+  ASSERT_TRUE(prerender_manager.was_activated());
 }
 
-// Tests that activation of prerendered pages is disabled when there is a
+// Tests that activation of a prerendered page is deferred when there is a
 // pending PasswordProtectionRequest which might trigger a modal warning.
 // This tests the case where the prerender starts after the
 // PasswordProtectionRequest.
-// TODO(https://crbug.com/1234857): The activation should be deferred rather
-// than disallowed, like other navigations.
-IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTestWithActivation,
-                       DoNotActivatePrerenderStartedAfterRequest) {
-  SetUpPrimaryAccountWithHostedDomain(kNoHostedDomainFound);
-  // Prepare sync account will trigger a password change.
-  ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false);
-  ASSERT_TRUE(service);
+IN_PROC_BROWSER_TEST_F(
+    ChromePasswordProtectionServiceDeferActivationBrowserTest,
+    DeferActivatePrerenderStartedAfterRequest) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(kLoginPageUrl)));
 
-  // Start a request for a PASSWORD_REUSE_EVENT. This disables activation
-  // navigations because the throttle responsible for deferring while the
-  // request is pending cannot see the activation navigation.
-  service->StartRequest(
-      GetWebContents(), GURL(), GURL(), GURL(), "",
-      PasswordType::PASSWORD_TYPE_UNKNOWN,
-      std::vector<password_manager::MatchingReusedCredential>(),
-      LoginReputationClientRequest::PASSWORD_REUSE_EVENT, true);
+  // Start a request that could lead to showing a modal warning.
+  scoped_refptr<PasswordProtectionRequest> request =
+      StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
-  // Start a prerender.
-  GURL prerender_url = embedded_test_server()->GetURL("/simple.html");
-  prerender_helper_.AddPrerender(prerender_url);
+  // Start a prerender; this should not be deferred since it's happening in the
+  // background.
+  const GURL kPrerenderUrl = embedded_test_server()->GetURL("/simple.html");
+  prerender_helper_.AddPrerender(kPrerenderUrl);
 
-  // Navigate to the prerendered URL. It will be loaded anew without an
-  // activation.
-  content::TestNavigationManager prerender_manager(GetWebContents(),
-                                                   prerender_url);
+  ASSERT_NE(prerender_helper_.GetHostForUrl(kPrerenderUrl),
+            content::RenderFrameHost::kNoFrameTreeNodeId);
+
+  // Navigate to the prerendered URL. Ensure the activation navigation is
+  // deferred until the request finishes without showing a modal.
+  content::TestActivationManager prerender_manager(GetWebContents(),
+                                                   kPrerenderUrl);
   ASSERT_TRUE(
       content::ExecJs(GetWebContents()->GetMainFrame(),
-                      content::JsReplace("location = $1", prerender_url)));
+                      content::JsReplace("location = $1", kPrerenderUrl)));
+
+  // Run the navigation until it defers on the
+  // PasswordProtectionCommitDeferringCondition.
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), prerender_manager));
+
+  // Simulate a response arriving that doesn't show the warning dialog. The
+  // activating navigation should now be allowed to complete.
+  FinishRequest(request.get(), LoginReputationClientResponse::SAFE);
+  ASSERT_FALSE(request->is_modal_warning_showing());
+
   prerender_manager.WaitForNavigationFinished();
-  EXPECT_FALSE(prerender_manager.was_prerendered_page_activation());
-  EXPECT_TRUE(prerender_manager.was_successful());
+  ASSERT_TRUE(prerender_manager.was_activated());
 }
 
-// Tests that activation of back/forward cached pages is disabled when there is
-// a pending PasswordProtectionRequest which might trigger a modal warning.
-// TODO(https://crbug.com/1234857): The activation should be deferred rather
-// than disallowed, like other navigations.
-IN_PROC_BROWSER_TEST_F(ChromePasswordProtectionServiceBrowserTestWithActivation,
-                       DoNotActivateBackForwardCache) {
-  SetUpPrimaryAccountWithHostedDomain(kNoHostedDomainFound);
+IN_PROC_BROWSER_TEST_F(
+    ChromePasswordProtectionServiceDeferActivationBrowserTest,
+    PrerenderActivationDeferredByModalWarning) {
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(kLoginPageUrl)));
 
-  // Prepare sync account will trigger a password change.
-  ChromePasswordProtectionService* service = GetService(/*is_incognito=*/false);
-  ASSERT_TRUE(service);
+  // Start a prerender.
+  const GURL kPrerenderUrl = embedded_test_server()->GetURL("/simple.html");
+  prerender_helper_.AddPrerender(kPrerenderUrl);
 
+  // Start a request that could lead to showing a modal warning.
+  scoped_refptr<PasswordProtectionRequest> request =
+      StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
+
+  // Finish the request so that it results in a modal warning being shown.
+  FinishRequest(request.get(), LoginReputationClientResponse::PHISHING);
+  ASSERT_TRUE(request->is_modal_warning_showing());
+
+  // Navigate to the prerendered URL. Ensure the activation navigation is
+  // deferred until the request finishes without showing a modal.
+  content::TestActivationManager prerender_manager(GetWebContents(),
+                                                   kPrerenderUrl);
+
+  ASSERT_TRUE(
+      content::ExecJs(GetWebContents()->GetMainFrame(),
+                      content::JsReplace("location = $1", kPrerenderUrl)));
+
+  // Run the navigation until it defers on the
+  // PasswordProtectionCommitDeferringCondition.
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), prerender_manager));
+
+  // Simulate the user dismissing the dialog. The navigation should be resumed.
+  DismissModalDialog(WarningAction::IGNORE_WARNING);
+
+  prerender_manager.WaitForNavigationFinished();
+  ASSERT_TRUE(prerender_manager.was_successful());
+}
+
+// Tests that activation of back/forward cached pages is not deferred if the
+// navigation is browser-initiated.
+// TODO(bokan): This is existing behavior but I wonder if it's intentional? The
+// user can't click any browser UI while the modal is up anyway...
+IN_PROC_BROWSER_TEST_F(
+    ChromePasswordProtectionServiceDeferActivationBrowserTest,
+    BrowserInitiatedBackForwardCacheActivation) {
   // Put a simple page in the back/forward cache.
-  GURL url_a = embedded_test_server()->GetURL("/simple.html");
+  const GURL kURLInBFCache = embedded_test_server()->GetURL("/simple.html");
   content::RenderFrameHost* rfh_a_raw =
-      ui_test_utils::NavigateToURL(browser(), url_a);
+      ui_test_utils::NavigateToURL(browser(), kURLInBFCache);
   content::RenderFrameHostWrapper rfh_a(rfh_a_raw);
   content::RenderFrameHost* rfh_b_raw = ui_test_utils::NavigateToURL(
       browser(), embedded_test_server()->GetURL(kLoginPageUrl));
@@ -1226,20 +1335,71 @@
   EXPECT_EQ(rfh_a->GetLifecycleState(),
             content::RenderFrameHost::LifecycleState::kInBackForwardCache);
 
-  // Start a request for a PASSWORD_REUSE_EVENT. This disables activation
-  // navigations because the throttle responsible for deferring while the
-  // request is pending cannot see the activation navigation.
-  service->StartRequest(
-      GetWebContents(), GURL(), GURL(), GURL(), "",
-      PasswordType::PASSWORD_TYPE_UNKNOWN,
-      std::vector<password_manager::MatchingReusedCredential>(),
-      LoginReputationClientRequest::PASSWORD_REUSE_EVENT, true);
+  // Start a request that could lead to showing a modal warning.
+  scoped_refptr<PasswordProtectionRequest> request =
+      StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
 
-  // Navigate back. It will be loaded anew without an activation.
+  content::TestActivationManager prerender_manager(GetWebContents(),
+                                                   kURLInBFCache);
+
+  // Do a browser-initiated back history navigation. This should be allowed
+  // because it is browser-initiated.
   GetWebContents()->GetController().GoBack();
-  EXPECT_TRUE(content::WaitForLoadStop(GetWebContents()));
-  ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted());
-  EXPECT_EQ(GetWebContents()->GetLastCommittedURL(), url_a);
+  ASSERT_TRUE(prerender_manager.WaitForBeforeChecks());
+
+  // The activating navigation should be unblocked.
+  prerender_manager.WaitForNavigationFinished();
+  ASSERT_TRUE(prerender_manager.was_activated());
+}
+
+// Tests that activation of back/forward cached pages from a renderer initiated
+// history navigation is deferred while there is a pending
+// PasswordProtectionRequest which might trigger a modal warning.
+IN_PROC_BROWSER_TEST_F(
+    ChromePasswordProtectionServiceDeferActivationBrowserTest,
+    DeferRendererInitiatedBackForwardCacheActivation) {
+  // Put a simple page in the back/forward cache.
+  const GURL kURLInBFCache = embedded_test_server()->GetURL("/simple.html");
+  content::RenderFrameHost* rfh_a_raw =
+      ui_test_utils::NavigateToURL(browser(), kURLInBFCache);
+  content::RenderFrameHostWrapper rfh_a(rfh_a_raw);
+  content::RenderFrameHost* rfh_b_raw = ui_test_utils::NavigateToURL(
+      browser(), embedded_test_server()->GetURL(kLoginPageUrl));
+  content::RenderFrameHostWrapper rfh_b(rfh_b_raw);
+
+  // Ensure that `rfh_a` is in the back/forward cache.
+  EXPECT_FALSE(rfh_a.IsRenderFrameDeleted());
+  EXPECT_NE(rfh_a.get(), rfh_b.get());
+  EXPECT_EQ(rfh_a->GetLifecycleState(),
+            content::RenderFrameHost::LifecycleState::kInBackForwardCache);
+
+  // Start a request that could lead to showing a modal warning.
+  scoped_refptr<PasswordProtectionRequest> request =
+      StartRequestWithPotentialForModalWarning();
+  ASSERT_TRUE(request);
+
+  // Navigate back to the URL in the BFCache. Ensure the BFCache restore is
+  // deferred until the request finishes without showing a modal.  Note: this
+  // must be a renderer-initiated history navigation. A user-initiated history
+  // navigation should not be deferred.
+  content::TestActivationManager prerender_manager(GetWebContents(),
+                                                   kURLInBFCache);
+  ASSERT_TRUE(content::ExecJs(
+      GetWebContents()->GetMainFrame(),
+      content::JsReplace("window.history.back()", kURLInBFCache)));
+
+  // Run the navigation until it defers on the
+  // PasswordProtectionCommitDeferringCondition.
+  ASSERT_TRUE(RunUntilRequestDefersCommit(request.get(), prerender_manager));
+
+  // Finish the request so that no warning is shown.
+  FinishRequest(request.get(), LoginReputationClientResponse::SAFE);
+  ASSERT_FALSE(request->is_modal_warning_showing());
+
+  // Since no modal is showing, the activating navigation should be unblocked.
+  prerender_manager.WaitForNavigationFinished();
+  ASSERT_TRUE(prerender_manager.was_activated());
 }
 
 }  // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc
index c5cf71a..567a6db 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/file_analysis_request.cc
@@ -113,7 +113,7 @@
   }
 
   file_data.hash.resize(crypto::kSHA256Length);
-  secure_hash->Finish(base::data(file_data.hash), crypto::kSHA256Length);
+  secure_hash->Finish(std::data(file_data.hash), crypto::kSHA256Length);
   file_data.hash =
       base::HexEncode(base::as_bytes(base::make_span(file_data.hash)));
 
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc
index dcf44a69..e2a5fe78 100644
--- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/notreached.h"
@@ -38,16 +37,16 @@
     NOTREACHED();
 
   std::vector<base::FilePath> critical_binaries;
-  critical_binaries.reserve(base::size(kUnversionedFiles) +
-                            base::size(kVersionedFiles));
+  critical_binaries.reserve(std::size(kUnversionedFiles) +
+                            std::size(kVersionedFiles));
 
-  for (size_t i = 0; i < base::size(kUnversionedFiles); ++i) {
+  for (size_t i = 0; i < std::size(kUnversionedFiles); ++i) {
     critical_binaries.push_back(chrome_exe_dir.Append(kUnversionedFiles[i]));
   }
 
   base::FilePath version_dir(
       chrome_exe_dir.AppendASCII(CHROME_VERSION_STRING));
-  for (size_t i = 0; i < base::size(kVersionedFiles); ++i) {
+  for (size_t i = 0; i < std::size(kVersionedFiles); ++i) {
     critical_binaries.push_back(version_dir.Append(kVersionedFiles[i]));
   }
 
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident_unittest.cc
index cddfcfd..59ca85e 100644
--- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_incident_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "components/safe_browsing/core/common/proto/csd.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -33,10 +32,10 @@
       {42, 255, 100, 53, 2},
       {64, 33, 51, 91, 210},
   };
-  for (size_t i = 0; i < base::size(certificates); ++i) {
+  for (size_t i = 0; i < std::size(certificates); ++i) {
     ClientDownloadRequest_CertificateChain_Element* element =
         certificate_chain->add_element();
-    element->set_certificate(certificates[i], base::size(certificates[i]));
+    element->set_certificate(certificates[i], std::size(certificates[i]));
   }
 
   return std::make_unique<BinaryIntegrityIncident>(std::move(incident));
diff --git a/chrome/browser/safe_browsing/incident_reporting/environment_data_collection_win.cc b/chrome/browser/safe_browsing/incident_reporting/environment_data_collection_win.cc
index 4386f5e..6b3ec6ac 100644
--- a/chrome/browser/safe_browsing/incident_reporting/environment_data_collection_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/environment_data_collection_win.cc
@@ -10,7 +10,6 @@
 #include <set>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/enterprise_util.h"
 #include "base/i18n/case_conversion.h"
 #include "base/logging.h"
@@ -292,12 +291,12 @@
     ClientIncidentReport_EnvironmentData_Process* process) {
   CollectDlls(process);
   RecordLspFeature(process);
-  CollectModuleVerificationData(kModulesToVerify, base::size(kModulesToVerify),
+  CollectModuleVerificationData(kModulesToVerify, std::size(kModulesToVerify),
                                 process);
 }
 
 void CollectPlatformOSData(ClientIncidentReport_EnvironmentData_OS* os_data) {
-  CollectRegistryData(kRegKeysToCollect, base::size(kRegKeysToCollect),
+  CollectRegistryData(kRegKeysToCollect, std::size(kRegKeysToCollect),
                       os_data->mutable_registry_key());
   CollectDomainEnrollmentData(os_data);
 }
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
index 6bd2bda1..eb96351 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/process/process.h"
@@ -103,7 +102,7 @@
       "SBIRS.DiscardedIncident",
       "SBIRS.NoDownloadIncident",
   };
-  static_assert(base::size(kHistogramNames) == NUM_DISPOSITIONS,
+  static_assert(std::size(kHistogramNames) == NUM_DISPOSITIONS,
                 "Keep kHistogramNames in sync with enum IncidentDisposition.");
   DCHECK_GE(disposition, 0);
   DCHECK_LT(disposition, NUM_DISPOSITIONS);
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
index 25c3a66..5e08418 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/safe_browsing/incident_reporting/module_integrity_unittest_util_win.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace safe_browsing {
 
@@ -13,7 +13,7 @@
     L"verifier_test_dll_2.dll",
 };
 
-const size_t kTestDllNamesCount = base::size(kTestDllNames);
+const size_t kTestDllNamesCount = std::size(kTestDllNames);
 
 const char kTestExportName[] = "DummyExport";
 
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
index fc7ca7d..0416d55 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win.cc
@@ -10,7 +10,6 @@
 #include <string>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/memory/raw_ptr.h"
@@ -322,8 +321,8 @@
 
   WCHAR module_path[MAX_PATH] = {};
   DWORD length =
-      GetModuleFileName(module_handle, module_path, base::size(module_path));
-  if (!length || length == base::size(module_path))
+      GetModuleFileName(module_handle, module_path, std::size(module_path));
+  if (!length || length == std::size(module_path))
     return false;
 
   base::MemoryMappedFile mapped_module;
diff --git a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
index 6162680..daf39c3f 100644
--- a/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/module_integrity_verifier_win_unittest.cc
@@ -13,7 +13,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/memory/raw_ptr.h"
@@ -113,8 +112,8 @@
 
     WCHAR module_path[MAX_PATH] = {};
     DWORD length =
-        GetModuleFileName(module_handle, module_path, base::size(module_path));
-    ASSERT_NE(base::size(module_path), length);
+        GetModuleFileName(module_handle, module_path, std::size(module_path));
+    ASSERT_NE(std::size(module_path), length);
     ASSERT_TRUE(disk_dll_handle_.Initialize(base::FilePath(module_path)));
   }
 
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc
index 44543b3..5b7e755 100644
--- a/chrome/browser/search/search.cc
+++ b/chrome/browser/search/search.cc
@@ -324,10 +324,8 @@
 
   // Replace the scheme with "chrome-search:", and clear the port, since
   // chrome-search is a scheme without port.
-  url::Replacements<char> replacements;
-  std::string search_scheme(chrome::kChromeSearchScheme);
-  replacements.SetScheme(search_scheme.data(),
-                         url::Component(0, search_scheme.length()));
+  GURL::Replacements replacements;
+  replacements.SetSchemeStr(chrome::kChromeSearchScheme);
   replacements.ClearPort();
 
   // If this is the URL for a server-provided NTP, replace the host with
@@ -337,8 +335,7 @@
   if (details.state == NEW_TAB_URL_VALID &&
       (MatchesOriginAndPath(url, details.url) ||
        IsMatchingServiceWorker(url, details.url))) {
-    replacements.SetHost(remote_ntp_host.c_str(),
-                         url::Component(0, remote_ntp_host.length()));
+    replacements.SetHostStr(remote_ntp_host);
   }
 
   return url.ReplaceComponents(replacements);
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index c031c45..fc53a45 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -11,7 +11,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/browser/search/instant_service.h"
@@ -163,7 +162,7 @@
       {"https://foo.com/", false, "Instant support was removed"},
   };
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const SearchTestCase& test = kTestCases[i];
     EXPECT_EQ(test.expected_result,
               ShouldAssignURLToInstantRenderer(GURL(test.url), profile()))
@@ -186,7 +185,7 @@
       {"https://foo.com/", false, "Non-exact path"},
   };
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const SearchTestCase& test = kTestCases[i];
     EXPECT_EQ(test.expected_result, ShouldUseProcessPerSiteForInstantSiteURL(
                                         GURL(test.url), profile()))
@@ -195,7 +194,7 @@
 }
 
 TEST_F(SearchTest, ProcessIsolation) {
-  for (size_t i = 0; i < base::size(kProcessIsolationTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kProcessIsolationTestCases); ++i) {
     const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
     AddTab(browser(), GURL("chrome://blank"));
     content::WebContents* contents =
@@ -232,7 +231,7 @@
 }
 
 TEST_F(SearchTest, ProcessIsolation_RendererInitiated) {
-  for (size_t i = 0; i < base::size(kProcessIsolationTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kProcessIsolationTestCases); ++i) {
     const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i];
     AddTab(browser(), GURL("chrome://blank"));
     content::WebContents* contents =
@@ -414,7 +413,7 @@
       {"", false, "Invalid URL"},
   };
 
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const SearchTestCase& test = kTestCases[i];
     EXPECT_EQ(test.expected_result, IsNTPURL(GURL(test.url)))
         << test.url << " " << test.comment;
diff --git a/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java b/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java
index 5d034bd..5c3e88e9 100644
--- a/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java
+++ b/chrome/browser/search_engines/android/java/src/org/chromium/chrome/browser/search_engines/SogouPromoDialog.java
@@ -66,7 +66,7 @@
     public SogouPromoDialog(Activity activity, @NonNull Callback<Boolean> onSelectEngine,
             @Nullable Callback<Boolean> onDismissed, @NonNull SettingsLauncher settingsLauncher) {
         super(activity);
-        mSpan = new NoUnderlineClickableSpan(activity.getResources(), (widget) -> {
+        mSpan = new NoUnderlineClickableSpan(activity, (widget) -> {
             mChoice = UserChoice.SETTINGS;
             settingsLauncher.launchSettingsActivity(getContext(), SearchEngineSettings.class);
             dismiss();
diff --git a/chrome/browser/search_engines/template_url_fetcher_unittest.cc b/chrome/browser/search_engines/template_url_fetcher_unittest.cc
index 6eaf419..3238065c 100644
--- a/chrome/browser/search_engines/template_url_fetcher_unittest.cc
+++ b/chrome/browser/search_engines/template_url_fetcher_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/search_engines/template_url_fetcher.h"
-
 #include <stddef.h>
 
 #include <memory>
@@ -12,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
@@ -20,6 +17,7 @@
 #include "chrome/browser/search_engines/template_url_service_test_util.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/search_engines/template_url.h"
+#include "components/search_engines/template_url_fetcher.h"
 #include "components/search_engines/template_url_service.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/storage_partition.h"
@@ -231,7 +229,7 @@
        keyword},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     StartDownload(test_cases[i].keyword, test_cases[i].osdd_file_name, false);
     EXPECT_EQ(1, template_url_fetcher()->requests_count())
         << test_cases[i].description;
diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
index 5f497df..9874693d 100644
--- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
@@ -1899,7 +1898,7 @@
       {NEITHER, SYNC, NEITHER, BOTH, false, 2},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(testing::Message() << "Case #" << i << std::endl);
 
     // Assert all the valid states of ExpectedTemplateURLs.
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 91b808d..8bed8ab 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/search_engines/template_url_service.h"
-
 #include <stddef.h>
 
 #include <memory>
@@ -12,7 +10,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/strings/string_split.h"
@@ -35,6 +32,7 @@
 #include "components/search_engines/search_terms_data.h"
 #include "components/search_engines/template_url.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
+#include "components/search_engines/template_url_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -1209,7 +1207,7 @@
                      "http://sugg1", "http://x/foo#query={searchTerms}",
                      "http://icon1", false, "UTF-8;UTF-16");
 
-  for (size_t i = 0; i < base::size(data); ++i) {
+  for (size_t i = 0; i < std::size(data); ++i) {
     TemplateURLService::URLVisitedDetails details = {
       GURL(data[i].url), false
     };
@@ -1231,7 +1229,7 @@
   AddKeywordWithDate("name", "x", "http://x/foo", "http://sugg1", std::string(),
                      "http://icon1", false, "UTF-8;UTF-16");
 
-  for (size_t i = 0; i < base::size(data); ++i) {
+  for (size_t i = 0; i < std::size(data); ++i) {
     TemplateURLService::URLVisitedDetails details = {
       GURL(data[i].url), false
     };
diff --git a/chrome/browser/sessions/session_restore_delegate.cc b/chrome/browser/sessions/session_restore_delegate.cc
index d7a45a5f..b6b2ad1 100644
--- a/chrome/browser/sessions/session_restore_delegate.cc
+++ b/chrome/browser/sessions/session_restore_delegate.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/sessions/session_restore_delegate.h"
 
 #include <stddef.h>
+
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/field_trial.h"
 #include "chrome/browser/sessions/session_restore_stats_collector.h"
 #include "chrome/browser/sessions/tab_loader.h"
@@ -32,7 +32,7 @@
   };
   // Prefix-match against the table above. Use strncmp to avoid allocating
   // memory to convert the URL prefix constants into std::strings.
-  for (size_t i = 0; i < base::size(kReloadableUrlPrefixes); ++i) {
+  for (size_t i = 0; i < std::size(kReloadableUrlPrefixes); ++i) {
     if (!strncmp(url.spec().c_str(), kReloadableUrlPrefixes[i],
                  strlen(kReloadableUrlPrefixes[i])))
       return true;
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/DevicePickerBottomSheetContent.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/DevicePickerBottomSheetContent.java
index 783f34f5..d627f74e 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/DevicePickerBottomSheetContent.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/send_tab_to_self/DevicePickerBottomSheetContent.java
@@ -142,7 +142,7 @@
                         R.string.send_tab_to_self_manage_devices_link, account.getEmail()),
                 new SpanApplier.SpanInfo("<link>", "</link>",
                         new NoUnderlineClickableSpan(
-                                resources, this::openManageDevicesPageInNewTab)));
+                                mContext, this::openManageDevicesPageInNewTab)));
         TextView linkView = containerView.findViewById(R.id.manage_devices_link);
         linkView.setText(linkText);
         linkView.setMovementMethod(LinkMovementMethod.getInstance());
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
index 17248e9..b3cf67f 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -287,7 +287,7 @@
         mOrderedFirstPartyOptions.add(createScreenshotFirstPartyOption());
         // TODO(crbug.com/1250871): Long Screenshots on by default; supported on Android 7.0+.
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_SHARE_LONG_SCREENSHOT)
-                && Build.VERSION.SDK_INT >= VERSION_CODES.N) {
+                && mTabProvider.hasValue() && Build.VERSION.SDK_INT >= VERSION_CODES.N) {
             mOrderedFirstPartyOptions.add(createLongScreenshotsFirstPartyOption());
         }
         if (ChromeFeatureList.isEnabled(ChromeFeatureList.LIGHTWEIGHT_REACTIONS)
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
index 22361ab..ef7bfef7 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -155,6 +155,22 @@
 
     @Test
     @MediumTest
+    public void getPropertyModels_longScreenshotEnabledNoTab_excludesLongScreenshot() {
+        Mockito.when(mTabProvider.hasValue()).thenReturn(false);
+        setUpChromeProvidedSharingOptionsProviderTest(/*isIncognito=*/false,
+                /*printingEnabled=*/true, LinkGeneration.MAX);
+        List<PropertyModel> propertyModels =
+                mChromeProvidedSharingOptionsProvider.getPropertyModels(
+                        ShareSheetPropertyModelBuilder.ALL_CONTENT_TYPES_FOR_TEST,
+                        DetailedContentType.NOT_SPECIFIED,
+                        /*isMultiWindow=*/false);
+
+        assertFalse("Property models should not contain long screenshots.",
+                propertyModelsContain(propertyModels, R.string.sharing_long_screenshot));
+    }
+
+    @Test
+    @MediumTest
     public void getPropertyModels_printingEnabledNoTab_excludesPrinting() {
         Mockito.when(mTabProvider.hasValue()).thenReturn(false);
         setUpChromeProvidedSharingOptionsProviderTest(/*isIncognito=*/false,
diff --git a/chrome/browser/shell_integration_linux_unittest.cc b/chrome/browser/shell_integration_linux_unittest.cc
index 085c8104..f984025 100644
--- a/chrome/browser/shell_integration_linux_unittest.cc
+++ b/chrome/browser/shell_integration_linux_unittest.cc
@@ -310,7 +310,7 @@
     { "http___foo_.desktop", "http://foo/bar/././../baz/././../" },
     { "http___.._.desktop", "http://../../../../" },
   };
-  for (size_t i = 0; i < base::size(test_cases); i++) {
+  for (size_t i = 0; i < std::size(test_cases); i++) {
     EXPECT_EQ(std::string(chrome::kBrowserProcessExecutableName) + "-" +
               test_cases[i].path,
               GetWebShortcutFilename(GURL(test_cases[i].url)).value()) <<
@@ -453,7 +453,7 @@
        "Categories=Image\n"
        "StartupWMClass=paint.app\n"}};
 
-  for (size_t i = 0; i < base::size(test_cases); i++) {
+  for (size_t i = 0; i < std::size(test_cases); i++) {
     SCOPED_TRACE(i);
     EXPECT_EQ(
         test_cases[i].expected_output,
@@ -532,7 +532,7 @@
        "action%%205\n"},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); i++) {
+  for (size_t i = 0; i < std::size(test_cases); i++) {
     SCOPED_TRACE(i);
     EXPECT_EQ(
         test_cases[i].expected_output,
@@ -576,7 +576,7 @@
       },
   };
 
-  for (size_t i = 0; i < base::size(test_cases); i++) {
+  for (size_t i = 0; i < std::size(test_cases); i++) {
     SCOPED_TRACE(i);
     EXPECT_EQ(test_cases[i].expected_output,
               GetDirectoryFileContents(base::ASCIIToUTF16(test_cases[i].title),
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index 87b59e8..8c177bd 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -4,9 +4,10 @@
 
 #include "chrome/browser/shell_integration_win.h"
 
-#include <windows.h>
-#include <objbase.h>
 #include <shobjidl.h>
+#include <windows.h>
+
+#include <objbase.h>
 #include <propkey.h>  // Needs to come after shobjidl.h.
 #include <stddef.h>
 #include <stdint.h>
@@ -19,7 +20,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
 #include "base/memory/weak_ptr.h"
@@ -176,7 +176,7 @@
   // populate the external protocol dialog box the user sees when invoking
   // an unknown external protocol.
   wchar_t out_buffer[1024];
-  DWORD buffer_size = base::size(out_buffer);
+  DWORD buffer_size = std::size(out_buffer);
   HRESULT hr =
       AssocQueryString(ASSOCF_IS_PROTOCOL, ASSOCSTR_FRIENDLYAPPNAME,
                        url_scheme.c_str(), NULL, out_buffer, &buffer_size);
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc
index 5fc8c9f0..822fbdb0 100644
--- a/chrome/browser/signin/chrome_signin_client_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -3,11 +3,11 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/signin/chrome_signin_client.h"
+
 #include <memory>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
@@ -423,7 +423,7 @@
     signin_metrics::ProfileSignout::
         IOS_ACCOUNT_REMOVED_FROM_DEVICE_AFTER_RESTORE,
 };
-static_assert(base::size(kSignoutSources) ==
+static_assert(std::size(kSignoutSources) ==
                   signin_metrics::ProfileSignout::NUM_PROFILE_SIGNOUT_METRICS,
               "kSignoutSources should enumerate all ProfileSignout values");
 
diff --git a/chrome/browser/signin/signin_global_error_unittest.cc b/chrome/browser/signin/signin_global_error_unittest.cc
index ca30aab..73428ef7 100644
--- a/chrome/browser/signin/signin_global_error_unittest.cc
+++ b/chrome/browser/signin/signin_global_error_unittest.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
@@ -134,8 +133,8 @@
       {GoogleServiceAuthError::SERVICE_ERROR, true},
   };
   static_assert(
-      base::size(table) == GoogleServiceAuthError::NUM_STATES -
-                               GoogleServiceAuthError::kDeprecatedStateCount,
+      std::size(table) == GoogleServiceAuthError::NUM_STATES -
+                              GoogleServiceAuthError::kDeprecatedStateCount,
       "table size should match number of auth error types");
 
   // Mark the profile with an active timestamp so profile_metrics logs it.
diff --git a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
index 8f113453..606ae6a 100644
--- a/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_browsertest.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
@@ -579,8 +578,8 @@
     base::ScopedAllowBlockingForTesting allow_blocking;
     size_t actual = base::WriteFile(
         bdict_path, reinterpret_cast<const char*>(kCorruptedBDICT),
-        base::size(kCorruptedBDICT));
-    EXPECT_EQ(base::size(kCorruptedBDICT), actual);
+        std::size(kCorruptedBDICT));
+    EXPECT_EQ(std::size(kCorruptedBDICT), actual);
   }
 
   // Attach an event to the SpellcheckService object so we can receive its
diff --git a/chrome/browser/spellchecker/spelling_service_client_unittest.cc b/chrome/browser/spellchecker/spelling_service_client_unittest.cc
index 234e3674..242397e2 100644
--- a/chrome/browser/spellchecker/spelling_service_client_unittest.cc
+++ b/chrome/browser/spellchecker/spelling_service_client_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/spellcheck/browser/spelling_service_client.h"
-
 #include <stddef.h>
 
 #include <memory>
@@ -11,7 +9,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -20,6 +17,7 @@
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "components/spellcheck/browser/pref_names.h"
+#include "components/spellcheck/browser/spelling_service_client.h"
 #include "components/spellcheck/common/spellcheck_result.h"
 #include "content/public/test/browser_task_environment.h"
 #include "net/base/load_flags.h"
@@ -115,7 +113,7 @@
     } kCountries[] = {
         {"af", "ZAF"}, {"en", "USA"},
     };
-    for (size_t i = 0; i < base::size(kCountries); ++i) {
+    for (size_t i = 0; i < std::size(kCountries); ++i) {
       if (!language.compare(kCountries[i].language)) {
         country->assign(kCountries[i].country);
         return true;
@@ -372,7 +370,7 @@
   };
   // If spellcheck is allowed, then suggest is not since spellcheck is a
   // superset of suggest.
-  for (size_t i = 0; i < base::size(kSupported); ++i) {
+  for (size_t i = 0; i < std::size(kSupported); ++i) {
     base::ListValue dictionary;
     dictionary.Append(kSupported[i]);
     pref->Set(spellcheck::prefs::kSpellCheckDictionaries, dictionary);
@@ -389,7 +387,7 @@
       "lv-LV", "nb-NO", "nl-NL", "pl-PL", "pt-BR", "pt-PT", "ro-RO", "ru-RU",
       "sk-SK", "sl-SI", "sh",    "sr",    "sv-SE", "tr-TR", "uk-UA", "vi-VN",
   };
-  for (size_t i = 0; i < base::size(kUnsupported); ++i) {
+  for (size_t i = 0; i < std::size(kUnsupported); ++i) {
     SCOPED_TRACE(std::string("Expected language ") + kUnsupported[i]);
     base::ListValue dictionary;
     dictionary.Append(kUnsupported[i]);
diff --git a/chrome/browser/ssl/sct_reporting_service.cc b/chrome/browser/ssl/sct_reporting_service.cc
index 3338c81..eb5e1e1 100644
--- a/chrome/browser/ssl/sct_reporting_service.cc
+++ b/chrome/browser/ssl/sct_reporting_service.cc
@@ -10,6 +10,8 @@
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/storage_partition.h"
@@ -98,6 +100,11 @@
     "https://sctauditing-pa.googleapis.com/v1/knownscts/"
     "length/$1/prefix/$2?key=";
 
+// The maximum number of reports currently allowed to be sent by hashdance
+// clients, browser-wide. When this limit is reached, no more auditing reports
+// will be sent by the client.
+constexpr int kSCTAuditingHashdanceMaxReports = 3;
+
 // static
 GURL& SCTReportingService::GetReportURLInstance() {
   static base::NoDestructor<GURL> instance(kSBSCTAuditingReportURL);
@@ -124,6 +131,37 @@
       net::MutableNetworkTrafficAnnotationTag(kSCTHashdanceTrafficAnnotation));
 }
 
+// static
+bool SCTReportingService::CanSendSCTAuditingReport() {
+  PrefService* local_state = g_browser_process->local_state();
+  if (!local_state) {
+    // Fail safe by returning `false` if we can't get the pref state.
+    return false;
+  }
+  int report_count =
+      local_state->GetInteger(prefs::kSCTAuditingHashdanceReportCount);
+  return report_count < kSCTAuditingHashdanceMaxReports;
+}
+
+// static
+void SCTReportingService::OnNewSCTAuditingReportSent() {
+  PrefService* local_state = g_browser_process->local_state();
+  if (!local_state) {
+    return;
+  }
+  int report_count =
+      local_state->GetInteger(prefs::kSCTAuditingHashdanceReportCount);
+
+  // We should not ever send more than kSCTAuditingHashdanceMaxReports full
+  // reports. DCHECK to make it very clear in testing if this is not the case.
+  DCHECK_LE(report_count, kSCTAuditingHashdanceMaxReports);
+
+  // Note: Pref updates won't be persisted for Incognito profiles, but SCT
+  // auditing is disabled entirely for Incognito profiles.
+  local_state->SetInteger(prefs::kSCTAuditingHashdanceReportCount,
+                          ++report_count);
+}
+
 SCTReportingService::SCTReportingService(
     safe_browsing::SafeBrowsingService* safe_browsing_service,
     Profile* profile)
diff --git a/chrome/browser/ssl/sct_reporting_service.h b/chrome/browser/ssl/sct_reporting_service.h
index 0daf156..227c8a2 100644
--- a/chrome/browser/ssl/sct_reporting_service.h
+++ b/chrome/browser/ssl/sct_reporting_service.h
@@ -33,6 +33,13 @@
   static GURL& GetHashdanceLookupQueryURLInstance();
   static void ReconfigureAfterNetworkRestart();
 
+  // Returns whether the browser can send another SCT auditing report (i.e.,
+  // whether the maximum report limit has been reached).
+  static bool CanSendSCTAuditingReport();
+  // Notification that a new SCT auditing report has been sent. Used to keep
+  // track a browser-wide report count.
+  static void OnNewSCTAuditingReportSent();
+
   SCTReportingService(safe_browsing::SafeBrowsingService* safe_browsing_service,
                       Profile* profile);
   ~SCTReportingService() override;
diff --git a/chrome/browser/ssl/sct_reporting_service_browsertest.cc b/chrome/browser/ssl/sct_reporting_service_browsertest.cc
index 764ee0b..b9555bf 100644
--- a/chrome/browser/ssl/sct_reporting_service_browsertest.cc
+++ b/chrome/browser/ssl/sct_reporting_service_browsertest.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/ssl/sct_reporting_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
@@ -184,19 +185,19 @@
         net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions1",
         "signature1", base::Time::Now(),
         std::string(reinterpret_cast<const char*>(kTestGoogleLogId),
-                    base::size(kTestGoogleLogId)),
+                    std::size(kTestGoogleLogId)),
         net::ct::SCT_STATUS_OK, &verify_result.scts);
     MakeTestSCTAndStatus(
         net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions2",
         "signature2", base::Time::Now(),
         std::string(reinterpret_cast<const char*>(kTestNonGoogleLogId1),
-                    base::size(kTestNonGoogleLogId1)),
+                    std::size(kTestNonGoogleLogId1)),
         net::ct::SCT_STATUS_OK, &verify_result.scts);
     MakeTestSCTAndStatus(
         net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions3",
         "signature3", base::Time::Now(),
         std::string(reinterpret_cast<const char*>(kTestNonGoogleLogId2),
-                    base::size(kTestNonGoogleLogId2)),
+                    std::size(kTestNonGoogleLogId2)),
         net::ct::SCT_STATUS_OK, &verify_result.scts);
 
     // Set up two test hosts as using publicly-issued certificates for testing.
@@ -574,19 +575,19 @@
       net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions1",
       "signature1", base::Time::Now(),
       std::string(reinterpret_cast<const char*>(kTestGoogleLogId),
-                  base::size(kTestGoogleLogId)),
+                  std::size(kTestGoogleLogId)),
       net::ct::SCT_STATUS_OK, &verify_result.scts);
   MakeTestSCTAndStatus(
       net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions2",
       "signature2", base::Time::Now(),
       std::string(reinterpret_cast<const char*>(kTestNonGoogleLogId1),
-                  base::size(kTestNonGoogleLogId1)),
+                  std::size(kTestNonGoogleLogId1)),
       net::ct::SCT_STATUS_OK, &verify_result.scts);
   MakeTestSCTAndStatus(
       net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions3",
       "signature3", base::Time::Now(),
       std::string(reinterpret_cast<const char*>(kTestNonGoogleLogId2),
-                  base::size(kTestNonGoogleLogId2)),
+                  std::size(kTestNonGoogleLogId2)),
       net::ct::SCT_STATUS_OK, &verify_result.scts);
   mock_cert_verifier()->AddResultForCertAndHost(
       https_server()->GetCertificate().get(), "a.test", verify_result, net::OK);
@@ -878,7 +879,7 @@
         net::ct::SignedCertificateTimestamp::SCT_EMBEDDED, "extensions1",
         "signature1", base::Time::UnixEpoch(),
         std::string(reinterpret_cast<const char*>(kTestGoogleLogId),
-                    base::size(kTestGoogleLogId)),
+                    std::size(kTestGoogleLogId)),
         net::ct::SCT_STATUS_OK, &verify_result.scts);
     mock_cert_verifier()->AddResultForCertAndHost(
         https_server()->GetCertificate().get(), "hashdance.test", verify_result,
@@ -933,3 +934,38 @@
   // No requests should have been sent.
   EXPECT_TRUE(FlushAndCheckZeroReports(/*requests_so_far=*/1));
 }
+
+IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest,
+                       HashdanceReportCountIncremented) {
+  // Visit an HTTPS page and wait for the full report to be sent.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), https_server()->GetURL("hashdance.test", "/")));
+  WaitForRequests(2);
+
+  // Check that two requests (lookup and full report) were sent and the report
+  // contains the expected details.
+  EXPECT_EQ(2u, requests_seen());
+  EXPECT_EQ(
+      "hashdance.test",
+      GetLastSeenReport().certificate_report(0).context().origin().hostname());
+
+  // Check that the report count got incremented.
+  int report_count = g_browser_process->local_state()->GetInteger(
+      prefs::kSCTAuditingHashdanceReportCount);
+  EXPECT_EQ(report_count, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(SCTHashdanceBrowserTest, HashdanceReportLimitReached) {
+  // Override the report count to be the maximum.
+  g_browser_process->local_state()->SetInteger(
+      prefs::kSCTAuditingHashdanceReportCount, 3);
+
+  // Visit an HTTPS page.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), https_server()->GetURL("hashdance.test", "/")));
+
+  // Check that no reports are sent.
+  EXPECT_EQ(0u, requests_seen());
+  SetSafeBrowsingEnabled(false);  // Clears the deduplication cache.
+  EXPECT_TRUE(FlushAndCheckZeroReports());
+}
diff --git a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc
index 79db121..9e3edc4f 100644
--- a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc
+++ b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/supervised_user/child_accounts/family_info_fetcher.h"
 
 #include <stddef.h>
+
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
@@ -106,7 +106,7 @@
 bool FamilyInfoFetcher::StringToRole(
     const std::string& str,
     FamilyInfoFetcher::FamilyMemberRole* role) {
-  for (size_t i = 0; i < base::size(kFamilyMemberRoleStrings); i++) {
+  for (size_t i = 0; i < std::size(kFamilyMemberRoleStrings); i++) {
     if (str == kFamilyMemberRoleStrings[i]) {
       *role = FamilyMemberRole(i);
       return true;
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_mac_win_linux.cc b/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_mac_win_linux.cc
index 1845804..db6788b4 100644
--- a/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_mac_win_linux.cc
+++ b/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_mac_win_linux.cc
@@ -18,18 +18,9 @@
 using TwoClientWebAppsIntegrationTestMacWinLinux =
     TwoClientWebAppsIntegrationTestBase;
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -45,18 +36,9 @@
   helper_.CheckLaunchIconShown();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -71,18 +53,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -95,18 +68,9 @@
   helper_.CheckTabCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -120,18 +84,9 @@
   helper_.CheckLaunchIconNotShown();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -147,18 +102,9 @@
   helper_.CheckLaunchIconShown();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -173,18 +119,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -197,17 +134,9 @@
   helper_.CheckTabCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -221,18 +150,9 @@
   helper_.CheckLaunchIconNotShown();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20 \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_37SiteA_17_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -248,18 +168,9 @@
   helper_.CheckLaunchIconShown();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24 \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_34SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -274,18 +185,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22 \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_34SiteA_22) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -298,18 +200,9 @@
   helper_.CheckTabCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19 \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_37SiteA_18_19) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -370,19 +263,9 @@
   helper_.CheckTabCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20 \
-  DISABLED_WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20
-#else
-#define MAYBE_WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20 \
-  WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20
-#endif
-
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20) {
+    WebAppIntegration_30SiteC_12SiteC_40Client2_45SiteC_46SiteC_12SiteC_37SiteC_17_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -413,9 +296,8 @@
   helper_.CheckLaunchIconNotShown();
 }
 
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestMacWinLinux,
-    DISABLED_WebAppIntegration_41_30SiteA_42_40Client2_45SiteA) {
+IN_PROC_BROWSER_TEST_F(TwoClientWebAppsIntegrationTestMacWinLinux,
+                       WebAppIntegration_41_30SiteA_42_40Client2_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -426,9 +308,8 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestMacWinLinux,
-    DISABLED_WebAppIntegration_41_31SiteA_42_40Client2_45SiteA) {
+IN_PROC_BROWSER_TEST_F(TwoClientWebAppsIntegrationTestMacWinLinux,
+                       WebAppIntegration_41_31SiteA_42_40Client2_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -439,17 +320,8 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// Flaky, see https://crbug.com/1273666
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_41_47SiteA_42_40Client2_45SiteA \
-  DISABLED_WebAppIntegration_41_47SiteA_42_40Client2_45SiteA
-#else
-#define MAYBE_WebAppIntegration_41_47SiteA_42_40Client2_45SiteA \
-  WebAppIntegration_41_47SiteA_42_40Client2_45SiteA
-#endif
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_41_47SiteA_42_40Client2_45SiteA) {
+IN_PROC_BROWSER_TEST_F(TwoClientWebAppsIntegrationTestMacWinLinux,
+                       WebAppIntegration_41_47SiteA_42_40Client2_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -472,17 +344,8 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_41_30SiteC_42_40Client2_45SiteC \
-  DISABLED_WebAppIntegration_41_30SiteC_42_40Client2_45SiteC
-#else
-#define MAYBE_WebAppIntegration_41_30SiteC_42_40Client2_45SiteC \
-  WebAppIntegration_41_30SiteC_42_40Client2_45SiteC
-#endif
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_41_30SiteC_42_40Client2_45SiteC) {
+IN_PROC_BROWSER_TEST_F(TwoClientWebAppsIntegrationTestMacWinLinux,
+                       WebAppIntegration_41_30SiteC_42_40Client2_45SiteC) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -505,18 +368,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteC");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -531,18 +385,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -557,18 +402,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24 \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_46SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -583,18 +419,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -609,18 +436,9 @@
   helper_.CheckAppNotInList("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -635,18 +453,9 @@
   helper_.CheckAppNotInList("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_10SiteA_15SiteA_40Client1_15SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -677,18 +486,9 @@
   helper_.CheckAppNotInList("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -703,18 +503,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -729,17 +520,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_10SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -770,18 +553,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
+    WebAppIntegration_30SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -796,18 +570,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
+    WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -822,18 +587,9 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-// TODO(crbug.com/1273666): Test failed on Mac.
-// TODO(crbug.com/1281950): Browsers size failure on Mac.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  DISABLED_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#else
-#define MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA \
-  WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestMacWinLinux,
-    MAYBE_WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
+    WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_43SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_win.cc b/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_win.cc
index 950273b..59ce1280 100644
--- a/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_win.cc
+++ b/chrome/browser/sync/test/integration/two_client_web_apps_integration_test_win.cc
@@ -34,22 +34,6 @@
 
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestWin,
-    WebAppIntegration_30SiteA_24_12SiteA_87SiteA_15SiteA_37SiteA_18_19) {
-  // Test contents are generated by script. Please do not modify!
-  // See `chrome/test/webapps/README.md` for more info.
-  // Sheriffs: Disabling this test is supported.
-  helper_.InstallCreateShortcutWindowed("SiteA");
-  helper_.CheckWindowCreated();
-  helper_.CheckAppInListWindowed("SiteA");
-  helper_.UninstallFromOs("SiteA");
-  helper_.CheckAppNotInList("SiteA");
-  helper_.NavigateBrowser("SiteA");
-  helper_.CheckInstallIconShown();
-  helper_.CheckLaunchIconNotShown();
-}
-
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestWin,
     WebAppIntegration_31SiteA_24_12SiteA_40Client2_45SiteA_41_87SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
@@ -67,22 +51,6 @@
 
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestWin,
-    WebAppIntegration_31SiteA_24_12SiteA_87SiteA_15SiteA_37SiteA_18_19) {
-  // Test contents are generated by script. Please do not modify!
-  // See `chrome/test/webapps/README.md` for more info.
-  // Sheriffs: Disabling this test is supported.
-  helper_.InstallOmniboxIcon("SiteA");
-  helper_.CheckWindowCreated();
-  helper_.CheckAppInListWindowed("SiteA");
-  helper_.UninstallFromOs("SiteA");
-  helper_.CheckAppNotInList("SiteA");
-  helper_.NavigateBrowser("SiteA");
-  helper_.CheckInstallIconShown();
-  helper_.CheckLaunchIconNotShown();
-}
-
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestWin,
     WebAppIntegration_47SiteA_24_12SiteA_40Client2_45SiteA_41_87SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
@@ -100,22 +68,6 @@
 
 IN_PROC_BROWSER_TEST_F(
     TwoClientWebAppsIntegrationTestWin,
-    WebAppIntegration_47SiteA_24_12SiteA_87SiteA_15SiteA_37SiteA_18_19) {
-  // Test contents are generated by script. Please do not modify!
-  // See `chrome/test/webapps/README.md` for more info.
-  // Sheriffs: Disabling this test is supported.
-  helper_.InstallMenuOption("SiteA");
-  helper_.CheckWindowCreated();
-  helper_.CheckAppInListWindowed("SiteA");
-  helper_.UninstallFromOs("SiteA");
-  helper_.CheckAppNotInList("SiteA");
-  helper_.NavigateBrowser("SiteA");
-  helper_.CheckInstallIconShown();
-  helper_.CheckLaunchIconNotShown();
-}
-
-IN_PROC_BROWSER_TEST_F(
-    TwoClientWebAppsIntegrationTestWin,
     WebAppIntegration_29SiteA_11SiteA_40Client2_45SiteA_41_87SiteA_42_45SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
@@ -130,16 +82,5 @@
   helper_.CheckAppInListNotLocallyInstalled("SiteA");
 }
 
-IN_PROC_BROWSER_TEST_F(TwoClientWebAppsIntegrationTestWin,
-                       WebAppIntegration_30SiteC_12SiteC_87SiteC_15SiteA) {
-  // Test contents are generated by script. Please do not modify!
-  // See `chrome/test/webapps/README.md` for more info.
-  // Sheriffs: Disabling this test is supported.
-  helper_.InstallCreateShortcutWindowed("SiteC");
-  helper_.CheckAppInListWindowed("SiteC");
-  helper_.UninstallFromOs("SiteC");
-  helper_.CheckAppNotInList("SiteA");
-}
-
 }  // namespace
 }  // namespace web_app
diff --git a/chrome/browser/sync_file_system/drive_backend/leveldb_wrapper_unittest.cc b/chrome/browser/sync_file_system/drive_backend/leveldb_wrapper_unittest.cc
index dc48f9c..b16dd70 100644
--- a/chrome/browser/sync_file_system/drive_backend/leveldb_wrapper_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/leveldb_wrapper_unittest.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/strings/string_number_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -47,7 +46,7 @@
     // Expected contents are
     // {"a": "1", "ab": "0", "bb": "3", "d": "4"}
     const char* keys[] = {"ab", "a", "d", "bb", "d"};
-    for (size_t i = 0; i < base::size(keys); ++i) {
+    for (size_t i = 0; i < std::size(keys); ++i) {
       leveldb::Status status =
           db->Put(leveldb::WriteOptions(), keys[i], base::NumberToString(i));
       ASSERT_TRUE(status.ok());
@@ -176,7 +175,7 @@
   GetDB()->Put("bb", "new2");  // Overwrite an entry.
 
   SCOPED_TRACE("PutTest_Pending");
-  CheckDBContents(merged_data, base::size(merged_data));
+  CheckDBContents(merged_data, std::size(merged_data));
 
   EXPECT_EQ(3, GetDB()->num_puts());
   // Remove all pending transactions.
@@ -184,7 +183,7 @@
   EXPECT_EQ(0, GetDB()->num_puts());
 
   SCOPED_TRACE("PutTest_Clear");
-  CheckDBContents(orig_data, base::size(orig_data));
+  CheckDBContents(orig_data, std::size(orig_data));
 
   // Add pending transactions again, with commiting.
   GetDB()->Put("aa", "new0");
@@ -196,7 +195,7 @@
   GetDB()->Clear();  // Clear just in case.
 
   SCOPED_TRACE("PutTest_Commit");
-  CheckDBContents(merged_data, base::size(merged_data));
+  CheckDBContents(merged_data, std::size(merged_data));
 }
 
 TEST_F(LevelDBWrapperTest, DeleteTest) {
@@ -217,13 +216,13 @@
   EXPECT_EQ(2, GetDB()->num_deletes());
 
   SCOPED_TRACE("DeleteTest_Pending");
-  CheckDBContents(merged_data, base::size(merged_data));
+  CheckDBContents(merged_data, std::size(merged_data));
 
   // Remove all pending transactions.
   GetDB()->Clear();
 
   SCOPED_TRACE("DeleteTest_Clear");
-  CheckDBContents(orig_data, base::size(orig_data));
+  CheckDBContents(orig_data, std::size(orig_data));
 
   // Add pending transactions again, with commiting.
   GetDB()->Put("aa", "new0");
@@ -238,7 +237,7 @@
   EXPECT_EQ(0, GetDB()->num_deletes());
 
   SCOPED_TRACE("DeleteTest_Commit");
-  CheckDBContents(merged_data, base::size(merged_data));
+  CheckDBContents(merged_data, std::size(merged_data));
 }
 
 }  // namespace drive_backend
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
index 94dad84f..7e5626a 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
@@ -731,7 +731,7 @@
   };
 
   int64_t num_deletes_before = db_->num_deletes();
-  for (size_t i = 0; i < base::size(kIndexPrefixes); ++i)
+  for (size_t i = 0; i < std::size(kIndexPrefixes); ++i)
     DeleteKeyStartsWith(kIndexPrefixes[i]);
   num_dirty_trackers_ = 0;
   return db_->num_deletes() - num_deletes_before;
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
index 0cb4763..87b791ac 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -12,8 +12,6 @@
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/task_environment.h"
@@ -675,11 +673,11 @@
     &sync_root, &app_root, &file, &folder, &file_in_folder, &orphaned_file
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
 
   orphaned_file.should_be_absent = true;
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 }
 
 TEST_P(MetadataDatabaseTest, AppManagementTest) {
@@ -695,9 +693,9 @@
   const TrackedFile* tracked_files[] = {
     &sync_root, &app_root, &file, &folder,
   };
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 
   folder.tracker.set_app_id("foo");
   EXPECT_EQ(SYNC_STATUS_OK, RegisterApp(
@@ -912,7 +910,7 @@
     &new_file,
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
 
   ApplyRenameChangeToMetadata("renamed", &renamed_file.metadata);
@@ -949,7 +947,7 @@
 
   new_file.should_be_absent = false;
 
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -971,9 +969,9 @@
     &sync_root, &app_root, &folder_to_populate, &known_file, &new_file
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 
   FileIDList listed_children;
   listed_children.push_back(known_file.metadata.file_id());
@@ -991,7 +989,7 @@
   new_file.tracker.clear_synced_details();
   new_file.should_be_absent = false;
   new_file.tracker_only = true;
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -1011,9 +1009,9 @@
     &sync_root, &app_root, &inactive_folder, &new_file,
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 
   FileIDList listed_children;
   listed_children.push_back(new_file.metadata.file_id());
@@ -1021,7 +1019,7 @@
   EXPECT_EQ(SYNC_STATUS_OK,
             PopulateFolder(inactive_folder.metadata.file_id(),
                            listed_children));
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -1040,9 +1038,9 @@
     &sync_root, &disabled_app_root, &disabled_app_root, &known_file, &file,
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 
   FileIDList disabled_app_children;
   disabled_app_children.push_back(file.metadata.file_id());
@@ -1057,7 +1055,7 @@
 
   disabled_app_root.tracker.set_dirty(false);
   disabled_app_root.tracker.set_needs_folder_listing(false);
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -1083,15 +1081,15 @@
     &sync_root, &app_root, &file, &inactive_file, &new_conflict
   };
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 
   *file.tracker.mutable_synced_details() = file.metadata.details();
   file.tracker.set_dirty(false);
   EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(file.tracker));
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 
   *inactive_file.tracker.mutable_synced_details() =
@@ -1099,7 +1097,7 @@
   inactive_file.tracker.set_dirty(false);
   inactive_file.tracker.set_active(true);
   EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(inactive_file.tracker));
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 
   *new_conflict.tracker.mutable_synced_details() =
@@ -1109,7 +1107,7 @@
   file.tracker.set_dirty(true);
   file.tracker.set_active(false);
   EXPECT_EQ(SYNC_STATUS_OK, UpdateTracker(new_conflict.tracker));
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -1140,7 +1138,7 @@
   ResetTrackerID(&app_root.tracker);
   app_root.tracker.set_parent_tracker_id(sync_root.tracker.tracker_id());
 
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
   VerifyReloadConsistency();
 }
 
@@ -1155,9 +1153,9 @@
   const TrackedFile* tracked_files[] = {&sync_root, &app_root, &folder_0,
                                         &file_0};
 
-  SetUpDatabaseByTrackedFiles(tracked_files, base::size(tracked_files));
+  SetUpDatabaseByTrackedFiles(tracked_files, std::size(tracked_files));
   EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
-  VerifyTrackedFiles(tracked_files, base::size(tracked_files));
+  VerifyTrackedFiles(tracked_files, std::size(tracked_files));
 
   std::unique_ptr<base::ListValue> files =
       metadata_database()->DumpFiles(app_root.tracker.app_id());
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
index 930503c..04fbac3a 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine_unittest.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/sync_file_system/drive_backend/sync_engine.h"
 
 #include <stddef.h>
+
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
 #include "base/task/post_task.h"
@@ -217,7 +217,7 @@
     {REMOTE_SERVICE_DISABLED, "DISABLED"},
   };
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     PostUpdateServiceState(test_data[i].state, test_data[i].description);
     EXPECT_EQ(test_data[i].state, sync_engine()->GetCurrentState())
         << "Expected state: REMOTE_SERVICE_" << test_data[i].description;
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
index 38194b25..947a1bd2 100644
--- a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
+++ b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
@@ -810,7 +810,7 @@
 
   // Create kFile1 and populate it with kTestFileData0.
   EXPECT_EQ(base::File::FILE_OK, file_system.CreateFile(kFile1));
-  EXPECT_EQ(static_cast<int64_t>(base::size(kTestFileData0) - 1),
+  EXPECT_EQ(static_cast<int64_t>(std::size(kTestFileData0) - 1),
             file_system.WriteString(kFile1, kTestFileData0));
 
   // kFile2 and kDir are not there yet.
@@ -830,12 +830,12 @@
   const base::FilePath kFilePath1(temp_dir.GetPath().Append(FPL("file1")));
   const base::FilePath kFilePath2(temp_dir.GetPath().Append(FPL("file2")));
 
-  ASSERT_EQ(static_cast<int>(base::size(kTestFileData1) - 1),
+  ASSERT_EQ(static_cast<int>(std::size(kTestFileData1) - 1),
             base::WriteFile(kFilePath1, kTestFileData1,
-                            base::size(kTestFileData1) - 1));
-  ASSERT_EQ(static_cast<int>(base::size(kTestFileData2) - 1),
+                            std::size(kTestFileData1) - 1));
+  ASSERT_EQ(static_cast<int>(std::size(kTestFileData2) - 1),
             base::WriteFile(kFilePath2, kTestFileData2,
-                            base::size(kTestFileData2) - 1));
+                            std::size(kTestFileData2) - 1));
 
   // Record the usage.
   int64_t usage = -1, new_usage = -1;
@@ -866,7 +866,7 @@
 
   // Check if the usage has been increased by (kTestFileData1 - kTestFileData0).
   const int updated_size =
-      base::size(kTestFileData1) - base::size(kTestFileData0);
+      std::size(kTestFileData1) - std::size(kTestFileData0);
   EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(updated_size, new_usage - usage);
@@ -917,7 +917,7 @@
   EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_GT(new_usage,
-            static_cast<int64_t>(usage + base::size(kTestFileData2) - 1));
+            static_cast<int64_t>(usage + std::size(kTestFileData2) - 1));
 
   // The changes applied by ApplyRemoteChange should not be recorded in
   // the change tracker.
@@ -962,8 +962,8 @@
   // Prepare a temporary file which represents remote file data.
   const base::FilePath kFilePath(temp_dir.GetPath().Append(FPL("file")));
   ASSERT_EQ(
-      static_cast<int>(base::size(kTestFileData) - 1),
-      base::WriteFile(kFilePath, kTestFileData, base::size(kTestFileData) - 1));
+      static_cast<int>(std::size(kTestFileData) - 1),
+      base::WriteFile(kFilePath, kTestFileData, std::size(kTestFileData) - 1));
 
   // Calling ApplyChange's with kFilePath should create
   // kFile along with kDir.
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc
index a7c9add..f1d3b51 100644
--- a/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc
+++ b/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc
@@ -234,7 +234,7 @@
   const FileSystemURL kFile(file_system_->URL("file"));
   const FileSystemURL kDir(file_system_->URL("dir"));
   const char kTestFileData[] = "0123456789";
-  const int kTestFileDataSize = static_cast<int>(base::size(kTestFileData) - 1);
+  const int kTestFileDataSize = static_cast<int>(std::size(kTestFileData) - 1);
 
   base::FilePath local_path;
   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &local_path));
@@ -294,7 +294,7 @@
   const FileSystemURL kFile(file_system_->URL("file"));
   const FileSystemURL kDir(file_system_->URL("dir"));
   const char kTestFileData[] = "0123456789";
-  const int kTestFileDataSize = static_cast<int>(base::size(kTestFileData) - 1);
+  const int kTestFileDataSize = static_cast<int>(std::size(kTestFileData) - 1);
 
   EXPECT_EQ(base::File::FILE_OK, file_system_->CreateFile(kFile));
 
@@ -352,7 +352,7 @@
 TEST_F(LocalFileSyncServiceTest, ProcessLocalChange_CreateFile) {
   const FileSystemURL kFile(file_system_->URL("foo"));
   const char kTestFileData[] = "0123456789";
-  const int kTestFileDataSize = static_cast<int>(base::size(kTestFileData) - 1);
+  const int kTestFileDataSize = static_cast<int>(std::size(kTestFileData) - 1);
 
   base::RunLoop run_loop;
 
@@ -655,7 +655,7 @@
 
   const GURL kOrigins[] = { kOrigin1, kOrigin2, kOrigin3 };
   std::set<GURL> all_origins;
-  all_origins.insert(kOrigins, kOrigins + base::size(kOrigins));
+  all_origins.insert(kOrigins, kOrigins + std::size(kOrigins));
 
   GURL origin;
   while (!all_origins.empty()) {
@@ -692,7 +692,7 @@
   SetOriginChangeCount(kOrigin2, 8);
   ASSERT_EQ(1 + 4 + 8, GetTotalChangeCount());
 
-  all_origins.insert(kOrigins, kOrigins + base::size(kOrigins));
+  all_origins.insert(kOrigins, kOrigins + std::size(kOrigins));
   while (!all_origins.empty()) {
     ASSERT_TRUE(NextOriginToProcess(&origin));
     ASSERT_TRUE(base::Contains(all_origins, origin));
@@ -715,7 +715,7 @@
   ASSERT_EQ(1 + 2 + 4, GetTotalChangeCount());
 
   std::set<GURL> all_origins;
-  all_origins.insert(kOrigins, kOrigins + base::size(kOrigins));
+  all_origins.insert(kOrigins, kOrigins + std::size(kOrigins));
 
   GURL origin;
   while (!all_origins.empty()) {
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/SadTab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/SadTab.java
index d284bd0..bcf5885 100644
--- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/SadTab.java
+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/SadTab.java
@@ -191,11 +191,10 @@
      */
     private static CharSequence getHelpMessage(
             Context context, final Runnable suggestionAction, final boolean showSendFeedback) {
-        NoUnderlineClickableSpan linkSpan =
-                new NoUnderlineClickableSpan(context.getResources(), (view) -> {
-                    recordEvent(showSendFeedback, SadTabEvent.HELP_LINK_CLICKED);
-                    suggestionAction.run();
-                });
+        NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(context, (view) -> {
+            recordEvent(showSendFeedback, SadTabEvent.HELP_LINK_CLICKED);
+            suggestionAction.run();
+        });
 
         if (showSendFeedback) {
             SpannableString learnMoreLink =
diff --git a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
index a51286c4..35c75d3 100644
--- a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/path_service.h"
@@ -73,7 +72,7 @@
     },
 };
 
-const size_t kTestPagesLength = base::size(kTestPages);
+const size_t kTestPagesLength = std::size(kTestPages);
 
 // Blocks till the current page uses a specific icon URL.
 class FaviconWaiter : public favicon::FaviconDriverObserver {
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 2a16c7cf9..b32c810 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -219,7 +219,7 @@
     // /!\ If you make any changes here, you must also increment
     // kThemePackVersion above, or else themes will display incorrectly.
 };
-const size_t kTintTableLength = base::size(kTintTable);
+const size_t kTintTableLength = std::size(kTintTable);
 
 // Strings used by themes to identify colors in the JSON.
 constexpr StringToIntTable kOverwritableColorTable[] = {
@@ -258,7 +258,7 @@
     // kThemePackVersion above, or else themes will display incorrectly.
 };
 constexpr size_t kOverwritableColorTableLength =
-    base::size(kOverwritableColorTable);
+    std::size(kOverwritableColorTable);
 
 // Colors generated based on the theme, but not overwritable in the theme file.
 constexpr int kNonOverwritableColorTable[] = {
@@ -279,7 +279,7 @@
     // kThemePackVersion above, or else themes will display incorrectly.
 };
 constexpr size_t kNonOverwritableColorTableLength =
-    base::size(kNonOverwritableColorTable);
+    std::size(kNonOverwritableColorTable);
 
 // The maximum number of colors we may need to store (includes ones that can be
 // specified by the theme, and ones that we calculate but can't be specified).
@@ -295,7 +295,7 @@
     // /!\ If you make any changes here, you must also increment
     // kThemePackVersion above, or else themes will display incorrectly.
 };
-const size_t kDisplayPropertiesSize = base::size(kDisplayProperties);
+const size_t kDisplayPropertiesSize = std::size(kDisplayProperties);
 
 int GetIntForString(const std::string& key,
                     const StringToIntTable* table,
@@ -1180,7 +1180,7 @@
 
   // Generate raw images (for new-tab-page attribution and background) for
   // any missing scale from an available scale image.
-  for (size_t i = 0; i < base::size(kPreloadIDs); ++i) {
+  for (size_t i = 0; i < std::size(kPreloadIDs); ++i) {
     GenerateRawImageForAllSupportedScales(kPreloadIDs[i]);
   }
 
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index 08f0a53..62261da 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -116,6 +116,9 @@
        kColorDownloadShelfButtonBackground},
       {TP::COLOR_DOWNLOAD_SHELF_BUTTON_TEXT, kColorDownloadShelfButtonText},
       {TP::COLOR_LOCATION_BAR_BORDER, kColorLocationBarBorder},
+      {TP::COLOR_NTP_BACKGROUND, kColorNewTabPageBackground},
+      {TP::COLOR_NTP_HEADER, kColorNewTabPageHeader},
+      {TP::COLOR_NTP_TEXT, kColorNewTabPageText},
       {TP::COLOR_OMNIBOX_BACKGROUND, kColorOmniboxBackground},
       {TP::COLOR_OMNIBOX_BACKGROUND_HOVERED, kColorOmniboxBackgroundHovered},
       {TP::COLOR_OMNIBOX_BUBBLE_OUTLINE, kColorOmniboxBubbleOutline},
diff --git a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
index 22599d3..260beb7 100644
--- a/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
+++ b/chrome/browser/translate/translate_manager_render_view_host_unittest.cc
@@ -514,7 +514,7 @@
 // Test the fetching of languages from the translate server
 TEST_F(TranslateManagerRenderViewHostTest, FetchLanguagesFromTranslateServer) {
   std::vector<std::string> server_languages;
-  for (size_t i = 0; i < base::size(kServerLanguageList); ++i)
+  for (size_t i = 0; i < std::size(kServerLanguageList); ++i)
     server_languages.push_back(kServerLanguageList[i]);
 
   // First, get the default languages list. Note that calling
diff --git a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java
index 03aeada..cefe086 100644
--- a/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java
+++ b/chrome/browser/ui/android/autofill/internal/java/src/org/chromium/chrome/browser/ui/autofill/OtpVerificationDialogView.java
@@ -158,7 +158,7 @@
                         org.chromium.chrome.browser.ui.autofill.internal.R.string
                                 .autofill_payments_otp_verification_dialog_cant_find_code_message),
                 new SpanInfo("<link>", "</link>",
-                        new NoUnderlineClickableSpan(context.getResources(),
-                                textView -> { viewDelegate.onResendLinkClicked(); })));
+                        new NoUnderlineClickableSpan(
+                                context, textView -> { viewDelegate.onResendLinkClicked(); })));
     }
 }
diff --git a/chrome/browser/ui/android/management/BUILD.gn b/chrome/browser/ui/android/management/BUILD.gn
index 6f270715..b7d5734 100644
--- a/chrome/browser/ui/android/management/BUILD.gn
+++ b/chrome/browser/ui/android/management/BUILD.gn
@@ -38,6 +38,8 @@
     "java/res/values/dimens.xml",
   ]
   deps = [
+    "//chrome/app:chromium_strings",
+    "//chrome/app:google_chrome_strings",
     "//chrome/browser/ui/android/strings:ui_strings_grd",
     "//components/browser_ui/styles/android:java_resources",
     "//components/strings:components_locale_settings_grd",
diff --git a/chrome/browser/ui/android/management/java/res/layout/enterprise_management.xml b/chrome/browser/ui/android/management/java/res/layout/enterprise_management.xml
index eee19105..546a424 100644
--- a/chrome/browser/ui/android/management/java/res/layout/enterprise_management.xml
+++ b/chrome/browser/ui/android/management/java/res/layout/enterprise_management.xml
@@ -21,7 +21,7 @@
             android:layout_width="@dimen/cm_logo_width"
             android:layout_height="@dimen/cm_logo_height"
             android:src="@drawable/enterprise_icon"
-            android:contentDescription="@string/close" />
+            android:contentDescription="@string/product_logo_enterprise_alt_text" />
 
         <TextView
             android:id="@+id/title_text"
diff --git a/chrome/browser/ui/android/management/java/src/org/chromium/chrome/browser/management/ManagementMediator.java b/chrome/browser/ui/android/management/java/src/org/chromium/chrome/browser/management/ManagementMediator.java
index b48a8ad9..c0e3b6f3 100644
--- a/chrome/browser/ui/android/management/java/src/org/chromium/chrome/browser/management/ManagementMediator.java
+++ b/chrome/browser/ui/android/management/java/src/org/chromium/chrome/browser/management/ManagementMediator.java
@@ -42,8 +42,8 @@
 
     private SpannableString getLearnMoreClickableText() {
         final Context context = mHost.getContext();
-        final NoUnderlineClickableSpan clickableLearnMoreSpan = new NoUnderlineClickableSpan(
-                context.getResources(), (v) -> { showHelpCenterArticle(); });
+        final NoUnderlineClickableSpan clickableLearnMoreSpan =
+                new NoUnderlineClickableSpan(context, (v) -> { showHelpCenterArticle(); });
         return SpanApplier.applySpans(context.getString(R.string.management_learn_more),
                 new SpanApplier.SpanInfo("<LINK>", "</LINK>", clickableLearnMoreSpan));
     }
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
index 57462fa3..ec1a2f7 100644
--- a/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/values/dimens.xml
@@ -55,6 +55,7 @@
     <dimen name="omnibox_carousel_suggestion_padding">12dp</dimen>
     <dimen name="omnibox_carousel_icon_rounding_radius">4dp</dimen>
     <dimen name="omnibox_pedal_suggestion_pedal_height">48dp</dimen>
+    <dimen name="omnibox_pedal_suggestion_icon_size">18dp</dimen>
 
     <dimen name="omnibox_suggestion_36dp_icon_size">36dp</dimen>
     <dimen name="omnibox_suggestion_24dp_icon_size">24dp</dimen>
diff --git a/chrome/browser/ui/android/omnibox/java/res/values/styles.xml b/chrome/browser/ui/android/omnibox/java/res/values/styles.xml
index 7ed2e5de..12576ce8 100644
--- a/chrome/browser/ui/android/omnibox/java/res/values/styles.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/values/styles.xml
@@ -32,4 +32,14 @@
         <item name="android:layout_height">match_parent</item>
     </style>
 
+    <style name="OmniboxPedalChipThemeOverlay">
+        <item name="chipStyle">@style/OmniboxPedalChip</item>
+    </style>
+
+    <style name="OmniboxPedalChip" parent="SuggestionChip">
+        <item name="iconWidth">@dimen/omnibox_pedal_suggestion_icon_size</item>
+        <item name="iconHeight">@dimen/omnibox_pedal_suggestion_icon_size</item>
+        <item name="textAlignStart">true</item>
+    </style>
+
 </resources>
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
index 2b71ef4a..7ca6ca7 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java
@@ -156,13 +156,33 @@
     }
 
     /**
-     * Deletes an omnibox suggestion, if possible.
-     * @param position The position at which the suggestion is located.
+     * Partially deletes an omnibox suggestion.
+     * This call should be used by compound suggestion types (such as carousel) that host multiple
+     * components inside (eg. MostVisitedTiles).
+     * @param matchIndex The position at which the match is located.
+     * @param elementIndex The element within the match that needs to be deleted.
      */
-    void deleteSuggestion(int position) {
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public void deleteMatchElement(int matchIndex, int elementIndex) {
         if (mNativeController == 0) return;
-        if (!mAutocompleteResult.verifyCoherency(position, VerificationPoint.DELETE_MATCH)) return;
-        AutocompleteControllerJni.get().deleteSuggestion(mNativeController, position);
+        if (!mAutocompleteResult.verifyCoherency(matchIndex, VerificationPoint.DELETE_MATCH)) {
+            return;
+        }
+        AutocompleteControllerJni.get().deleteMatchElement(
+                mNativeController, matchIndex, elementIndex);
+    }
+
+    /**
+     * Deletes an omnibox suggestion, if possible.
+     * @param matchIndex The position at which the match is located.
+     */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public void deleteMatch(int matchIndex) {
+        if (mNativeController == 0) return;
+        if (!mAutocompleteResult.verifyCoherency(matchIndex, VerificationPoint.DELETE_MATCH)) {
+            return;
+        }
+        AutocompleteControllerJni.get().deleteMatch(mNativeController, matchIndex);
     }
 
     @CalledByNative
@@ -184,7 +204,7 @@
      * Called whenever a navigation happens from the omnibox to record metrics about the user's
      * interaction with the omnibox.
      *
-     * @param selectedIndex The index of the suggestion that was selected.
+     * @param matchIndex The index of the suggestion that was selected.
      * @param disposition The window open disposition.
      * @param type The type of the selected suggestion.
      * @param currentPageUrl The URL of the current page.
@@ -195,14 +215,14 @@
      * @param webContents The web contents for the tab where the selected suggestion will be shown.
      */
     @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-    public void onSuggestionSelected(int selectedIndex, int disposition, int type,
+    public void onSuggestionSelected(int matchIndex, int disposition, int type,
             @NonNull String currentPageUrl, int pageClassification, long elapsedTimeSinceModified,
             int completedLength, @Nullable WebContents webContents) {
         if (mNativeController == 0) return;
-        if (!mAutocompleteResult.verifyCoherency(selectedIndex, VerificationPoint.SELECT_MATCH)) {
+        if (!mAutocompleteResult.verifyCoherency(matchIndex, VerificationPoint.SELECT_MATCH)) {
             return;
         }
-        AutocompleteControllerJni.get().onSuggestionSelected(mNativeController, selectedIndex,
+        AutocompleteControllerJni.get().onSuggestionSelected(mNativeController, matchIndex,
                 disposition, currentPageUrl, pageClassification, elapsedTimeSinceModified,
                 completedLength, webContents);
     }
@@ -229,15 +249,15 @@
      * Updates aqs parameters on the selected match that we will navigate to and returns the
      * updated URL.
      *
-     * @param selectedIndex The index of the autocomplete entry selected.
+     * @param matchIndex The index of the autocomplete entry selected.
      * @param elapsedTimeSinceInputChange The number of ms between the time the user started
      *         typing in the omnibox and the time the user has selected a suggestion.
      */
     @Nullable
     GURL updateMatchDestinationUrlWithQueryFormulationTime(
-            int selectedIndex, long elapsedTimeSinceInputChange) {
+            int matchIndex, long elapsedTimeSinceInputChange) {
         return updateMatchDestinationUrlWithQueryFormulationTime(
-                selectedIndex, elapsedTimeSinceInputChange, null, null);
+                matchIndex, elapsedTimeSinceInputChange, null, null);
     }
 
     /**
@@ -253,7 +273,7 @@
      *   "www.google.com/search?q=Politics+news&aqs=chrome.0.69i...l3.1409j0j9"
      * where ".1409j0j9" is the encoded elapsed time.
      *
-     * @param selectedIndex The index of the autocomplete entry selected.
+     * @param matchIndex The index of the autocomplete entry selected.
      * @param elapsedTimeSinceInputChange The number of ms between the time the user started
      *                                    typing in the omnibox and the time the user has selected
      *                                    a suggestion.
@@ -263,16 +283,16 @@
      *         updated, if we are making a Google search query.
      */
     @Nullable
-    GURL updateMatchDestinationUrlWithQueryFormulationTime(int selectedIndex,
+    GURL updateMatchDestinationUrlWithQueryFormulationTime(int matchIndex,
             long elapsedTimeSinceInputChange, @Nullable String newQueryText,
             @Nullable List<String> newQueryParams) {
         if (mNativeController == 0) return null;
-        if (!mAutocompleteResult.verifyCoherency(selectedIndex, VerificationPoint.UPDATE_MATCH)) {
+        if (!mAutocompleteResult.verifyCoherency(matchIndex, VerificationPoint.UPDATE_MATCH)) {
             return null;
         }
         return AutocompleteControllerJni.get()
                 .updateMatchDestinationURLWithAdditionalAssistedQueryStats(mNativeController,
-                        selectedIndex, elapsedTimeSinceInputChange, newQueryText,
+                        matchIndex, elapsedTimeSinceInputChange, newQueryText,
                         newQueryParams == null
                                 ? null
                                 : newQueryParams.toArray(new String[newQueryParams.size()]));
@@ -283,14 +303,14 @@
      * TODO(crbug.com/1266558): move this to AutocompleteMatch object when Tab is no longer part
      * of the //chrome/browser directory.
      *
-     * @param index Index of the suggestion to retrieve Tab info for.
+     * @param matchIndex Index of the suggestion to retrieve Tab info for.
      * @return Tab that hosts matching URL.
      */
     @Nullable
-    Tab getMatchingTabForSuggestion(int index) {
+    Tab getMatchingTabForSuggestion(int matchIndex) {
         if (mNativeController == 0) return null;
         return AutocompleteControllerJni.get().getMatchingTabForSuggestion(
-                mNativeController, index);
+                mNativeController, matchIndex);
     }
 
     /**
@@ -317,16 +337,18 @@
                 long nativeAutocompleteControllerAndroid, String text, boolean focusedFromFakebox);
         void stop(long nativeAutocompleteControllerAndroid, boolean clearResults);
         void resetSession(long nativeAutocompleteControllerAndroid);
-        void onSuggestionSelected(long nativeAutocompleteControllerAndroid, int selectedIndex,
+        void onSuggestionSelected(long nativeAutocompleteControllerAndroid, int matchIndex,
                 int disposition, String currentPageUrl, int pageClassification,
                 long elapsedTimeSinceModified, int completedLength, WebContents webContents);
         void onOmniboxFocused(long nativeAutocompleteControllerAndroid, String omniboxText,
                 String currentUrl, int pageClassification, String currentTitle);
-        void deleteSuggestion(long nativeAutocompleteControllerAndroid, int selectedIndex);
+        void deleteMatchElement(
+                long nativeAutocompleteControllerAndroid, int matchIndex, int elementIndex);
+        void deleteMatch(long nativeAutocompleteControllerAndroid, int matchIndex);
         GURL updateMatchDestinationURLWithAdditionalAssistedQueryStats(
-                long nativeAutocompleteControllerAndroid, int selectedIndex,
+                long nativeAutocompleteControllerAndroid, int matchIndex,
                 long elapsedTimeSinceInputChange, String newQueryText, String[] newQueryParams);
-        Tab getMatchingTabForSuggestion(long nativeAutocompleteControllerAndroid, int index);
+        Tab getMatchingTabForSuggestion(long nativeAutocompleteControllerAndroid, int matchIndex);
         void setVoiceMatches(long nativeAutocompleteControllerAndroid, String[] matches,
                 float[] confidenceScores);
 
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
index b81991e..4c3c73a 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -71,6 +71,7 @@
     private final @NonNull ObservableSupplier<Profile> mProfileSupplier;
     private final @NonNull Callback<Profile> mProfileChangeCallback;
     private final @NonNull AutocompleteMediator mMediator;
+    private final @NonNull Supplier<ModalDialogManager> mModalDialogManagerSupplier;
     private @Nullable OmniboxSuggestionsDropdown mDropdown;
 
     public AutocompleteCoordinator(@NonNull ViewGroup parent,
@@ -88,6 +89,7 @@
             @NonNull ExploreIconProvider exploreIconProvider,
             @NonNull OmniboxPedalDelegate omniboxPedalDelegate) {
         mParent = parent;
+        mModalDialogManagerSupplier = modalDialogManagerSupplier;
         Context context = parent.getContext();
 
         PropertyModel listModel = new PropertyModel(SuggestionListProperties.ALL_KEYS);
@@ -416,4 +418,10 @@
     public ModelList getSuggestionModelListForTest() {
         return mMediator.getSuggestionModelListForTest();
     }
+
+    @VisibleForTesting
+    public @NonNull ModalDialogManager getModalDialogManagerForTest() {
+        assert mModalDialogManagerSupplier.hasValue();
+        return mModalDialogManagerSupplier.get();
+    }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index 2718ff3..52fbb405 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -235,11 +235,11 @@
      * in the underlying model.  The index does not represent visibility due to the current scroll
      * position of the list.
      *
-     * @param index The index of the suggestion to fetch.
+     * @param matchIndex The index of the suggestion to fetch.
      * @return The suggestion at the given index.
      */
-    public AutocompleteMatch getSuggestionAt(int index) {
-        return mAutocompleteResult.getSuggestionsList().get(index);
+    public AutocompleteMatch getSuggestionAt(int matchIndex) {
+        return mAutocompleteResult.getSuggestionsList().get(matchIndex);
     }
 
     /**
@@ -386,22 +386,22 @@
     /**
      * Triggered when the user selects one of the omnibox suggestions to navigate to.
      * @param suggestion The AutocompleteMatch which was selected.
-     * @param position Position of the suggestion in the drop down view.
+     * @param matchIndex Position of the suggestion in the drop down view.
      * @param url The URL associated with the suggestion.
      */
     @Override
     public void onSuggestionClicked(
-            @NonNull AutocompleteMatch suggestion, int position, @NonNull GURL url) {
+            @NonNull AutocompleteMatch suggestion, int matchIndex, @NonNull GURL url) {
         if (mAutocompleteResult.isFromCachedResult()
                 && (!mNativeInitialized || mAutocomplete == null)) {
             // clang-format off
             mDeferredLoadAction = () -> loadUrlForOmniboxMatch(
-                            position, suggestion, url, mLastActionUpTimestamp, true);
+                            matchIndex, suggestion, url, mLastActionUpTimestamp, true);
             // clang-format on
             return;
         }
 
-        loadUrlForOmniboxMatch(position, suggestion, url, mLastActionUpTimestamp, true);
+        loadUrlForOmniboxMatch(matchIndex, suggestion, url, mLastActionUpTimestamp, true);
     }
 
     /**
@@ -434,10 +434,10 @@
     }
 
     @Override
-    public void onSwitchToTab(AutocompleteMatch suggestion, int position) {
-        Tab tab = mAutocomplete.getMatchingTabForSuggestion(position);
+    public void onSwitchToTab(AutocompleteMatch suggestion, int matchIndex) {
+        Tab tab = mAutocomplete.getMatchingTabForSuggestion(matchIndex);
         if (tab == null || !mTabWindowManagerSupplier.hasValue()) {
-            onSuggestionClicked(suggestion, position, suggestion.getUrl());
+            onSuggestionClicked(suggestion, matchIndex, suggestion.getUrl());
             return;
         }
 
@@ -453,7 +453,7 @@
             // In the event the user deleted the tab as part during the interaction with the
             // Omnibox, reject the switch to tab action.
             if (tabIndex < 0) {
-                onSuggestionClicked(suggestion, position, suggestion.getUrl());
+                onSuggestionClicked(suggestion, matchIndex, suggestion.getUrl());
                 return;
             }
 
@@ -461,7 +461,7 @@
         } else {
             mBringTabToFrontCallback.onResult(tab);
         }
-        recordMetrics(position, WindowOpenDisposition.SWITCH_TO_TAB, suggestion);
+        recordMetrics(matchIndex, WindowOpenDisposition.SWITCH_TO_TAB, suggestion);
     }
 
     @Override
@@ -475,13 +475,31 @@
     /**
      * Triggered when the user long presses the omnibox suggestion.
      * @param suggestion The suggestion selected.
-     * @param position The position of the suggestion.
-     *
-     * TODO(crbug.com/1136107): revisit the event propagation here to make sure we do not try to
-     * execute an action before native is initialize.
+     * @param titleText The title to display in the delete dialog.
+     * @param matchIndex The position of the suggestion.
      */
     @Override
-    public void onSuggestionLongClicked(@NonNull AutocompleteMatch suggestion, int position) {
+    public void onDeleteMatch(
+            @NonNull AutocompleteMatch suggestion, @NonNull String titleText, int matchIndex) {
+        showDeleteDialog(suggestion, titleText, () -> mAutocomplete.deleteMatch(matchIndex));
+    }
+
+    /**
+     * Triggered when the user long presses the omnibox suggestion element (eg. a tile).
+     * @param suggestion The suggestion selected.
+     * @param titleText The title to display in the delete dialog.
+     * @param matchIndex The position of the suggestion.
+     * @param elementIndex The element of the suggestion to be deleted.
+     */
+    @Override
+    public void onDeleteMatchElement(@NonNull AutocompleteMatch suggestion,
+            @NonNull String titleText, int matchIndex, int elementIndex) {
+        showDeleteDialog(suggestion, titleText,
+                () -> mAutocomplete.deleteMatchElement(matchIndex, elementIndex));
+    }
+
+    public void showDeleteDialog(@NonNull AutocompleteMatch suggestion, @NonNull String titleText,
+            Runnable deleteAction) {
         RecordUserAction.record("MobileOmniboxDeleteGesture");
         if (!suggestion.isDeletable()) return;
 
@@ -496,7 +514,7 @@
             public void onClick(PropertyModel model, int buttonType) {
                 if (buttonType == ModalDialogProperties.ButtonType.POSITIVE) {
                     RecordUserAction.record("MobileOmniboxDeleteRequested");
-                    mAutocomplete.deleteSuggestion(position);
+                    deleteAction.run();
                     manager.dismissDialog(model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED);
                 } else if (buttonType == ModalDialogProperties.ButtonType.NEGATIVE) {
                     manager.dismissDialog(model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED);
@@ -519,7 +537,7 @@
         mDeleteDialogModel =
                 new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
                         .with(ModalDialogProperties.CONTROLLER, dialogController)
-                        .with(ModalDialogProperties.TITLE, suggestion.getDisplayText())
+                        .with(ModalDialogProperties.TITLE, titleText)
                         .with(ModalDialogProperties.TITLE_MAX_LINES, 1)
                         .with(ModalDialogProperties.MESSAGE, resources.getString(dialogMessageId))
                         .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, R.string.ok)
@@ -562,13 +580,13 @@
      * on regular web search URLs.
      *
      * @param suggestion The chosen omnibox suggestion.
-     * @param selectedIndex The index of the chosen omnibox suggestion.
+     * @param matchIndex The index of the chosen omnibox suggestion.
      * @param url The URL associated with the suggestion to navigate to.
      * @param skipCheck Whether to skip an out of bounds check.
      * @return The url to navigate to.
      */
-    private GURL updateSuggestionUrlIfNeeded(@NonNull AutocompleteMatch suggestion,
-            int selectedIndex, @NonNull GURL url, boolean skipCheck) {
+    private GURL updateSuggestionUrlIfNeeded(@NonNull AutocompleteMatch suggestion, int matchIndex,
+            @NonNull GURL url, boolean skipCheck) {
         if (!mNativeInitialized || mAutocomplete == null) return url;
         if (suggestion.getType() == OmniboxSuggestionType.VOICE_SUGGEST
                 || suggestion.getType() == OmniboxSuggestionType.TILE_SUGGESTION
@@ -578,7 +596,7 @@
 
         int verifiedIndex = SUGGESTION_NOT_FOUND;
         if (!skipCheck) {
-            verifiedIndex = findSuggestionInAutocompleteResult(suggestion, selectedIndex);
+            verifiedIndex = findSuggestionInAutocompleteResult(suggestion, matchIndex);
         }
 
         // If we do not have the suggestion as part of our results, skip the URL update.
@@ -599,14 +617,14 @@
      * called by all the methods that are dispatched rather than called directly.
      *
      * @param suggestion Suggestion to look for.
-     * @param index Last known position of the suggestion.
+     * @param matchIndex Last known position of the suggestion.
      * @return Current index of the supplied suggestion, or SUGGESTION_NOT_FOUND if it is no longer
      *         part of the model.
      */
     @SuppressWarnings("ReferenceEquality")
-    private int findSuggestionInAutocompleteResult(AutocompleteMatch suggestion, int position) {
-        if (getSuggestionCount() > position && getSuggestionAt(position) == suggestion) {
-            return position;
+    private int findSuggestionInAutocompleteResult(AutocompleteMatch suggestion, int matchIndex) {
+        if (getSuggestionCount() > matchIndex && getSuggestionAt(matchIndex) == suggestion) {
+            return matchIndex;
         }
 
         // Underlying omnibox results may have changed since the selection was made,
@@ -751,13 +769,13 @@
     /**
      * Loads the specified omnibox suggestion.
      *
-     * @param matchPosition The position of the selected omnibox suggestion.
+     * @param matchIndex The position of the selected omnibox suggestion.
      * @param suggestion The suggestion selected.
      * @param url The URL to load.
      * @param inputStart The timestamp the input was started.
      * @param inVisibleSuggestionList Whether the suggestion is in the visible suggestion list.
      */
-    private void loadUrlForOmniboxMatch(int matchPosition, @NonNull AutocompleteMatch suggestion,
+    private void loadUrlForOmniboxMatch(int matchIndex, @NonNull AutocompleteMatch suggestion,
             @NonNull GURL url, long inputStart, boolean inVisibleSuggestionList) {
         SuggestionsMetrics.recordFocusToOpenTime(System.currentTimeMillis() - mUrlFocusTime);
 
@@ -765,7 +783,7 @@
         mDeferredLoadAction = null;
 
         mOmniboxFocusResultedInNavigation = true;
-        url = updateSuggestionUrlIfNeeded(suggestion, matchPosition, url, !inVisibleSuggestionList);
+        url = updateSuggestionUrlIfNeeded(suggestion, matchIndex, url, !inVisibleSuggestionList);
 
         // loadUrl modifies AutocompleteController's state clearing the native
         // AutocompleteResults needed by onSuggestionsSelected. Therefore,
@@ -773,7 +791,7 @@
         int transition = suggestion.getTransition();
         int type = suggestion.getType();
 
-        recordMetrics(matchPosition, WindowOpenDisposition.CURRENT_TAB, suggestion);
+        recordMetrics(matchIndex, WindowOpenDisposition.CURRENT_TAB, suggestion);
         if (((transition & PageTransition.CORE_MASK) == PageTransition.TYPED)
                 && TextUtils.equals(url.getSpec(), mDataProvider.getCurrentUrl())) {
             // When the user hit enter on the existing permanent URL, treat it like a
@@ -913,11 +931,11 @@
      * Called whenever a navigation happens from the omnibox to record metrics about the user's
      * interaction with the omnibox.
      *
-     * @param matchPosition The index of the suggestion that was selected.
+     * @param matchIndex The index of the suggestion that was selected.
      * @param disposition The window open disposition.
      * @param suggestion The suggestion selected.
      */
-    private void recordMetrics(int matchPosition, int disposition, AutocompleteMatch suggestion) {
+    private void recordMetrics(int matchIndex, int disposition, AutocompleteMatch suggestion) {
         SuggestionsMetrics.recordUsedSuggestionFromCache(mAutocompleteResult.isFromCachedResult());
 
         // Do not attempt to record other metrics for cached suggestions if the source of the list
@@ -934,7 +952,7 @@
         WebContents webContents =
                 mDataProvider.hasTab() ? mDataProvider.getTab().getWebContents() : null;
 
-        mAutocomplete.onSuggestionSelected(matchPosition, disposition, suggestion.getType(),
+        mAutocomplete.onSuggestionSelected(matchIndex, disposition, suggestion.getType(),
                 currentPageUrl, pageClassification, elapsedTimeSinceModified, autocompleteLength,
                 webContents);
     }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionHost.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionHost.java
index a030ed66..84c809a 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionHost.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionHost.java
@@ -30,11 +30,28 @@
 
     /**
      * Triggered when the user long presses the omnibox suggestion.
+     * Deletes the entire AutocompleteMatch. Execution of this method implies removal of the
+     * AutocompleteMatch.
      *
      * @param suggestion Long-pressed Suggestion.
+     * @param titleText The title to display in the delete dialog.
      * @param position The position of the suggestion on the list.
      */
-    void onSuggestionLongClicked(@NonNull AutocompleteMatch suggestion, int position);
+    void onDeleteMatch(
+            @NonNull AutocompleteMatch suggestion, @NonNull String titleText, int position);
+
+    /**
+     * Triggered when the user long presses the omnibox suggestion element (eg. tile).
+     * Performs partial deletion of an AutocompleteMatch, focusing on the supplied element.
+     * Execution of this method does not imply removal of the AutocompleteMatch.
+     *
+     * @param suggestion Long-pressed Suggestion.
+     * @param titleText The title to display in the delete dialog.
+     * @param position The position of the suggestion on the list.
+     * @param element Element of the suggestion to be deleted.
+     */
+    void onDeleteMatchElement(@NonNull AutocompleteMatch suggestion, @NonNull String titleText,
+            int position, int element);
 
     /**
      * Triggered when the user selects a switch to tab action.
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java
index d0b62df..2579766 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java
@@ -145,7 +145,7 @@
      * @param position Position of the suggestion on the list.
      */
     protected void onSuggestionLongClicked(@NonNull AutocompleteMatch suggestion, int position) {
-        mSuggestionHost.onSuggestionLongClicked(suggestion, position);
+        mSuggestionHost.onDeleteMatch(suggestion, suggestion.getDisplayText(), position);
     }
 
     @Override
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java
index 22efd4f3..4a9f30e 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/mostvisited/MostVisitedTilesProcessor.java
@@ -96,7 +96,7 @@
     }
 
     @Override
-    public boolean doesProcessSuggestion(AutocompleteMatch suggestion, int position) {
+    public boolean doesProcessSuggestion(AutocompleteMatch suggestion, int matchIndex) {
         return suggestion.getType() == OmniboxSuggestionType.TILE_NAVSUGGEST;
     }
 
@@ -116,22 +116,29 @@
     }
 
     @Override
-    public void populateModel(AutocompleteMatch suggestion, PropertyModel model, int position) {
+    public void populateModel(AutocompleteMatch suggestion, PropertyModel model, int matchIndex) {
         final List<AutocompleteMatch.NavsuggestTile> tiles = suggestion.getNavsuggestTiles();
         final int tilesCount = tiles.size();
         final List<ListItem> tileList = new ArrayList<>(tilesCount);
         final LargeIconBridge iconBridge = mIconBridgeSupplier.get();
 
-        for (int index = 0; index < tilesCount; index++) {
+        for (int elementIndex = 0; elementIndex < tilesCount; elementIndex++) {
             final PropertyModel tileModel = new PropertyModel(TileViewProperties.ALL_KEYS);
-            final String title = tiles.get(index).title;
-            final GURL url = tiles.get(index).url;
+            final String title = tiles.get(elementIndex).title;
+            final GURL url = tiles.get(elementIndex).url;
             tileModel.set(TileViewProperties.TITLE, title);
             tileModel.set(TileViewProperties.TITLE_LINES, 1);
             tileModel.set(TileViewProperties.ON_FOCUS_VIA_SELECTION,
                     () -> mSuggestionHost.setOmniboxEditingText(url.getSpec()));
             tileModel.set(TileViewProperties.ON_CLICK,
-                    v -> mSuggestionHost.onSuggestionClicked(suggestion, position, url));
+                    v -> mSuggestionHost.onSuggestionClicked(suggestion, matchIndex, url));
+
+            final int elementIndexForDeletion = elementIndex;
+            tileModel.set(TileViewProperties.ON_LONG_CLICK, v -> {
+                mSuggestionHost.onDeleteMatchElement(
+                        suggestion, title, matchIndex, elementIndexForDeletion);
+                return true;
+            });
             tileModel.set(TileViewProperties.CONTENT_DESCRIPTION,
                     mContext.getString(R.string.accessibility_omnibox_most_visited_tile, title,
                             url.getHost()));
@@ -147,7 +154,7 @@
             if (TextUtils.equals(url.getSpec(), UrlConstants.EXPLORE_URL)) {
                 setExploreSitesIcon(tileModel);
             } else if (iconBridge != null) {
-                iconBridge.getLargeIconForUrl(tiles.get(index).url, mDesiredFaviconWidthPx,
+                iconBridge.getLargeIconForUrl(tiles.get(elementIndex).url, mDesiredFaviconWidthPx,
                         (Bitmap icon, int fallbackColor, boolean isFallbackColorDefault,
                                 int iconType) -> {
                             if (icon == null) return;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java
index 547bc1a..0a9581f4 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/pedal/PedalView.java
@@ -40,7 +40,7 @@
 
         setFocusable(true);
 
-        mPedal = new ChipView(context, null);
+        mPedal = new ChipView(context, R.style.OmniboxPedalChipThemeOverlay);
         mPedal.setLayoutParams(LayoutParams.forDynamicView());
 
         final int baseColor = MaterialColors.getColor(context, R.attr.colorSurface, TAG);
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
index 57d84f6d6..1353587 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/fre/SigninFirstRunMediator.java
@@ -271,16 +271,15 @@
 
         ArrayList<SpanApplier.SpanInfo> spans = new ArrayList<>();
         // Terms of Service SpanInfo.
-        final NoUnderlineClickableSpan clickableTermsOfServiceSpan =
-                new NoUnderlineClickableSpan(mContext.getResources(),
-                        view -> mDelegate.showInfoPage(R.string.google_terms_of_service_url));
+        final NoUnderlineClickableSpan clickableTermsOfServiceSpan = new NoUnderlineClickableSpan(
+                mContext, view -> mDelegate.showInfoPage(R.string.google_terms_of_service_url));
         spans.add(
                 new SpanApplier.SpanInfo("<TOS_LINK>", "</TOS_LINK>", clickableTermsOfServiceSpan));
 
         // Privacy notice Link SpanInfo.
         if (hasChildAccount) {
             final NoUnderlineClickableSpan clickablePrivacyPolicySpan =
-                    new NoUnderlineClickableSpan(mContext.getResources(),
+                    new NoUnderlineClickableSpan(mContext,
                             view -> mDelegate.showInfoPage(R.string.google_privacy_policy_url));
 
             spans.add(new SpanApplier.SpanInfo(
@@ -290,8 +289,8 @@
         // Metrics and Crash Reporting SpanInfo.
         if (!isMetricsReportingDisabled) {
             footerString += "\n" + mContext.getString(R.string.signin_fre_footer_metrics_reporting);
-            final NoUnderlineClickableSpan clickableUMADialogSpan = new NoUnderlineClickableSpan(
-                    mContext.getResources(), view -> mDelegate.openUmaDialog());
+            final NoUnderlineClickableSpan clickableUMADialogSpan =
+                    new NoUnderlineClickableSpan(mContext, view -> mDelegate.openUmaDialog());
             spans.add(
                     new SpanApplier.SpanInfo("<UMA_LINK>", "</UMA_LINK>", clickableUMADialogSpan));
         }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
index 2ba787a53..45bcebc 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressMediatorTest.java
@@ -82,8 +82,8 @@
         assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
                 CompletionState.FINISHED_DONT_ANIMATE);
 
-        NavigationHandle navigation = new NavigationHandle(0, URL_1, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, URL_1, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
                 mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
@@ -119,8 +119,8 @@
     @UiThreadTest
     public void switchToLoadedTab() {
         initMediator();
-        NavigationHandle navigation = new NavigationHandle(0, URL_1, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, URL_1, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
                 mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
@@ -139,15 +139,15 @@
     public void loadNativePage() {
         initMediator();
         doReturn(0.1f).when(mTab).getProgress();
-        NavigationHandle navigation = new NavigationHandle(0, URL_1, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, URL_1, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
                 mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
         assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 0.1f, MathUtils.EPSILON);
 
-        navigation = new NavigationHandle(0, NATIVE_PAGE_URL, null, null, true, false, false, null,
-                null, 0, false, false, false, false, 0);
+        navigation = new NavigationHandle(0, NATIVE_PAGE_URL, GURL.emptyGURL(), GURL.emptyGURL(),
+                true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
                 CompletionState.FINISHED_DONT_ANIMATE);
@@ -158,8 +158,8 @@
     @UiThreadTest
     public void switchToTabWithNativePage() {
         initMediator();
-        NavigationHandle navigation = new NavigationHandle(0, URL_1, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, URL_1, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
                 mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
@@ -180,8 +180,8 @@
     @UiThreadTest
     public void pageCrashes() {
         initMediator();
-        NavigationHandle navigation = new NavigationHandle(0, URL_1, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, URL_1, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         assertEquals(
                 mModel.get(LoadProgressProperties.COMPLETION_STATE), CompletionState.UNFINISHED);
@@ -229,15 +229,15 @@
         assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
                 CompletionState.FINISHED_DONT_ANIMATE);
 
-        NavigationHandle navigation = new NavigationHandle(0, gurl, null, null, true, false, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle navigation = new NavigationHandle(0, gurl, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, false, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, navigation);
         mTabObserver.onLoadProgressChanged(mTab, 1.0f);
         assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 1.0f, MathUtils.EPSILON);
         assertEquals(mModel.get(LoadProgressProperties.COMPLETION_STATE),
                 CompletionState.FINISHED_DO_ANIMATE);
-        NavigationHandle sameDocNav = new NavigationHandle(0, gurl, null, null, true, true, false,
-                null, null, 0, false, false, false, false, 0);
+        NavigationHandle sameDocNav = new NavigationHandle(0, gurl, GURL.emptyGURL(),
+                GURL.emptyGURL(), true, true, false, null, null, 0, false, false, false, false, 0);
         mTabObserver.onDidStartNavigation(mTab, sameDocNav);
 
         assertEquals(mModel.get(LoadProgressProperties.PROGRESS), 1.0f, MathUtils.EPSILON);
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
index f226024..0ae77467 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionViewBinder.java
@@ -160,7 +160,7 @@
         tabCreator.launchUrl(url, TabLaunchType.FROM_CHROME_UI);
     }
 
-    static SpanApplier.SpanInfo createLink(Resources r, String url, String tag) {
+    static SpanApplier.SpanInfo createLink(Context context, String url, String tag) {
         if (TextUtils.isEmpty(url)) return null;
 
         String startTag = "<" + tag + ">";
@@ -169,7 +169,7 @@
             openTab(url);
         };
         return new SpanApplier.SpanInfo(
-                startTag, endTag, new NoUnderlineClickableSpan(r, onClickCallback));
+                startTag, endTag, new NoUnderlineClickableSpan(context, onClickCallback));
     }
 
     /**
@@ -183,11 +183,11 @@
             DataSharingConsentProperties.Properties properties =
                     model.get(DataSharingConsentProperties.PROPERTIES);
 
-            Resources resources = view.getResources();
+            Context context = view.getContext();
             SpanApplier.SpanInfo privacyPolicySpan =
-                    createLink(resources, properties.mPrivacyPolicyUrl, "link_privacy_policy");
+                    createLink(context, properties.mPrivacyPolicyUrl, "link_privacy_policy");
             SpanApplier.SpanInfo termsOfServiceSpan =
-                    createLink(resources, properties.mTermsOfServiceUrl, "link_terms_of_service");
+                    createLink(context, properties.mTermsOfServiceUrl, "link_terms_of_service");
 
             // TODO(crbug.com/1293913): Validate string choices.
             int consentTextId = (privacyPolicySpan == null && termsOfServiceSpan == null)
diff --git a/chrome/browser/ui/app_list/page_break_constants.cc b/chrome/browser/ui/app_list/page_break_constants.cc
index 1154bb7..3e10f207 100644
--- a/chrome/browser/ui/app_list/page_break_constants.cc
+++ b/chrome/browser/ui/app_list/page_break_constants.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/app_list/page_break_constants.h"
 
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 
 namespace app_list {
 
@@ -17,8 +16,7 @@
     kDefaultPageBreak1,
 };
 
-const size_t kDefaultPageBreakAppIdsLength =
-    base::size(kDefaultPageBreakAppIds);
+const size_t kDefaultPageBreakAppIdsLength = std::size(kDefaultPageBreakAppIds);
 
 // Returns true if |item_id| is of a default-installed page break item.
 bool IsDefaultPageBreakItem(const std::string& item_id) {
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
index 4a3e8586..03d202c 100644
--- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
+++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.cc
@@ -7,7 +7,6 @@
 #include <cmath>
 
 #include "ash/public/cpp/app_list/app_list_features.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/notreached.h"
 
@@ -158,7 +157,7 @@
   const auto& frequency_table_map =
       proto_.hour_app_launch_predictor().binned_frequency_table();
 
-  for (size_t i = 0; i < base::size(kAdjacentHourBin); ++i) {
+  for (size_t i = 0; i < std::size(kAdjacentHourBin); ++i) {
     // Finds adjacent bin and weight.
     const int adj_bin =
         (hour + kAdjacentHourBin[i]) % kHoursADay + kHoursADay * is_weekend;
diff --git a/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc b/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc
index d3474aa..9b45389 100644
--- a/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc
+++ b/chrome/browser/ui/ash/app_list/bubble_apps_grid_drag_browsertest.cc
@@ -172,23 +172,23 @@
 
   // Move the dragged item in two steps to ensure that the reordering animation
   // in the top level apps grid is triggered:
-  // Step 1: move the dragged item upon a top level item then fire the
-  // reparenting timer.
+  // Step 1: move the dragged item upon a top level item (that is not occluded
+  // by the folder view) then fire the reparenting timer.
   // Step 2: move the dragged item to the right of a top level item.
   event_generator_->MoveMouseTo(
-      root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/1)
+      root_apps_grid_test_api_->GetViewAtVisualIndex(/*page=*/0, /*slot=*/2)
           ->GetBoundsInScreen()
           .CenterPoint());
   folder_apps_grid_test_api.FireFolderItemReparentTimer();
   event_generator_->MoveMouseTo(
-      CalculatePositionBetweenAdjacentTopLevelItems(/*prev_item_index=*/1));
+      CalculatePositionBetweenAdjacentTopLevelItems(/*prev_item_index=*/2));
   root_apps_grid_test_api_->FireReorderTimerAndWaitForAnimationDone();
   event_generator_->ReleaseLeftButton();
 
   // Calculate the expected top level item ids after moving `dragged_view` out
-  // of the parent folder. `dragged_view` should be inserted at the third slot.
+  // of the parent folder. `dragged_view` should be inserted at the fourth slot.
   std::vector<std::string> expected_top_level_ids = top_level_ids_after_merging;
-  expected_top_level_ids.insert(expected_top_level_ids.begin() + 2,
+  expected_top_level_ids.insert(expected_top_level_ids.begin() + 3,
                                 dragged_app_id);
 
   const std::vector<std::string> final_top_level_ids =
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
index 25afee1..5ce671c8 100644
--- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -311,6 +311,11 @@
   if (ash::features::IsBluetoothRevampEnabled())
     chromeos::bluetooth_config::Shutdown();
 
+  // Disable event dispatch before Exo starts closing windows to prevent
+  // synthetic events from being dispatched. crbug.com/874156 and
+  // crbug.com/1163269.
+  ash::Shell::Get()->ShutdownEventDispatch();
+
 #if BUILDFLAG(ENABLE_WAYLAND_SERVER)
   // ExoParts uses state from ash, delete it before ash so that exo can
   // uninstall correctly.
diff --git a/chrome/browser/ui/ash/default_pinned_apps.cc b/chrome/browser/ui/ash/default_pinned_apps.cc
index 224f3b1..43eda618 100644
--- a/chrome/browser/ui/ash/default_pinned_apps.cc
+++ b/chrome/browser/ui/ash/default_pinned_apps.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/ash/default_pinned_apps.h"
 
 #include "ash/constants/ash_switches.h"
-#include "base/cxx17_backports.h"
 #include "chrome/browser/ash/file_manager/app_id.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/web_applications/web_app_id_constants.h"
@@ -38,7 +37,7 @@
       arc::kGooglePhotosAppId,
   };
   return base::span<StaticAppId>(kDefaultPinnedApps,
-                                 base::size(kDefaultPinnedApps));
+                                 std::size(kDefaultPinnedApps));
 }
 
 base::span<StaticAppId> GetTabletFormFactorDefaultPinnedApps() {
@@ -53,9 +52,8 @@
 
       arc::kGooglePhotosAppId,
   };
-  return base::span<StaticAppId>(
-      kTabletFormFactorDefaultPinnedApps,
-      base::size(kTabletFormFactorDefaultPinnedApps));
+  return base::span<StaticAppId>(kTabletFormFactorDefaultPinnedApps,
+                                 std::size(kTabletFormFactorDefaultPinnedApps));
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
index ffa91d7..4ec55bf 100644
--- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
+++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.cc
@@ -333,6 +333,7 @@
 
 void ChromeDesksTemplatesDelegate::LaunchAppsFromTemplate(
     std::unique_ptr<ash::DeskTemplate> desk_template,
+    base::Time time_launch_started,
     base::TimeDelta delay) {
   const auto& launch_list =
       desk_template->desk_restore_data()->app_id_to_launch_list();
@@ -341,8 +342,8 @@
   // Show app unavailable toast.
   if (!unavailable_apps.empty())
     ShowUnavailableAppToast(unavailable_apps);
-  DesksTemplatesClient::Get()->LaunchAppsFromTemplate(std::move(desk_template),
-                                                      delay);
+  DesksTemplatesClient::Get()->LaunchAppsFromTemplate(
+      std::move(desk_template), time_launch_started, delay);
 }
 
 // Returns true if `window` is supported in desk templates feature.
diff --git a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h
index b45ed21f..cebd2ee 100644
--- a/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h
+++ b/chrome/browser/ui/ash/desks_templates/chrome_desks_templates_delegate.h
@@ -45,6 +45,7 @@
       int desired_icon_size,
       base::OnceCallback<void(const gfx::ImageSkia&)> callback) const override;
   void LaunchAppsFromTemplate(std::unique_ptr<ash::DeskTemplate> desk_template,
+                              base::Time time_launch_started,
                               base::TimeDelta delay) override;
   bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
   void OpenFeedbackDialog(const std::string& extra_diagnostics) override;
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.cc
index bb4988f..4463f99 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.cc
@@ -8,6 +8,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/wm/desks/desks_controller.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/ash/app_restore/app_restore_arc_task_handler.h"
 #include "chrome/browser/ash/app_restore/arc_app_launch_handler.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/ash/desks_templates/desks_templates_client.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_tabstrip.h"
@@ -123,8 +125,17 @@
   if (is_multi_instance_window)
     return true;
 
-  return ash::DesksController::Get()->OnSingleInstanceAppLaunchingFromTemplate(
-      app_id, launch_list);
+  const bool should_launch =
+      ash::DesksController::Get()->OnSingleInstanceAppLaunchingFromTemplate(
+          app_id, launch_list);
+
+  // Notify performance tracker that some tracked windows will be moving.
+  if (!should_launch) {
+    for (const auto& window : launch_list)
+      NotifyMovedSingleInstanceApp(window.first);
+  }
+
+  return should_launch;
 }
 
 void DesksTemplatesAppLaunchHandler::OnExtensionLaunching(
@@ -236,6 +247,8 @@
     DCHECK(it != app_id_to_launch_list.end());
     if (!ash::DesksController::Get()->OnSingleInstanceAppLaunchingFromTemplate(
             app_id, it->second)) {
+      for (auto& window : it->second)
+        NotifyMovedSingleInstanceApp(window.first);
       restore_data()->RemoveApp(app_id);
     }
   }
@@ -260,3 +273,8 @@
   // TODO: Add UMA Histogram.
   NOTIMPLEMENTED();
 }
+
+void DesksTemplatesAppLaunchHandler::NotifyMovedSingleInstanceApp(
+    int32_t window_id) {
+  DesksTemplatesClient::Get()->NotifyMovedSingleInstanceApp(window_id);
+}
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h b/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h
index 32ea70c..cb435c3 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h
@@ -56,6 +56,9 @@
   // current desk template launch is considered done.
   void ClearDeskTemplateReadHandlerRestoreData();
 
+  // Notifies observers that a single instance app has moved.
+  void NotifyMovedSingleInstanceApp(int32_t window_id);
+
   // chromeos::AppLaunchHandler:
   void RecordRestoredAppLaunch(apps::AppTypeName app_type_name) override;
 
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
index 629e5a0..dc0505c9 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client.cc
@@ -16,6 +16,8 @@
 #include "base/guid.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/scoped_observation.h"
+#include "base/timer/timer.h"
 #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/profiles/profile_helper.h"
@@ -23,9 +25,12 @@
 #include "chrome/browser/sync/desk_sync_service_factory.h"
 #include "chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h"
 #include "components/app_constants/constants.h"
+#include "components/app_restore/full_restore_info.h"
+#include "components/app_restore/window_properties.h"
 #include "components/desks_storage/core/desk_sync_service.h"
 #include "components/desks_storage/core/local_desk_data_manager.h"
 #include "components/sync/model/model_type_store.h"
+#include "ui/views/widget/widget.h"
 
 namespace {
 
@@ -41,6 +46,8 @@
     "Ash.DeskTemplate.LaunchFromTemplate";
 constexpr char kUserTemplateCountHistogramName[] =
     "Ash.DeskTemplate.UserTemplateCount";
+constexpr char kTimeToLoadTemplateHistogramName[] =
+    "Ash.DeskTemplate.TimeToLoadTemplate";
 
 // Error strings
 constexpr char kMaximumDesksOpenedError[] =
@@ -53,14 +60,113 @@
     "Either the profile is not valid or there is not an active proflile.";
 constexpr char kNoSavedTemplatesError[] = "You can create up to 6 templates.";
 
-// Returns true if |profile| is a supported profile in desk template feature.
+// Timeout time used in LaunchPerformanceTracker
+constexpr base::TimeDelta kLaunchPerformanceTimeout = base::Minutes(3);
+
+// Returns true if `profile` is a supported profile in desk template feature.
 bool IsSupportedProfile(Profile* profile) {
   // Public users & guest users are not supported.
   return profile && profile->IsRegularProfile();
 }
 
+// Creates a set of window IDs for the launch tracker to monitor for.
+std::set<int> GetWindowIDSetFromTemplate(
+    const ash::DeskTemplate* desk_template) {
+  std::set<int> window_ids;
+  const app_restore::RestoreData* desk_restore_data =
+      desk_template->desk_restore_data();
+
+  for (const auto& app : desk_restore_data->app_id_to_launch_list()) {
+    for (const auto& window : app.second)
+      window_ids.insert(window.first);
+  }
+
+  return window_ids;
+}
+
+// Records the time to load a template based on the starting time `time_started`
+// passed into this function and a call to base::Time::Now called at the
+// beginning of this function.
+void RecordTimeToLoadTemplateHistogram(const base::Time time_started) {
+  base::UmaHistogramMediumTimes(kTimeToLoadTemplateHistogramName,
+                                base::Time::Now() - time_started);
+}
+
 }  // namespace
 
+// Tracks a set of WindowIDs through the launching process, records a
+// launch performance metric when the set of window_ids have all been
+// launched
+class DesksTemplatesClient::LaunchPerformanceTracker
+    : public full_restore::FullRestoreInfo::Observer {
+ public:
+  LaunchPerformanceTracker(base::Time time_launch_started,
+                           const std::set<int>& window_ids,
+                           base::GUID template_id,
+                           DesksTemplatesClient* templates_client)
+      : tracked_window_ids_(window_ids),
+        time_launch_started_(time_launch_started),
+        template_id_(template_id),
+        templates_client_(templates_client) {
+    scoped_observation_.Observe(full_restore::FullRestoreInfo::GetInstance());
+    timeout_timer_ = std::make_unique<base::OneShotTimer>();
+    timeout_timer_->Start(
+        FROM_HERE, kLaunchPerformanceTimeout,
+        base::BindOnce(
+            &DesksTemplatesClient::LaunchPerformanceTracker::OnTimeout,
+            weak_ptr_factory_.GetWeakPtr()));
+  }
+
+  LaunchPerformanceTracker(const LaunchPerformanceTracker&) = delete;
+  LaunchPerformanceTracker& operator=(const LaunchPerformanceTracker&) = delete;
+  ~LaunchPerformanceTracker() override {}
+
+  // Removes window ID from tracked set because the window has been launched.
+  // full_restore::FullRestoreInfo::Observer
+  void OnWidgetInitialized(views::Widget* widget) override {
+    tracked_window_ids_.erase(widget->GetNativeWindow()->GetProperty(
+        app_restore::kRestoreWindowIdKey));
+    MaybeRecordMetric();
+  }
+
+  // Removes `window_id` from the tracked set because the window has already
+  // been launched by another process.
+  void OnMovedSingleInstanceApp(int32_t window_id) {
+    tracked_window_ids_.erase(window_id);
+    MaybeRecordMetric();
+  }
+
+ private:
+  // Records performance metric iff `tracked_window_ids_` are empty.
+  void MaybeRecordMetric() {
+    if (tracked_window_ids_.empty()) {
+      RecordTimeToLoadTemplateHistogram(time_launch_started_);
+      templates_client_->RemoveLaunchPerformanceTracker(template_id_);
+    }
+  }
+
+  // Called when timeout timer runs out. Records time metric.
+  void OnTimeout() {
+    tracked_window_ids_.clear();
+    MaybeRecordMetric();
+  }
+
+  std::set<int> tracked_window_ids_;
+  base::Time time_launch_started_;
+  base::GUID template_id_;
+  std::unique_ptr<base::OneShotTimer> timeout_timer_;
+
+  // Pointer back to the owning templates client. This is done to facilitate
+  // this object's removal from the mapping of template id's to trackers after
+  // this object has recorded its metric.
+  DesksTemplatesClient* templates_client_;
+
+  base::ScopedObservation<full_restore::FullRestoreInfo,
+                          full_restore::FullRestoreInfo::Observer>
+      scoped_observation_{this};
+  base::WeakPtrFactory<LaunchPerformanceTracker> weak_ptr_factory_{this};
+};
+
 DesksTemplatesClient::DesksTemplatesClient()
     : desks_controller_(ash::DesksController::Get()) {
   DCHECK(!g_desks_templates_client_instance);
@@ -176,6 +282,8 @@
 void DesksTemplatesClient::LaunchDeskTemplate(
     const std::string& template_uuid,
     LaunchDeskTemplateCallback callback) {
+  base::Time launch_started = base::Time::Now();
+
   if (!active_profile_) {
     std::move(callback).Run(std::string(kNoCurrentUserError));
     return;
@@ -186,7 +294,7 @@
 
   if (launch_template_for_test_) {
     OnGetTemplateForDeskLaunch(
-        std::move(callback),
+        std::move(callback), base::Time(),
         desks_storage::DeskModel::GetEntryByUuidStatus::kOk,
         launch_template_for_test_->Clone());
     return;
@@ -195,11 +303,13 @@
   GetDeskModel()->GetEntryByUUID(
       template_uuid,
       base::BindOnce(&DesksTemplatesClient::OnGetTemplateForDeskLaunch,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     launch_started));
 }
 
 void DesksTemplatesClient::LaunchAppsFromTemplate(
     std::unique_ptr<ash::DeskTemplate> desk_template,
+    base::Time time_launch_started,
     base::TimeDelta delay) {
   DCHECK(desk_template);
   const app_restore::RestoreData* restore_data =
@@ -209,6 +319,12 @@
 
   MaybeCreateAppLaunchHandler();
   DCHECK(app_launch_handler_);
+
+  template_ids_to_launch_performance_trackers_[desk_template->uuid()] =
+      std::make_unique<LaunchPerformanceTracker>(
+          time_launch_started, GetWindowIDSetFromTemplate(desk_template.get()),
+          desk_template->uuid(), this);
+
   app_launch_handler_->set_delay(delay);
   app_launch_handler_->SetRestoreDataAndLaunch(restore_data->Clone());
 }
@@ -258,6 +374,11 @@
     GetDeskModel()->RemovePolicyDeskTemplates();
 }
 
+void DesksTemplatesClient::NotifyMovedSingleInstanceApp(int32_t window_id) {
+  for (auto& id_to_tracker : template_ids_to_launch_performance_trackers_)
+    id_to_tracker.second->OnMovedSingleInstanceApp(window_id);
+}
+
 void DesksTemplatesClient::MaybeCreateAppLaunchHandler() {
   if (app_launch_handler_ &&
       app_launch_handler_->profile() == active_profile_) {
@@ -317,6 +438,7 @@
 
 void DesksTemplatesClient::OnGetTemplateForDeskLaunch(
     LaunchDeskTemplateCallback callback,
+    base::Time time_launch_started,
     desks_storage::DeskModel::GetEntryByUuidStatus status,
     std::unique_ptr<ash::DeskTemplate> entry) {
   if (status != desks_storage::DeskModel::GetEntryByUuidStatus::kOk) {
@@ -332,12 +454,13 @@
       template_name,
       base::BindOnce(&DesksTemplatesClient::OnCreateAndActivateNewDesk,
                      weak_ptr_factory_.GetWeakPtr(), std::move(entry),
-                     std::move(callback)));
+                     std::move(callback), time_launch_started));
 }
 
 void DesksTemplatesClient::OnCreateAndActivateNewDesk(
     std::unique_ptr<ash::DeskTemplate> desk_template,
     LaunchDeskTemplateCallback callback,
+    base::Time time_launch_started,
     bool on_create_activate_success) {
   if (!on_create_activate_success) {
     // This only returns false if the number of desks is at a maximum.
@@ -351,7 +474,8 @@
     return;
   }
 
-  LaunchAppsFromTemplate(std::move(desk_template), base::TimeDelta());
+  LaunchAppsFromTemplate(std::move(desk_template), time_launch_started,
+                         base::TimeDelta());
   std::move(callback).Run(std::string(""));
 }
 
@@ -441,3 +565,8 @@
                       ? kStorageError
                       : ""));
 }
+
+void DesksTemplatesClient::RemoveLaunchPerformanceTracker(
+    base::GUID tracker_uuid) {
+  template_ids_to_launch_performance_trackers_.erase(tracker_uuid);
+}
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client.h b/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
index 6f20409..27f4414 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client.h
@@ -12,7 +12,10 @@
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/ash/desks_templates/desks_templates_app_launch_handler.h"
+#include "components/app_restore/full_restore_info.h"
 #include "components/desks_storage/core/desk_model.h"
 
 class DesksTemplatesAppLaunchHandler;
@@ -114,6 +117,7 @@
   // Uses `app_launch_handler_` to launch apps from the restore data found in
   // `desk_template`.
   void LaunchAppsFromTemplate(std::unique_ptr<ash::DeskTemplate> desk_template,
+                              base::Time time_launch_started,
                               base::TimeDelta delay);
 
   // Returns either the local desk storage backend or Chrome sync desk storage
@@ -125,7 +129,12 @@
                                       std::unique_ptr<std::string> data);
   void RemovePolicyPreconfiguredTemplate(const AccountId& account_id);
 
+  // Notifies launch performance trackers that an app has been moved rather
+  // than launched.
+  void NotifyMovedSingleInstanceApp(int32_t window_id);
+
  private:
+  class LaunchPerformanceTracker;
   friend class DesksTemplatesClientTest;
   friend class ScopedDesksTemplatesAppLaunchHandlerSetter;
 
@@ -139,6 +148,7 @@
   // Launches DeskTemplate after retrieval from storage.
   void OnGetTemplateForDeskLaunch(
       LaunchDeskTemplateCallback callback,
+      base::Time time_launch_started,
       desks_storage::DeskModel::GetEntryByUuidStatus status,
       std::unique_ptr<ash::DeskTemplate> entry);
 
@@ -147,6 +157,7 @@
   void OnCreateAndActivateNewDesk(
       std::unique_ptr<ash::DeskTemplate> desk_template,
       LaunchDeskTemplateCallback callback,
+      base::Time time_launch_started,
       bool on_create_activate_success);
 
   // Callback function that allows the |CaptureActiveDeskAndSaveTemplate|
@@ -193,6 +204,10 @@
                          desks_storage::DeskModel::GetTemplateJsonStatus status,
                          const std::string& json_representation);
 
+  // Called by a launch performance tracker when it has completed monitoring the
+  // launch of a template.
+  void RemoveLaunchPerformanceTracker(base::GUID tracker_uuid);
+
   // Convenience pointer to ash::DesksController. Guaranteed to be not null for
   // the duration of `this`.
   ash::DesksController* const desks_controller_;
@@ -211,6 +226,11 @@
   // The stored JSON values of preconfigured desk templates
   base::flat_map<AccountId, std::string> preconfigured_desk_templates_json_;
 
+  // Mapping of template ids that are being launched to their launch performance
+  // trackers.
+  base::flat_map<base::GUID, std::unique_ptr<LaunchPerformanceTracker>>
+      template_ids_to_launch_performance_trackers_;
+
   base::WeakPtrFactory<DesksTemplatesClient> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
index aed0daf..a92e1e3 100644
--- a/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks_templates/desks_templates_client_browsertest.cc
@@ -1938,6 +1938,28 @@
   histogram_tester.ExpectTotalCount(kLaunchFromTemplateHistogramName, launches);
 }
 
+// Tests that launching a desk template records the appropriate performance
+// metric.
+IN_PROC_BROWSER_TEST_F(DesksTemplatesClientTest,
+                       LaunchTemplateRecordsLoadTimeMetric) {
+  base::HistogramTester histogram_tester;
+
+  // Create the settings app, which is a system web app.
+  CreateSettingsSystemWebApp(browser()->profile());
+
+  CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2)});
+  CreateBrowser({GURL(kExampleUrl1), GURL(kExampleUrl2), GURL(kExampleUrl3)});
+
+  // Save and launch a template.
+  ash::ToggleOverview();
+  ash::WaitForOverviewEnterAnimation();
+  ClickSaveDeskAsTemplateButton();
+  ClickFirstTemplateItem();
+
+  // Verify that the metric was recorded.
+  histogram_tester.ExpectTotalCount("Ash.DeskTemplate.TimeToLoadTemplate", 1ul);
+}
+
 class DesksTemplatesClientArcTest : public InProcessBrowserTest {
  public:
   DesksTemplatesClientArcTest() {
diff --git a/chrome/browser/ui/ash/session_controller_client_impl.cc b/chrome/browser/ui/ash/session_controller_client_impl.cc
index fda3cb6..3ca4690 100644
--- a/chrome/browser/ui/ash/session_controller_client_impl.cc
+++ b/chrome/browser/ui/ash/session_controller_client_impl.cc
@@ -45,7 +45,6 @@
 #include "components/user_manager/user_type.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_service.h"
-#include "mojo/public/cpp/bindings/equals_traits.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
 #include "ui/gfx/image/image_skia.h"
@@ -129,20 +128,6 @@
 
 }  // namespace
 
-namespace mojo {
-
-// When comparing two mojom::UserSession objects we need to decide if the avatar
-// images are changed. Consider them equal if they have the same storage rather
-// than comparing the backing pixels.
-template <>
-struct EqualsTraits<gfx::ImageSkia> {
-  static bool Equals(const gfx::ImageSkia& a, const gfx::ImageSkia& b) {
-    return a.BackedBySameObjectAs(b);
-  }
-};
-
-}  // namespace mojo
-
 SessionControllerClientImpl::SessionControllerClientImpl() {
   SessionManager::Get()->AddObserver(this);
   UserManager::Get()->AddSessionStateObserver(this);
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
index 89eba5e..623baeb9 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
@@ -148,7 +148,8 @@
   // apps is likely override it. There is a case when App sync is disabled and
   // in last case local cache is available immediately.
   if (chromeos::features::IsSyncSettingsCategorizationEnabled()) {
-    if (settings->GetSelectedOsTypes().Has(UserSelectableOsType::kOsApps) &&
+    if (sync_service->IsSyncFeatureEnabled() &&
+        settings->GetSelectedOsTypes().Has(UserSelectableOsType::kOsApps) &&
         !app_list::AppListSyncableServiceFactory::GetForProfile(profile)
              ->IsSyncing()) {
       return false;
@@ -165,7 +166,8 @@
   // If shelf pin layout rolls preference is not started yet then we cannot say
   // if we rolled layout or not.
   if (chromeos::features::IsSyncSettingsCategorizationEnabled()) {
-    if (settings->GetSelectedOsTypes().Has(
+    if (sync_service->IsSyncFeatureEnabled() &&
+        settings->GetSelectedOsTypes().Has(
             UserSelectableOsType::kOsPreferences) &&
         !PrefServiceSyncableFromProfile(profile)->AreOsPrefsSyncing()) {
       return false;
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index bd4bdda..b7118c8 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -10,25 +10,20 @@
 #include <memory>
 #include <string>
 
-#include "base/memory/raw_ptr.h"
-#include "base/test/bind.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/resource_coordinator/lifecycle_unit.h"
-#include "chrome/browser/resource_coordinator/tab_manager.h"
-
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/strings/string_split.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/system/sys_info.h"
 #include "base/task/single_thread_task_runner.h"
+#include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -39,6 +34,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/apps/app_service/browser_app_launcher.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/defaults.h"
@@ -52,6 +48,8 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_attributes_storage.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/resource_coordinator/lifecycle_unit.h"
+#include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/sessions/session_service_factory.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
@@ -1626,7 +1624,7 @@
       Browser::CreateParams::CreateForDevTools(browser()->profile()),
       Browser::CreateParams::CreateForAppPopup("app_name", true, gfx::Rect(),
                                                browser()->profile(), true)};
-  for (size_t i = 0; i < base::size(params); ++i) {
+  for (size_t i = 0; i < std::size(params); ++i) {
     params[i].initial_show_state = ui::SHOW_STATE_MAXIMIZED;
     AddBlankTabAndShow(Browser::Create(params[i]));
   }
@@ -1643,7 +1641,7 @@
       Browser::CreateParams::CreateForDevTools(browser()->profile()),
       Browser::CreateParams::CreateForAppPopup("app_name", true, gfx::Rect(),
                                                browser()->profile(), true)};
-  for (size_t i = 0; i < base::size(params); ++i) {
+  for (size_t i = 0; i < std::size(params); ++i) {
     params[i].initial_show_state = ui::SHOW_STATE_MINIMIZED;
     AddBlankTabAndShow(Browser::Create(params[i]));
   }
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index 5c80a25..9797048 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/browser_command_controller.h"
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
@@ -392,7 +391,7 @@
       blink::WebInputEvent::Type::kUndefined, 0,
       blink::WebInputEvent::GetStaticTimeStampForTests());
   // Defaults for a tabbed browser.
-  for (size_t i = 0; i < base::size(commands); i++) {
+  for (size_t i = 0; i < std::size(commands); i++) {
     SCOPED_TRACE(commands[i].command_id);
     EXPECT_EQ(chrome::IsCommandEnabled(browser(), commands[i].command_id),
               commands[i].enabled_in_tab);
@@ -409,7 +408,7 @@
   // By default, in fullscreen mode, the toolbar should be hidden; and all
   // platforms behave similarly.
   EXPECT_FALSE(window()->IsToolbarShowing());
-  for (size_t i = 0; i < base::size(commands); i++) {
+  for (size_t i = 0; i < std::size(commands); i++) {
     SCOPED_TRACE(commands[i].command_id);
     EXPECT_EQ(chrome::IsCommandEnabled(browser(), commands[i].command_id),
               commands[i].enabled_in_fullscreen);
@@ -425,7 +424,7 @@
       true);
   EXPECT_TRUE(browser()->command_controller()->IsReservedCommandOrKey(
       IDC_FULLSCREEN, key_event));
-  for (size_t i = 0; i < base::size(commands); i++) {
+  for (size_t i = 0; i < std::size(commands); i++) {
     if (commands[i].command_id != IDC_FULLSCREEN) {
       SCOPED_TRACE(commands[i].command_id);
       EXPECT_EQ(browser()->command_controller()->IsReservedCommandOrKey(
@@ -443,7 +442,7 @@
   ASSERT_FALSE(browser()->window()->IsFullscreen());
   browser()->command_controller()->FullscreenStateChanged();
 
-  for (size_t i = 0; i < base::size(commands); i++) {
+  for (size_t i = 0; i < std::size(commands); i++) {
     SCOPED_TRACE(commands[i].command_id);
     EXPECT_EQ(chrome::IsCommandEnabled(browser(), commands[i].command_id),
               commands[i].enabled_in_tab);
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc
index 9f2b5802..7f70920 100644
--- a/chrome/browser/ui/browser_focus_uitest.cc
+++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -5,7 +5,6 @@
 #include <stddef.h>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
 #include "base/location.h"
@@ -134,9 +133,9 @@
                                                     false, false));
       }
 
-      for (size_t j = 0; j < base::size(kExpectedIDs); ++j) {
+      for (size_t j = 0; j < std::size(kExpectedIDs); ++j) {
         SCOPED_TRACE(base::StringPrintf("focus inner loop %" PRIuS, j));
-        const size_t index = reverse ? base::size(kExpectedIDs) - 1 - j : j;
+        const size_t index = reverse ? std::size(kExpectedIDs) - 1 - j : j;
         // The details are the node's editable state, i.e. true for "textEdit".
         bool is_editable_node = index == 0;
 
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc
index 40a8a50..125fdb7 100644
--- a/chrome/browser/ui/browser_instant_controller_unittest.cc
+++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/field_trial.h"
@@ -102,7 +101,7 @@
 };
 
 TEST_F(BrowserInstantControllerTest, DefaultSearchProviderChanged) {
-  size_t num_tests = base::size(kTabReloadTestCasesFinalProviderNotGoogle);
+  size_t num_tests = std::size(kTabReloadTestCasesFinalProviderNotGoogle);
   std::vector<std::unique_ptr<FakeWebContentsObserver>> observers;
   for (size_t i = 0; i < num_tests; ++i) {
     const TabReloadTestCase& test =
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 505d823..539f10e 100644
--- a/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm
+++ b/chrome/browser/ui/cocoa/applescript/apple_event_util_unittest.mm
@@ -10,7 +10,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/mac/scoped_aedesc.h"
 #include "base/notreached.h"
@@ -229,7 +228,7 @@
       typeAEList },
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     absl::optional<base::Value> value =
         base::JSONReader::Read(cases[i].json_input);
     NSAppleEventDescriptor* descriptor =
diff --git a/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
index cd63e6e..b60ddb9 100644
--- a/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
+++ b/chrome/browser/ui/cocoa/fullscreen/fullscreen_menubar_tracker.mm
@@ -7,7 +7,6 @@
 #include <Carbon/Carbon.h>
 #include <QuartzCore/QuartzCore.h>
 
-#include "base/cxx17_backports.h"
 #include "base/mac/mac_util.h"
 #import "chrome/browser/ui/cocoa/fullscreen/fullscreen_toolbar_controller.h"
 #include "ui/base/cocoa/appkit_utils.h"
@@ -86,7 +85,7 @@
     eventSpecs[2].eventKind = kEventMenuBarHidden;
 
     InstallApplicationEventHandler(NewEventHandlerUPP(&MenuBarRevealHandler),
-                                   base::size(eventSpecs), eventSpecs, self,
+                                   std::size(eventSpecs), eventSpecs, self,
                                    &_menubarTrackingHandler);
 
     // Register for Active Space change notifications.
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
index 5578c92d..d386d34 100644
--- a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
+++ b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
@@ -204,7 +204,7 @@
 void CheckMenuItemVisibility(HistoryMenuBridgeTest* test, bool is_incognito) {
   // Make sure the items belong to both original and incognito mode are visible.
   NSInteger always_visible_items[] = {IDC_HOME, IDC_BACK, IDC_FORWARD};
-  for (size_t i = 0; i < base::size(always_visible_items); i++) {
+  for (size_t i = 0; i < std::size(always_visible_items); i++) {
     // Create a fake item with tag.
     base::scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] init]);
     item.get().tag = always_visible_items[i];
@@ -220,7 +220,7 @@
       HistoryMenuBridge::kVisitedTitle,
       HistoryMenuBridge::kShowFullSeparator,
       IDC_SHOW_HISTORY};
-  for (size_t i = 0; i < base::size(regular_visible_items); i++) {
+  for (size_t i = 0; i < std::size(regular_visible_items); i++) {
     // Create a fake item with tag.
     base::scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] init]);
     item.get().tag = regular_visible_items[i];
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index e3d5549..5965c8d7 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
@@ -254,11 +253,11 @@
       {ContentSettingsType::SENSORS, IDS_ALLOWED_SENSORS_TITLE},
   };
   const ContentSettingsTypeIdEntry* title_ids = kBlockedTitleIDs;
-  size_t num_title_ids = base::size(kBlockedTitleIDs);
+  size_t num_title_ids = std::size(kBlockedTitleIDs);
   if (content_settings->IsContentAllowed(content_type()) &&
       !content_settings->IsContentBlocked(content_type())) {
     title_ids = kAccessedTitleIDs;
-    num_title_ids = base::size(kAccessedTitleIDs);
+    num_title_ids = std::size(kAccessedTitleIDs);
   }
   int title_id = GetIdForContentType(title_ids, num_title_ids, content_type());
   if (title_id)
@@ -300,11 +299,11 @@
            : IDS_ALLOWED_MOTION_SENSORS_MESSAGE},
   };
   const ContentSettingsTypeIdEntry* message_ids = kBlockedMessageIDs;
-  size_t num_message_ids = base::size(kBlockedMessageIDs);
+  size_t num_message_ids = std::size(kBlockedMessageIDs);
   if (content_settings->IsContentAllowed(content_type()) &&
       !content_settings->IsContentBlocked(content_type())) {
     message_ids = kAccessedMessageIDs;
-    num_message_ids = base::size(kAccessedMessageIDs);
+    num_message_ids = std::size(kAccessedMessageIDs);
   }
   int message_id =
       GetIdForContentType(message_ids, num_message_ids, content_type());
@@ -332,7 +331,7 @@
       {ContentSettingsType::MIXEDSCRIPT, IDS_ALLOW_INSECURE_CONTENT_BUTTON},
   };
   int custom_link_id =
-      GetIdForContentType(kCustomIDs, base::size(kCustomIDs), content_type());
+      GetIdForContentType(kCustomIDs, std::size(kCustomIDs), content_type());
   if (custom_link_id)
     set_custom_link(l10n_util::GetStringUTF16(custom_link_id));
 }
@@ -608,11 +607,11 @@
   std::u16string radio_allow_label;
   if (allowed) {
     int resource_id = GetIdForContentType(
-        kAllowedAllowIDs, base::size(kAllowedAllowIDs), content_type());
+        kAllowedAllowIDs, std::size(kAllowedAllowIDs), content_type());
     radio_allow_label = l10n_util::GetStringUTF16(resource_id);
   } else {
     radio_allow_label = l10n_util::GetStringFUTF16(
-        GetIdForContentType(kBlockedAllowIDs, base::size(kBlockedAllowIDs),
+        GetIdForContentType(kBlockedAllowIDs, std::size(kBlockedAllowIDs),
                             content_type()),
         display_host);
   }
@@ -640,11 +639,11 @@
   std::u16string radio_block_label;
   if (allowed) {
     int resource_id = GetIdForContentType(
-        kAllowedBlockIDs, base::size(kAllowedBlockIDs), content_type());
+        kAllowedBlockIDs, std::size(kAllowedBlockIDs), content_type());
     radio_block_label = l10n_util::GetStringFUTF16(resource_id, display_host);
   } else {
     radio_block_label = l10n_util::GetStringUTF16(GetIdForContentType(
-        kBlockedBlockIDs, base::size(kBlockedBlockIDs), content_type()));
+        kBlockedBlockIDs, std::size(kBlockedBlockIDs), content_type()));
   }
 
   radio_group.radio_items = {radio_allow_label, radio_block_label};
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc
index 7d0d5b46..f3f8fe7 100644
--- a/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc
+++ b/chrome/browser/ui/extensions/extension_action_view_controller_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -469,7 +468,7 @@
       extensions::ExtensionActionRunner::GetForWebContents(web_contents);
   int tab_id = sessions::SessionTabHelper::IdForTab(web_contents).id();
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(
         base::StringPrintf("Running test case %d", static_cast<int>(i)));
     const auto& test_case = test_cases[i];
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc
index b3c7bb54..27d90fc 100644
--- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc
+++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer_unittest.cc
@@ -7,7 +7,6 @@
 #include <unordered_map>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -248,7 +247,7 @@
         kNoResponse},
        true},
   };
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE("case #" + base::NumberToString(i));
     const Case& test_case = cases[i];
     const Response& response = test_case.response;
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
index e48377f..f0404c9 100644
--- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/strcat.h"
@@ -324,7 +323,7 @@
   void SetupHistory() {
     // Add enough history pages containing |kSearchText| to trigger
     // open history page url in autocomplete result.
-    for (size_t i = 0; i < base::size(kHistoryEntries); i++) {
+    for (size_t i = 0; i < std::size(kHistoryEntries); i++) {
       // Add everything in order of time. We don't want to have a time that
       // is "right now" or it will nondeterministically appear in the results.
       base::Time t = base::Time::Now() - base::Hours(i + 1);
@@ -333,7 +332,7 @@
   }
 
   void SetupHostResolver() {
-    for (size_t i = 0; i < base::size(kBlockedHostnames); ++i)
+    for (size_t i = 0; i < std::size(kBlockedHostnames); ++i)
       host_resolver()->AddSimulatedFailure(kBlockedHostnames[i]);
   }
 
@@ -504,7 +503,7 @@
 
   // Should stay in keyword mode while deleting search text by pressing
   // backspace.
-  for (size_t i = 0; i < base::size(kSearchText) - 1; ++i) {
+  for (size_t i = 0; i < std::size(kSearchText) - 1; ++i) {
     ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_BACK, 0));
     ASSERT_FALSE(omnibox_view->model()->is_keyword_hint());
     ASSERT_EQ(kSearchKeyword, omnibox_view->model()->keyword());
@@ -670,7 +669,7 @@
   std::u16string old_text = omnibox_view->GetText();
 
   // Make sure inline autocomplete is triggered.
-  EXPECT_GT(old_text.length(), base::size(kInlineAutocompleteText) - 1);
+  EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1);
 
   size_t old_selected_line = omnibox_view->model()->GetPopupSelection().line;
   EXPECT_EQ(0U, old_selected_line);
@@ -707,7 +706,7 @@
   std::u16string old_text = omnibox_view->GetText();
 
   // Make sure inline autocomplete is triggered.
-  EXPECT_GT(old_text.length(), base::size(kInlineAutocompleteText) - 1);
+  EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1);
 
   size_t old_selected_line = omnibox_view->model()->GetPopupSelection().line;
   EXPECT_EQ(0U, old_selected_line);
@@ -1120,7 +1119,7 @@
   std::u16string old_text = omnibox_view->GetText();
 
   // Make sure inline autocomplete is triggered.
-  EXPECT_GT(old_text.length(), base::size(kInlineAutocompleteText) - 1);
+  EXPECT_GT(old_text.length(), std::size(kInlineAutocompleteText) - 1);
 
   // Press ctrl key.
   omnibox_view->model()->OnControlKeyChanged(true);
diff --git a/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
index e8beb2e..803bb3f 100644
--- a/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_view_utils_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
@@ -134,7 +133,7 @@
 
 // Test for GetSavePasswordDialogTitleText().
 TEST(ManagePasswordsViewUtilTest, GetSavePasswordDialogTitleText) {
-  for (size_t i = 0; i < base::size(kDomainsTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kDomainsTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "user_visible_url = "
                                     << kDomainsTestCases[i].user_visible_url
                                     << ", form_origin_url = "
@@ -187,7 +186,7 @@
 }
 
 TEST(ManagePasswordsViewUtilTest, GetManagePasswordsDialogTitleText) {
-  for (size_t i = 0; i < base::size(kDomainsTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kDomainsTestCases); ++i) {
     SCOPED_TRACE(testing::Message() << "user_visible_url = "
                                     << kDomainsTestCases[i].user_visible_url
                                     << ", password_origin_url = "
diff --git a/chrome/browser/ui/prefs/pref_watcher.cc b/chrome/browser/ui/prefs/pref_watcher.cc
index 790633b..a7dbd620 100644
--- a/chrome/browser/ui/prefs/pref_watcher.cc
+++ b/chrome/browser/ui/prefs/pref_watcher.cc
@@ -68,7 +68,7 @@
 #endif
 };
 
-const int kWebPrefsToObserveLength = base::size(kWebPrefsToObserve);
+const int kWebPrefsToObserveLength = std::size(kWebPrefsToObserve);
 
 }  // namespace
 
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc
index 6e48cabb..d342269b 100644
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -95,7 +94,7 @@
 #undef EXPAND_SCRIPT_FONT
   };
 
-  for (size_t i = 0; i < base::size(kFontFamilyMap); ++i) {
+  for (size_t i = 0; i < std::size(kFontFamilyMap); ++i) {
     const char* pref_name = kFontFamilyMap[i];
     if (fonts_with_defaults.find(pref_name) == fonts_with_defaults.end()) {
       // We haven't already set a default value for this font preference, so set
@@ -198,7 +197,7 @@
 #endif
 };
 
-const size_t kFontDefaultsLength = base::size(kFontDefaults);
+const size_t kFontDefaultsLength = std::size(kFontDefaults);
 
 // Returns the script of the font pref |pref_name|.  For example, suppose
 // |pref_name| is "webkit.webprefs.fonts.serif.Hant".  Since the script code for
diff --git a/chrome/browser/ui/signin/profile_colors_util.cc b/chrome/browser/ui/signin/profile_colors_util.cc
index ac588842..a4199281 100644
--- a/chrome/browser/ui/signin/profile_colors_util.cc
+++ b/chrome/browser/ui/signin/profile_colors_util.cc
@@ -48,7 +48,7 @@
     const std::set<ProfileThemeColors>& used_theme_colors,
     absl::optional<double> current_color_lightness) {
   std::vector<int> available_color_indices;
-  for (size_t i = 0; i < base::size(chrome_colors::kGeneratedColorsInfo); ++i) {
+  for (size_t i = 0; i < std::size(chrome_colors::kGeneratedColorsInfo); ++i) {
     ProfileThemeColors theme_colors =
         GetProfileThemeColorsForAutogeneratedColor(
             chrome_colors::kGeneratedColorsInfo[i].color);
diff --git a/chrome/browser/ui/signin/profile_colors_util_unittest.cc b/chrome/browser/ui/signin/profile_colors_util_unittest.cc
index c698818..b4dfced 100644
--- a/chrome/browser/ui/signin/profile_colors_util_unittest.cc
+++ b/chrome/browser/ui/signin/profile_colors_util_unittest.cc
@@ -26,7 +26,7 @@
 
 namespace {
 
-constexpr size_t kColorsCount = base::size(chrome_colors::kGeneratedColorsInfo);
+constexpr size_t kColorsCount = std::size(chrome_colors::kGeneratedColorsInfo);
 
 size_t ReturnNth(size_t n, size_t size) {
   DCHECK_LT(n, size);
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index 8930986..452f0a3 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
@@ -239,7 +238,7 @@
   profile_->SetIsNewProfile(true);
   char buf[18];
   for (int i = 0; i < 10; i++) {
-    base::snprintf(buf, base::size(buf), "http://foo.com/%d", i);
+    base::snprintf(buf, std::size(buf), "http://foo.com/%d", i);
     history->AddPage(GURL(std::string(buf)), base::Time::Now(), nullptr, 1,
                      GURL(), history::RedirectList(), ui::PAGE_TRANSITION_LINK,
                      history::SOURCE_BROWSED, false, false);
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index a08b1084..afa7d12c 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -341,7 +341,6 @@
 }
 
 TabStripModel::~TabStripModel() {
-  std::vector<TabStripModelObserver*> observers;
   for (auto& observer : observers_)
     observer.ModelDestroyed(TabStripModelObserver::ModelPasskey(), this);
 
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
index da096ec..0c0323a 100644
--- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -15,7 +15,6 @@
 
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -2731,7 +2730,7 @@
       {7, 4, "2 3 4", 3, "0p 1p 2p 3p 5 4 6"},
   };
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     TestTabStripModelDelegate delegate;
     TabStripModel strip(&delegate, profile());
     ASSERT_NO_FATAL_FAILURE(PrepareTabstripForSelectionTest(
diff --git a/chrome/browser/ui/task_manager/task_manager_columns.cc b/chrome/browser/ui/task_manager/task_manager_columns.cc
index 68ae548..0ae98c3 100644
--- a/chrome/browser/ui/task_manager/task_manager_columns.cc
+++ b/chrome/browser/ui/task_manager/task_manager_columns.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/task_manager/task_manager_columns.h"
 
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -28,12 +27,12 @@
     {IDS_TASK_MANAGER_PROFILE_NAME_COLUMN, ui::TableColumn::LEFT, -1, 0, 60,
      200, true, true, false},
     {IDS_TASK_MANAGER_MEM_FOOTPRINT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("800 MiB") * kCharWidth,
-     base::size("Memory Footprint") * kCharWidth * 3 / 2, true, false, true},
+     std::size("800 MiB") * kCharWidth,
+     std::size("Memory Footprint") * kCharWidth * 3 / 2, true, false, true},
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {IDS_TASK_MANAGER_SWAPPED_MEM_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("800 MiB") * kCharWidth, -1, true, false, false},
+     std::size("800 MiB") * kCharWidth, -1, true, false, false},
 #endif
 
 // Make the CPU column min width a bit wider on macOS. When you click a column
@@ -42,22 +41,22 @@
 // caret in by tail-truncating the label, which looks terrible.
 #if BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_CPU_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("0099.9") * kCharWidth, -1, true, false, true},
+     std::size("0099.9") * kCharWidth, -1, true, false, true},
 #else
     {IDS_TASK_MANAGER_CPU_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("99.9") * kCharWidth, -1, true, false, true},
+     std::size("99.9") * kCharWidth, -1, true, false, true},
 #endif  // BUILDFLAG(IS_MAC)
 
 #if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_CPU_TIME_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("1234h 42m 30s") * kCharWidth, -1, true, false, false},
+     std::size("1234h 42m 30s") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_START_TIME_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("12/13/14 11:44:30 PM") * kCharWidth, -1, true, true, false},
+     std::size("12/13/14 11:44:30 PM") * kCharWidth, -1, true, true, false},
 #endif
     {IDS_TASK_MANAGER_NET_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("150 kiB/s") * kCharWidth, -1, true, false, true},
+     std::size("150 kiB/s") * kCharWidth, -1, true, false, true},
     {IDS_TASK_MANAGER_PROCESS_ID_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("73099  ") * kCharWidth, -1, true, true, true},
+     std::size("73099  ") * kCharWidth, -1, true, true, true},
 
 #if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_GDI_HANDLES_COLUMN, ui::TableColumn::RIGHT, -1, 0, 0, 0,
@@ -67,44 +66,44 @@
 #endif
 
     {IDS_TASK_MANAGER_WEBCORE_IMAGE_CACHE_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
+     std::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_WEBCORE_SCRIPTS_CACHE_COLUMN, ui::TableColumn::RIGHT, -1,
-     0, base::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false,
+     0, std::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false,
      false},
     {IDS_TASK_MANAGER_WEBCORE_CSS_CACHE_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
+     std::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_VIDEO_MEMORY_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("2000.0K") * kCharWidth, -1, true, false, false},
+     std::size("2000.0K") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("800 kB") * kCharWidth, -1, true, false, false},
+     std::size("800 kB") * kCharWidth, -1, true, false, false},
 
 #if BUILDFLAG(ENABLE_NACL)
     {IDS_TASK_MANAGER_NACL_DEBUG_STUB_PORT_COLUMN, ui::TableColumn::RIGHT, -1,
-     0, base::size("32767") * kCharWidth, -1, true, true, false},
+     0, std::size("32767") * kCharWidth, -1, true, true, false},
 #endif  // BUILDFLAG(ENABLE_NACL)
 
     {IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN,
      ui::TableColumn::RIGHT, -1, 0,
-     base::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
+     std::size("2000.0K (2000.0 live)") * kCharWidth, -1, true, false, false},
     {IDS_TASK_MANAGER_IDLE_WAKEUPS_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("idlewakeups") * kCharWidth, -1, true, false, false},
+     std::size("idlewakeups") * kCharWidth, -1, true, false, false},
 
 #if BUILDFLAG(IS_WIN)
     {IDS_TASK_MANAGER_HARD_FAULTS_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("100000") * kCharWidth, -1, true, false, false},
+     std::size("100000") * kCharWidth, -1, true, false, false},
 #endif
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_OPEN_FD_COUNT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("999") * kCharWidth, -1, true, false, false},
+     std::size("999") * kCharWidth, -1, true, false, false},
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
     {IDS_TASK_MANAGER_PROCESS_PRIORITY_COLUMN, ui::TableColumn::LEFT, -1, 0,
-     base::size("background") * kCharWidth, -1, true, true, false},
+     std::size("background") * kCharWidth, -1, true, true, false},
     {IDS_TASK_MANAGER_KEEPALIVE_COUNT_COLUMN, ui::TableColumn::RIGHT, -1, 0,
-     base::size("999") * kCharWidth, -1, false, false, false},
+     std::size("999") * kCharWidth, -1, false, false, false},
 };
 
-const size_t kColumnsSize = base::size(kColumns);
+const size_t kColumnsSize = std::size(kColumns);
 
 const char kSortColumnIdKey[] = "sort_column_id";
 const char kSortIsAscendingKey[] = "sort_is_ascending";
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc
index c163d92..0c67564 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_model_unittest.cc
@@ -563,7 +563,7 @@
 
   extensions::TestExtensionDir* dirs[] = {&dir1, &dir2};
   const extensions::Extension* extensions[] = {nullptr, nullptr};
-  for (size_t i = 0; i < base::size(dirs); ++i) {
+  for (size_t i = 0; i < std::size(dirs); ++i) {
     // The extension id will be calculated from the file path; we need this to
     // wait for the extension to load.
     base::FilePath path_for_id =
diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc
index fc617ce1..cc52a17 100644
--- a/chrome/browser/ui/views/accelerator_table.cc
+++ b/chrome/browser/ui/views/accelerator_table.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
@@ -268,7 +267,7 @@
   IDC_SELECT_NEXT_TAB,
   IDC_SELECT_PREVIOUS_TAB,
 };
-const size_t kRepeatableCommandIdsLength = base::size(kRepeatableCommandIds);
+const size_t kRepeatableCommandIdsLength = std::size(kRepeatableCommandIds);
 
 } // namespace
 
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
index a084a86..004e414 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views.cc
@@ -5,9 +5,9 @@
 #include "chrome/browser/ui/views/apps/chrome_native_app_window_views.h"
 
 #include <stddef.h>
+
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -74,17 +74,17 @@
   if (!chrome::IsRunningInForcedAppMode()) {
     static base::NoDestructor<std::map<ui::Accelerator, int>> accelerators(
         AcceleratorsFromMapping(kAppWindowAcceleratorMap,
-                                base::size(kAppWindowAcceleratorMap)));
+                                std::size(kAppWindowAcceleratorMap)));
     return *accelerators;
   }
 
   static base::NoDestructor<std::map<ui::Accelerator, int>>
       app_mode_accelerators([]() {
         std::map<ui::Accelerator, int> mapping = AcceleratorsFromMapping(
-            kAppWindowAcceleratorMap, base::size(kAppWindowAcceleratorMap));
+            kAppWindowAcceleratorMap, std::size(kAppWindowAcceleratorMap));
         std::map<ui::Accelerator, int> kiosk_mapping = AcceleratorsFromMapping(
             kAppWindowKioskAppModeAcceleratorMap,
-            base::size(kAppWindowKioskAppModeAcceleratorMap));
+            std::size(kAppWindowKioskAppModeAcceleratorMap));
         mapping.insert(std::begin(kiosk_mapping), std::end(kiosk_mapping));
         return mapping;
       }());
@@ -182,8 +182,8 @@
   // registered. This CHECK catches the case.
   CHECK(!is_kiosk_app_mode ||
         accelerator_table.size() ==
-            base::size(kAppWindowAcceleratorMap) +
-                base::size(kAppWindowKioskAppModeAcceleratorMap));
+            std::size(kAppWindowAcceleratorMap) +
+                std::size(kAppWindowKioskAppModeAcceleratorMap));
 
   // Ensure there is a ZoomController in kiosk mode, otherwise the processing
   // of the accelerators will cause a crash. Note CHECK here because DCHECK
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc
index e5f1790..78894df 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc
@@ -21,6 +21,8 @@
 
 using views::BubbleBorder;
 
+namespace autofill {
+
 namespace {
 
 // The minimum number of pixels the popup should be distanced from the edge of
@@ -508,3 +510,5 @@
 
   return arrow;
 }
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_utils.h b/chrome/browser/ui/views/autofill/autofill_popup_view_utils.h
index 42049f3..acc8608 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_utils.h
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_utils.h
@@ -13,6 +13,8 @@
 class WebContents;
 }  // namespace content
 
+namespace autofill {
+
 // Sets the |x| and |width| components of |popup_bounds| as the x-coordinate
 // of the starting point and the width of the popup, taking into account the
 // direction it's supposed to grow (either to the left or to the right).
@@ -138,4 +140,6 @@
 // extension popup) and stays within the bounds of the browser window.
 bool PopupMayExceedContentAreaBounds(content::WebContents* web_contents);
 
+}  // namespace autofill
+
 #endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_AUTOFILL_POPUP_VIEW_UTILS_H_
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_utils_unittest.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_utils_unittest.cc
index ae2028e..ad48896 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_utils_unittest.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_utils_unittest.cc
@@ -7,6 +7,8 @@
 #include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace autofill {
+
 TEST(AutofillPopupViewUtilsTest, CalculatePopupBounds) {
   // Define the prompt sizes.
   const int desired_prompt_width = 40;
@@ -334,3 +336,5 @@
     EXPECT_EQ(popup_bounds, test_case.expected_popup_bounds);
   }
 }
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc
index 2e5f52c..5a1dc8b 100644
--- a/chrome/browser/ui/views/device_chooser_content_view.cc
+++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -7,7 +7,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/strcat.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
@@ -187,7 +186,7 @@
       IDR_SIGNAL_4_BAR};
   DCHECK_GE(level, 0);
   DCHECK_LT(static_cast<size_t>(level),
-            base::size(kSignalStrengthLevelImageIds));
+            std::size(kSignalStrengthLevelImageIds));
   return ui::ImageModel::FromImageSkia(
       *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
           kSignalStrengthLevelImageIds[level]));
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_button.cc b/chrome/browser/ui/views/extensions/extensions_menu_button.cc
index bfa28cb..bc031c7 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_button.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_button.cc
@@ -77,11 +77,11 @@
 }
 
 void ExtensionsMenuButton::UpdateState() {
-  SetImage(
-      Button::STATE_NORMAL,
-      controller_
-          ->GetIcon(GetCurrentWebContents(), ExtensionsMenuItemView::kIconSize)
-          .AsImageSkia());
+  SetImage(Button::STATE_NORMAL,
+           controller_
+               ->GetIcon(GetCurrentWebContents(),
+                         InstalledExtensionMenuItemView::kIconSize)
+               .AsImageSkia());
   SetText(controller_->GetActionName());
   SetTooltipText(controller_->GetTooltip(GetCurrentWebContents()));
   SetEnabled(controller_->IsEnabled(GetCurrentWebContents()));
@@ -89,8 +89,8 @@
   // the dialog. Note that |kIconSize| also contains space for badging, so we
   // can't trivially use dialog-text insets (empty space inside the icon).
   constexpr gfx::Insets kBorderInsets =
-      gfx::Insets((ExtensionsMenuItemView::kMenuItemHeightDp -
-                   ExtensionsMenuItemView::kIconSize.height()) /
+      gfx::Insets((InstalledExtensionMenuItemView::kMenuItemHeightDp -
+                   InstalledExtensionMenuItemView::kIconSize.height()) /
                       2,
                   12);
   SetBorder(views::CreateEmptyBorder(kBorderInsets));
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_button.h b/chrome/browser/ui/views/extensions/extensions_menu_button.h
index e2e2427..79619ebf 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_button.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_button.h
@@ -62,4 +62,9 @@
   bool allow_pinning_;
 };
 
+BEGIN_VIEW_BUILDER(/* no export */, ExtensionsMenuButton, HoverButton)
+END_VIEW_BUILDER
+
+DEFINE_VIEW_BUILDER(/* no export */, ExtensionsMenuButton)
+
 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_BUTTON_H_
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc
index 7e044bf..5a30b64 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_item_unittest.cc
@@ -16,15 +16,16 @@
 #include "chrome/browser/ui/views/native_widget_factory.h"
 #include "ui/views/controls/styled_label.h"
 
-class ExtensionsMenuItemViewTest : public ExtensionsToolbarUnitTest {
+class InstalledExtensionMenuItemViewTest : public ExtensionsToolbarUnitTest {
  public:
-  ExtensionsMenuItemViewTest()
+  InstalledExtensionMenuItemViewTest()
       : initial_extension_name_(u"Initial Extension Name"),
         initial_tooltip_(u"Initial tooltip") {}
-  ExtensionsMenuItemViewTest(const ExtensionsMenuItemViewTest&) = delete;
-  ExtensionsMenuItemViewTest& operator=(const ExtensionsMenuItemViewTest&) =
-      delete;
-  ~ExtensionsMenuItemViewTest() override = default;
+  InstalledExtensionMenuItemViewTest(
+      const InstalledExtensionMenuItemViewTest&) = delete;
+  InstalledExtensionMenuItemViewTest& operator=(
+      const InstalledExtensionMenuItemViewTest&) = delete;
+  ~InstalledExtensionMenuItemViewTest() override = default;
 
  protected:
   ExtensionsMenuButton* primary_button() { return primary_button_; }
@@ -44,7 +45,7 @@
   raw_ptr<TestToolbarActionViewController> controller_ = nullptr;
 };
 
-void ExtensionsMenuItemViewTest::SetUp() {
+void InstalledExtensionMenuItemViewTest::SetUp() {
   ExtensionsToolbarUnitTest::SetUp();
 
   // TODO(crbug.com/1263310): This widget only tests behavior of
@@ -69,9 +70,8 @@
   controller_ = controller.get();
   controller_->SetActionName(initial_extension_name_);
   controller_->SetTooltip(initial_tooltip_);
-  auto menu_item = std::make_unique<ExtensionsMenuItemView>(
-      ExtensionsMenuItemView::MenuItemType::kExtensions, browser(),
-      std::move(controller), true);
+  auto menu_item = std::make_unique<InstalledExtensionMenuItemView>(
+      browser(), std::move(controller), true);
   primary_button_ = menu_item->primary_action_button_for_testing();
   pin_button_ = menu_item->pin_button_for_testing();
   context_menu_button_ = menu_item->context_menu_button_for_testing();
@@ -79,14 +79,14 @@
   widget_->SetContentsView(std::move(menu_item));
 }
 
-void ExtensionsMenuItemViewTest::TearDown() {
+void InstalledExtensionMenuItemViewTest::TearDown() {
   // All windows need to be closed before tear down.
   widget_.reset();
 
   TestWithBrowserView::TearDown();
 }
 
-TEST_F(ExtensionsMenuItemViewTest, UpdatesToDisplayCorrectActionTitle) {
+TEST_F(InstalledExtensionMenuItemViewTest, UpdatesToDisplayCorrectActionTitle) {
   EXPECT_EQ(primary_button()->label_text_for_testing(),
             initial_extension_name_);
 
@@ -96,7 +96,7 @@
   EXPECT_EQ(primary_button()->label_text_for_testing(), extension_name);
 }
 
-TEST_F(ExtensionsMenuItemViewTest, UpdatesToDisplayTooltip) {
+TEST_F(InstalledExtensionMenuItemViewTest, UpdatesToDisplayTooltip) {
   EXPECT_EQ(primary_button()->GetTooltipText(gfx::Point()), initial_tooltip_);
 
   std::u16string tooltip = u"New Tooltip";
@@ -105,7 +105,8 @@
   EXPECT_EQ(primary_button()->GetTooltipText(gfx::Point()), tooltip);
 }
 
-TEST_F(ExtensionsMenuItemViewTest, ButtonMatchesEnabledStateOfExtension) {
+TEST_F(InstalledExtensionMenuItemViewTest,
+       ButtonMatchesEnabledStateOfExtension) {
   EXPECT_TRUE(primary_button()->GetEnabled());
   controller_->SetEnabled(false);
   EXPECT_FALSE(primary_button()->GetEnabled());
@@ -113,7 +114,7 @@
   EXPECT_TRUE(primary_button()->GetEnabled());
 }
 
-TEST_F(ExtensionsMenuItemViewTest, NotifyClickExecutesAction) {
+TEST_F(InstalledExtensionMenuItemViewTest, NotifyClickExecutesAction) {
   base::UserActionTester user_action_tester;
   constexpr char kActivatedUserAction[] =
       "Extensions.Toolbar.ExtensionActivatedFromMenu";
@@ -127,7 +128,7 @@
   EXPECT_EQ(1, user_action_tester.GetActionCount(kActivatedUserAction));
 }
 
-TEST_F(ExtensionsMenuItemViewTest, PinButtonUserAction) {
+TEST_F(InstalledExtensionMenuItemViewTest, PinButtonUserAction) {
   base::UserActionTester user_action_tester;
   constexpr char kPinButtonUserAction[] = "Extensions.Toolbar.PinButtonPressed";
   EXPECT_EQ(0, user_action_tester.GetActionCount(kPinButtonUserAction));
@@ -137,7 +138,7 @@
   EXPECT_EQ(1, user_action_tester.GetActionCount(kPinButtonUserAction));
 }
 
-TEST_F(ExtensionsMenuItemViewTest, ContextMenuButtonUserAction) {
+TEST_F(InstalledExtensionMenuItemViewTest, ContextMenuButtonUserAction) {
   base::UserActionTester user_action_tester;
   constexpr char kContextMenuButtonUserAction[] =
       "Extensions.Toolbar.MoreActionsButtonPressedFromMenu";
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
index d68a8b7..b0bb215e 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/extensions/extensions_menu_item_view.h"
 
+#include <memory>
 #include <utility>
 
 #include "base/bind.h"
@@ -45,7 +46,8 @@
 constexpr int kSecondaryIconSizeDp = 16;
 // Set secondary item insets to get to square buttons.
 constexpr gfx::Insets kSecondaryButtonInsets = gfx::Insets(
-    (ExtensionsMenuItemView::kMenuItemHeightDp - kSecondaryIconSizeDp) / 2);
+    (InstalledExtensionMenuItemView::kMenuItemHeightDp - kSecondaryIconSizeDp) /
+    2);
 constexpr int EXTENSION_CONTEXT_MENU = 13;
 constexpr int EXTENSION_PINNING = 14;
 
@@ -64,69 +66,147 @@
 }  // namespace
 
 // static
-constexpr gfx::Size ExtensionsMenuItemView::kIconSize;
+constexpr gfx::Size InstalledExtensionMenuItemView::kIconSize;
 
-ExtensionsMenuItemView::ExtensionsMenuItemView(
-    MenuItemType item_type,
+SiteAccessMenuItemView::SiteAccessMenuItemView(
     Browser* browser,
     std::unique_ptr<ToolbarActionViewController> controller,
     bool allow_pinning)
-    : item_type_(item_type),
-      browser_(browser),
-      primary_action_button_(
-          new ExtensionsMenuButton(browser, controller.get(), allow_pinning)),
-      controller_(std::move(controller)),
-      model_(ToolbarActionsModel::Get(browser_->profile())) {
+    : browser_(browser), controller_(std::move(controller)) {
   // Items with kSiteAccess type should only be created if their
   // associated extension has or requests access to the current page.
-  if (item_type == MenuItemType::kSiteAccess) {
-    DCHECK(controller_->GetSiteInteraction(
-               browser->tab_strip_model()->GetActiveWebContents()) !=
-           extensions::SitePermissionsHelper::SiteInteraction::kNone);
-  }
+  DCHECK(controller_->GetSiteInteraction(
+             browser->tab_strip_model()->GetActiveWebContents()) !=
+         extensions::SitePermissionsHelper::SiteInteraction::kNone);
 
-  // Set so the extension button receives enter/exit on children to retain hover
-  // status when hovering child views.
-  SetNotifyEnterExitOnChild(true);
+  // Create the combobox model that will be used by the builder.
+  auto* extension = extensions::ExtensionRegistry::Get(browser_->profile())
+                        ->enabled_extensions()
+                        .GetByID(controller_->GetId());
+  auto combobox_model =
+      std::make_unique<ExtensionSiteAccessComboboxModel>(browser_, extension);
+  site_access_combobox_model_ = combobox_model.get();
 
-  views::FlexLayout* layout_manager_ =
-      SetLayoutManager(std::make_unique<views::FlexLayout>());
-  layout_manager_->SetOrientation(views::LayoutOrientation::kHorizontal)
-      .SetIgnoreDefaultMainAxisMargins(true);
-
-  AddChildView(primary_action_button_.get());
-  primary_action_button_->SetProperty(
-      views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded));
-
-  if (item_type_ == MenuItemType::kExtensions) {
-    AddPinButton();
-    AddContextMenuButton();
-  } else {
-    AddSiteAccessCombobox();
-  }
+  views::Builder<SiteAccessMenuItemView>(this)
+      .SetOrientation(views::LayoutOrientation::kHorizontal)
+      .SetIgnoreDefaultMainAxisMargins(true)
+      // Set so the extension button receives enter/exit on children to retain
+      // hover status when hovering child views.
+      .SetNotifyEnterExitOnChild(true)
+      .AddChildren(
+          views::Builder<ExtensionsMenuButton>(
+              std::make_unique<ExtensionsMenuButton>(
+                  browser_, controller_.get(), allow_pinning))
+              .CopyAddressTo(&primary_action_button_)
+              .SetProperty(views::kFlexBehaviorKey,
+                           views::FlexSpecification(
+                               views::MinimumFlexSizeRule::kScaleToZero,
+                               views::MaximumFlexSizeRule::kUnbounded)),
+          views::Builder<views::Combobox>(
+              std::make_unique<views::Combobox>(std::move(combobox_model)))
+              .CopyAddressTo(&site_access_combobox_)
+              .SetAccessibleName(l10n_util::GetStringUTF16(
+                  IDS_ACCNAME_EXTENSIONS_MENU_SITE_ACCESS_COMBOBOX))
+              .SetCallback(base::BindRepeating(
+                  &SiteAccessMenuItemView::OnComboboxSelectionChanged,
+                  base::Unretained(this))))
+      .BuildChildren();
 }
 
-ExtensionsMenuItemView::~ExtensionsMenuItemView() = default;
+SiteAccessMenuItemView::~SiteAccessMenuItemView() = default;
 
-void ExtensionsMenuItemView::OnThemeChanged() {
+void SiteAccessMenuItemView::Update() {
+  view_controller()->UpdateState();
+
+  content::WebContents* web_contents =
+      browser_->tab_strip_model()->GetActiveWebContents();
+  if (!web_contents)
+    return;
+  int index = site_access_combobox_model_->GetCurrentSiteAccessIndex();
+  site_access_combobox_->SetSelectedIndex(index);
+}
+
+void SiteAccessMenuItemView::OnComboboxSelectionChanged() {
+  int selected_index = site_access_combobox_->GetSelectedIndex();
+  site_access_combobox_model_->HandleSelection(selected_index);
+}
+
+InstalledExtensionMenuItemView::InstalledExtensionMenuItemView(
+    Browser* browser,
+    std::unique_ptr<ToolbarActionViewController> controller,
+    bool allow_pinning)
+    : browser_(browser),
+      controller_(std::move(controller)),
+      model_(ToolbarActionsModel::Get(browser_->profile())) {
+  views::Builder<InstalledExtensionMenuItemView>(this)
+      .SetOrientation(views::LayoutOrientation::kHorizontal)
+      .SetIgnoreDefaultMainAxisMargins(true)
+      // Set so the extension button receives enter/exit on children to retain
+      // hover status when hovering child views.
+      .SetNotifyEnterExitOnChild(true)
+      .AddChildren(
+          views::Builder<ExtensionsMenuButton>(
+              std::make_unique<ExtensionsMenuButton>(
+                  browser_, controller_.get(), allow_pinning))
+              .CopyAddressTo(&primary_action_button_)
+              .SetProperty(views::kFlexBehaviorKey,
+                           views::FlexSpecification(
+                               views::MinimumFlexSizeRule::kScaleToZero,
+                               views::MaximumFlexSizeRule::kUnbounded)),
+          views::Builder<HoverButton>(
+              std::make_unique<HoverButton>(
+                  base::BindRepeating(
+                      &InstalledExtensionMenuItemView::OnPinButtonPressed,
+                      base::Unretained(this)),
+                  std::u16string()))
+              .CopyAddressTo(&pin_button_)
+              .SetID(EXTENSION_PINNING)
+              .SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets)),
+          views::Builder<HoverButton>(
+              std::make_unique<HoverButton>(views::Button::PressedCallback(),
+                                            std::u16string()))
+              .CopyAddressTo(&context_menu_button_)
+              .SetID(EXTENSION_CONTEXT_MENU)
+              .SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets))
+              .SetTooltipText(l10n_util::GetStringUTF16(
+                  IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP)))
+      .BuildChildren();
+
+  // Add a controller to the context menu
+  context_menu_controller_ = std::make_unique<ExtensionContextMenuController>(
+      controller_.get(),
+      extensions::ExtensionContextMenuModel::ContextMenuSource::kMenuItem);
+
+  context_menu_button_->SetButtonController(
+      std::make_unique<views::MenuButtonController>(
+          context_menu_button_.get(),
+          base::BindRepeating(
+              &InstalledExtensionMenuItemView::OnContextMenuPressed,
+              base::Unretained(this)),
+          std::make_unique<views::Button::DefaultButtonControllerDelegate>(
+              context_menu_button_.get())));
+}
+
+InstalledExtensionMenuItemView::~InstalledExtensionMenuItemView() = default;
+
+void InstalledExtensionMenuItemView::OnThemeChanged() {
   views::View::OnThemeChanged();
-  if (item_type_ == MenuItemType::kExtensions) {
-    const SkColor icon_color =
-        GetAdjustedIconColor(GetColorProvider()->GetColor(ui::kColorMenuIcon));
+  const SkColor icon_color =
+      GetAdjustedIconColor(GetColorProvider()->GetColor(ui::kColorMenuIcon));
 
-    if (pin_button_)
-      views::InkDrop::Get(pin_button_)->SetBaseColor(icon_color);
+  if (pin_button_)
+    views::InkDrop::Get(pin_button_)->SetBaseColor(icon_color);
 
-    SetButtonIconWithColor(context_menu_button_, kBrowserToolsIcon, icon_color);
+  SetButtonIconWithColor(context_menu_button_, kBrowserToolsIcon, icon_color);
 
-    UpdatePinButton();
-  }
+  UpdatePinButton();
 }
 
-void ExtensionsMenuItemView::UpdatePinButton() {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
+void InstalledExtensionMenuItemView::Update() {
+  view_controller()->UpdateState();
+}
+
+void InstalledExtensionMenuItemView::UpdatePinButton() {
   if (!pin_button_)
     return;
 
@@ -158,19 +238,12 @@
                          icon_color);
 }
 
-bool ExtensionsMenuItemView::IsContextMenuRunningForTesting() const {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
-  return context_menu_controller_->IsMenuRunning();
-}
-
-bool ExtensionsMenuItemView::IsPinned() const {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
+bool InstalledExtensionMenuItemView::IsPinned() const {
   // |model_| can be null in unit tests.
   return model_ && model_->IsActionPinned(controller_->GetId());
 }
 
-void ExtensionsMenuItemView::ContextMenuPressed() {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
+void InstalledExtensionMenuItemView::OnContextMenuPressed() {
   base::RecordAction(base::UserMetricsAction(
       "Extensions.Toolbar.MoreActionsButtonPressedFromMenu"));
   // TODO(crbug.com/998298): Cleanup the menu source type.
@@ -179,9 +252,7 @@
       ui::MenuSourceType::MENU_SOURCE_MOUSE);
 }
 
-void ExtensionsMenuItemView::PinButtonPressed() {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
-
+void InstalledExtensionMenuItemView::OnPinButtonPressed() {
   base::RecordAction(
       base::UserMetricsAction("Extensions.Toolbar.PinButtonPressed"));
   model_->SetActionVisibility(controller_->GetId(), !IsPinned());
@@ -189,93 +260,12 @@
       IsPinned() ? IDS_EXTENSION_PINNED : IDS_EXTENSION_UNPINNED));
 }
 
-void ExtensionsMenuItemView::Update() {
-  view_controller()->UpdateState();
-  if (item_type_ == MenuItemType::kSiteAccess) {
-    content::WebContents* web_contents =
-        browser_->tab_strip_model()->GetActiveWebContents();
-    if (!web_contents)
-      return;
-    int index = site_access_combobox_model_->GetCurrentSiteAccessIndex();
-    site_access_combobox_->SetSelectedIndex(index);
-  }
+bool InstalledExtensionMenuItemView::IsContextMenuRunningForTesting() const {
+  return context_menu_controller_->IsMenuRunning();
 }
 
-ExtensionsMenuButton*
-ExtensionsMenuItemView::primary_action_button_for_testing() {
-  return primary_action_button_;
-}
-
-void ExtensionsMenuItemView::AddPinButton() {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
-
-  if (primary_action_button_->CanShowIconInToolbar()) {
-    auto pin_button = std::make_unique<HoverButton>(
-        base::BindRepeating(&ExtensionsMenuItemView::PinButtonPressed,
-                            base::Unretained(this)),
-        std::u16string());
-    pin_button->SetID(EXTENSION_PINNING);
-    pin_button->SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets));
-
-    pin_button_ = pin_button.get();
-    AddChildView(std::move(pin_button));
-  }
-  UpdatePinButton();
-}
-
-void ExtensionsMenuItemView::AddContextMenuButton() {
-  DCHECK_EQ(item_type_, MenuItemType::kExtensions);
-
-  context_menu_controller_ = std::make_unique<ExtensionContextMenuController>(
-      controller_.get(),
-      extensions::ExtensionContextMenuModel::ContextMenuSource::kMenuItem);
-
-  auto context_menu_button = std::make_unique<HoverButton>(
-      views::Button::PressedCallback(), std::u16string());
-  context_menu_button->SetID(EXTENSION_CONTEXT_MENU);
-  context_menu_button->SetBorder(
-      views::CreateEmptyBorder(kSecondaryButtonInsets));
-  context_menu_button->SetTooltipText(
-      l10n_util::GetStringUTF16(IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP));
-  context_menu_button->SetButtonController(
-      std::make_unique<views::MenuButtonController>(
-          context_menu_button.get(),
-          base::BindRepeating(&ExtensionsMenuItemView::ContextMenuPressed,
-                              base::Unretained(this)),
-          std::make_unique<views::Button::DefaultButtonControllerDelegate>(
-              context_menu_button.get())));
-  context_menu_button_ = AddChildView(std::move(context_menu_button));
-}
-
-void ExtensionsMenuItemView::AddSiteAccessCombobox() {
-  DCHECK_EQ(item_type_, MenuItemType::kSiteAccess);
-
-  auto* extension = extensions::ExtensionRegistry::Get(browser_->profile())
-                        ->enabled_extensions()
-                        .GetByID(controller_->GetId());
-
-  auto combobox_model =
-      std::make_unique<ExtensionSiteAccessComboboxModel>(browser_, extension);
-  site_access_combobox_model_ = combobox_model.get();
-
-  auto combobox = std::make_unique<views::Combobox>(std::move(combobox_model));
-  site_access_combobox_ = AddChildView(std::move(combobox));
-
-  site_access_combobox_->SetAccessibleName(l10n_util::GetStringUTF16(
-      IDS_ACCNAME_EXTENSIONS_MENU_SITE_ACCESS_COMBOBOX));
-  site_access_combobox_->SetCallback(
-      base::BindRepeating(&ExtensionsMenuItemView::OnComboboxSelectionChanged,
-                          base::Unretained(this)));
-}
-
-void ExtensionsMenuItemView::OnComboboxSelectionChanged() {
-  DCHECK_EQ(item_type_, MenuItemType::kSiteAccess);
-
-  int selected_index = site_access_combobox_->GetSelectedIndex();
-  site_access_combobox_model_->HandleSelection(selected_index);
-}
-
-SkColor ExtensionsMenuItemView::GetAdjustedIconColor(SkColor icon_color) const {
+SkColor InstalledExtensionMenuItemView::GetAdjustedIconColor(
+    SkColor icon_color) const {
   const SkColor background_color =
       GetColorProvider()->GetColor(ui::kColorBubbleBackground);
   if (background_color != SK_ColorTRANSPARENT) {
@@ -284,5 +274,8 @@
   return icon_color;
 }
 
-BEGIN_METADATA(ExtensionsMenuItemView, views::View)
+BEGIN_METADATA(SiteAccessMenuItemView, views::View)
+END_METADATA
+
+BEGIN_METADATA(InstalledExtensionMenuItemView, views::View)
 END_METADATA
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
index 51e387b5..e1a9a32ac 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h
@@ -10,7 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/ui/extensions/extension_site_access_combobox_model.h"
 #include "ui/base/metadata/metadata_header_macros.h"
-#include "ui/views/view.h"
+#include "ui/views/layout/flex_layout_view.h"
 
 class Browser;
 class ExtensionContextMenuController;
@@ -24,34 +24,81 @@
 class Combobox;
 }  // namespace views
 
-// ExtensionsMenuItemView is a single row inside the extensions menu for a
-// particular extension. Includes information about the extension in addition to
-// a button to pin the extension to the toolbar and a button for accessing the
-// associated context menu.
-class ExtensionsMenuItemView : public views::View {
+// SiteAccessMenuItemView is a single row inside the extensions menu for an
+// extension with host permissions. Includes information about the extension and
+// a dropdown to select host permission options.
+class SiteAccessMenuItemView : public views::FlexLayoutView {
  public:
-  METADATA_HEADER(ExtensionsMenuItemView);
-
-  enum class MenuItemType {
-    // Used by the extensions tab in ExtensionsTabbedMenu to add a pin button
-    // and a context menu button to the item view.
-    kExtensions,
-    // Used by the site access tab in ExtensionsTabbedMenu to add a dropdown
-    // button to the item view.
-    kSiteAccess
-  };
+  METADATA_HEADER(SiteAccessMenuItemView);
 
   static constexpr int kMenuItemHeightDp = 40;
   static constexpr gfx::Size kIconSize{28, 28};
 
-  ExtensionsMenuItemView(
-      MenuItemType item_type,
+  SiteAccessMenuItemView(
       Browser* browser,
       std::unique_ptr<ToolbarActionViewController> controller,
       bool allow_pinning);
-  ExtensionsMenuItemView(const ExtensionsMenuItemView&) = delete;
-  ExtensionsMenuItemView& operator=(const ExtensionsMenuItemView&) = delete;
-  ~ExtensionsMenuItemView() override;
+  SiteAccessMenuItemView(const SiteAccessMenuItemView&) = delete;
+  SiteAccessMenuItemView& operator=(const SiteAccessMenuItemView&) = delete;
+  ~SiteAccessMenuItemView() override;
+
+  // Updates the controller and child views to be on sync with the parent views.
+  void Update();
+
+  ToolbarActionViewController* view_controller() { return controller_.get(); }
+
+  ExtensionsMenuButton* primary_action_button_for_testing() {
+    return primary_action_button_;
+  }
+  views::Combobox* site_access_combobox_for_testing() {
+    return site_access_combobox_;
+  }
+
+ private:
+  // Handles the selection of an option in a combobox. This is passed as a
+  // callback to `site_access_combobox`.
+  void OnComboboxSelectionChanged();
+
+  const raw_ptr<Browser> browser_;
+
+  // Controller responsible for an action that is shown in the toolbar.
+  std::unique_ptr<ToolbarActionViewController> controller_;
+
+  raw_ptr<ExtensionsMenuButton> primary_action_button_;
+
+  raw_ptr<views::Combobox> site_access_combobox_ = nullptr;
+  raw_ptr<ExtensionSiteAccessComboboxModel> site_access_combobox_model_ =
+      nullptr;
+};
+
+BEGIN_VIEW_BUILDER(/* no export */,
+                   SiteAccessMenuItemView,
+                   views::FlexLayoutView)
+END_VIEW_BUILDER
+
+DEFINE_VIEW_BUILDER(/* no export */, SiteAccessMenuItemView)
+
+// InstalledExtensionMenuItemView is a single row inside the extensions menu for
+// a every installed extension. Includes information about the extension, a
+// button to pin the extension to the toolbar and a button for accessing the
+// associated context menu.
+class InstalledExtensionMenuItemView : public views::FlexLayoutView {
+ public:
+  METADATA_HEADER(InstalledExtensionMenuItemView);
+
+  // TODO(emiliapaz): Consider moving these variables outside this class.
+  static constexpr int kMenuItemHeightDp = 40;
+  static constexpr gfx::Size kIconSize{28, 28};
+
+  InstalledExtensionMenuItemView(
+      Browser* browser,
+      std::unique_ptr<ToolbarActionViewController> controller,
+      bool allow_pinning);
+  InstalledExtensionMenuItemView(const InstalledExtensionMenuItemView&) =
+      delete;
+  InstalledExtensionMenuItemView& operator=(
+      const InstalledExtensionMenuItemView&) = delete;
+  ~InstalledExtensionMenuItemView() override;
 
   // views::View:
   void OnThemeChanged() override;
@@ -59,82 +106,63 @@
   // Updates the controller and child views to be on sync with the parent views.
   void Update();
 
-  // Updates the pin button. `item_type_` must be `ItemType::kExtensions`.
+  // Updates the pin button.
   void UpdatePinButton();
 
-  // Returns whether the action corresponding to this view is pinned to the
-  // toolbar. `item_type_` must be `ItemType::kExtensions`.
-  bool IsPinned() const;
-
-  // Displays the context menu. `item_type_` must be `ItemType::kExtensions`.
-  void ContextMenuPressed();
-
-  // Pins or unpins the action in the toolbar. `item_type_` must be
-  // `ItemType::kExtensions`.
-  void PinButtonPressed();
-
   ToolbarActionViewController* view_controller() { return controller_.get(); }
   const ToolbarActionViewController* view_controller() const {
     return controller_.get();
   }
 
   bool IsContextMenuRunningForTesting() const;
-  ExtensionsMenuButton* primary_action_button_for_testing();
+  ExtensionsMenuButton* primary_action_button_for_testing() {
+    return primary_action_button_;
+  }
   HoverButton* context_menu_button_for_testing() {
     return context_menu_button_;
   }
   HoverButton* pin_button_for_testing() { return pin_button_; }
-  views::Combobox* site_access_combobox_for_testing() {
-    return site_access_combobox_;
-  }
 
  private:
-  // Adds a pin button as a child view. `item_type_` must be
-  // `ItemType::kExtensions`.
-  void AddPinButton();
-
-  // Adds a context menu button as a child view. `item_type_` must be
-  // `ItemType::kExtensions`.
-  void AddContextMenuButton();
-
-  // Adds a site access combobox as a child view. `item_type_` must be
-  // `ItemType::kSiteAccess`.
-  void AddSiteAccessCombobox();
-
-  // Handles the selection of a combobox option. `item_type_` must be
-  // `ItemType::kSiteAccess`.
-  void OnComboboxSelectionChanged();
-
-  // Maybe adjust |icon_color| to assure high enough contrast with the
+  // Maybe adjust `icon_color` to assure high enough contrast with the
   // background.
   SkColor GetAdjustedIconColor(SkColor icon_color) const;
 
-  // Determines which views will be added as children of this item view.
-  const MenuItemType item_type_;
+  // Returns whether the action corresponding to this view is pinned to the
+  // toolbar.
+  bool IsPinned() const;
+
+  // Handles the context menu button press. This is passed as a callback to
+  // `context_menu_button_`.
+  void OnContextMenuPressed();
+
+  // Handles the pin button press. This is passed as a callback to
+  // `pin_button_`.
+  void OnPinButtonPressed();
 
   const raw_ptr<Browser> browser_;
 
-  // Extension action button present in `ItemType::kSiteAccess` and
-  // `ItemType::kExtensions`.
-  const raw_ptr<ExtensionsMenuButton> primary_action_button_;
-  // Pin button present in `ItemType::kExtensions`.
-  raw_ptr<HoverButton> pin_button_ = nullptr;
-  // Context menu button present in `ItemType::kExtensions`.
-  raw_ptr<HoverButton> context_menu_button_ = nullptr;
-  // Dropdown list present in `ItemType::kSiteAccess`.
-  raw_ptr<views::Combobox> site_access_combobox_ = nullptr;
-
   // Controller responsible for an action that is shown in the toolbar.
   std::unique_ptr<ToolbarActionViewController> controller_;
-  // Controller responsible for showing the context menu for an extension.
-  std::unique_ptr<ExtensionContextMenuController> context_menu_controller_;
 
   // Model for the browser actions toolbar that provides information such as the
   // action pin status or visibility.
   const raw_ptr<ToolbarActionsModel> model_;
-  // Model for `site_access_combobox_` to select an option.
-  raw_ptr<ExtensionSiteAccessComboboxModel> site_access_combobox_model_ =
-      nullptr;
+
+  raw_ptr<ExtensionsMenuButton> primary_action_button_;
+
+  raw_ptr<HoverButton> pin_button_ = nullptr;
+
+  raw_ptr<HoverButton> context_menu_button_ = nullptr;
+  // Controller responsible for showing the context menu for an extension.
+  std::unique_ptr<ExtensionContextMenuController> context_menu_controller_;
 };
 
+BEGIN_VIEW_BUILDER(/* no export */,
+                   InstalledExtensionMenuItemView,
+                   views::FlexLayoutView)
+END_VIEW_BUILDER
+
+DEFINE_VIEW_BUILDER(/* no export */, InstalledExtensionMenuItemView)
+
 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_ITEM_VIEW_H_
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc b/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc
index e29b0ad0..004ec682 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_test_util.cc
@@ -121,14 +121,14 @@
 }
 
 void ExtensionsMenuTestUtil::InspectPopup(const extensions::ExtensionId& id) {
-  ExtensionsMenuItemView* view = GetMenuItemViewForId(id);
+  InstalledExtensionMenuItemView* view = GetMenuItemViewForId(id);
   DCHECK(view);
   static_cast<ExtensionActionViewController*>(view->view_controller())
       ->InspectPopup();
 }
 
 bool ExtensionsMenuTestUtil::HasIcon(const extensions::ExtensionId& id) {
-  ExtensionsMenuItemView* view = GetMenuItemViewForId(id);
+  InstalledExtensionMenuItemView* view = GetMenuItemViewForId(id);
   DCHECK(view);
   return !view->primary_action_button_for_testing()
               ->GetImage(views::Button::STATE_NORMAL)
@@ -136,14 +136,14 @@
 }
 
 gfx::Image ExtensionsMenuTestUtil::GetIcon(const extensions::ExtensionId& id) {
-  ExtensionsMenuItemView* view = GetMenuItemViewForId(id);
+  InstalledExtensionMenuItemView* view = GetMenuItemViewForId(id);
   DCHECK(view);
   return gfx::Image(view->primary_action_button_for_testing()->GetImage(
       views::Button::STATE_NORMAL));
 }
 
 void ExtensionsMenuTestUtil::Press(const extensions::ExtensionId& id) {
-  ExtensionsMenuItemView* view = GetMenuItemViewForId(id);
+  InstalledExtensionMenuItemView* view = GetMenuItemViewForId(id);
   DCHECK(view);
   ExtensionsMenuButton* primary_button =
       view->primary_action_button_for_testing();
@@ -155,7 +155,7 @@
 
 std::string ExtensionsMenuTestUtil::GetTooltip(
     const extensions::ExtensionId& id) {
-  ExtensionsMenuItemView* view = GetMenuItemViewForId(id);
+  InstalledExtensionMenuItemView* view = GetMenuItemViewForId(id);
   DCHECK(view);
   ExtensionsMenuButton* primary_button =
       view->primary_action_button_for_testing();
@@ -230,12 +230,11 @@
       views::BubbleFrameView::PreferredArrowAdjustment::kMirror);
 }
 
-ExtensionsMenuItemView* ExtensionsMenuTestUtil::GetMenuItemViewForId(
+InstalledExtensionMenuItemView* ExtensionsMenuTestUtil::GetMenuItemViewForId(
     const extensions::ExtensionId& id) {
-  base::flat_set<ExtensionsMenuItemView*> menu_items =
-      menu_view_->extensions_menu_items_for_testing();
-  auto iter =
-      base::ranges::find_if(menu_items, [id](ExtensionsMenuItemView* view) {
+  auto menu_items = menu_view_->extensions_menu_items_for_testing();
+  auto iter = base::ranges::find_if(
+      menu_items, [id](InstalledExtensionMenuItemView* view) {
         return view->view_controller()->GetId() == id;
       });
   if (iter == menu_items.end())
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_test_util.h b/chrome/browser/ui/views/extensions/extensions_menu_test_util.h
index 3af32e59..afac6f6 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_test_util.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_test_util.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/extensions/extension_action_test_helper.h"
 
 class Browser;
-class ExtensionsMenuItemView;
+class InstalledExtensionMenuItemView;
 class ExtensionsMenuView;
 class ExtensionsToolbarContainer;
 
@@ -58,9 +58,9 @@
   class MenuViewObserver;
   class Wrapper;
 
-  // Returns the ExtensionsMenuItemView for the given `id` from the
+  // Returns the InstalledExtensionMenuItemView for the given `id` from the
   // `menu_view`.
-  ExtensionsMenuItemView* GetMenuItemViewForId(
+  InstalledExtensionMenuItemView* GetMenuItemViewForId(
       const extensions::ExtensionId& id);
 
   // An override to allow test instances of the ExtensionsMenuView.
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
index ea3b785..e299e44 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc
@@ -52,19 +52,19 @@
 
 constexpr int kSettingsIconSize = 16;
 
-bool CompareExtensionMenuItemViews(const ExtensionsMenuItemView* a,
-                                   const ExtensionsMenuItemView* b) {
+bool CompareExtensionMenuItemViews(const InstalledExtensionMenuItemView* a,
+                                   const InstalledExtensionMenuItemView* b) {
   return base::i18n::ToLower(a->view_controller()->GetActionName()) <
          base::i18n::ToLower(b->view_controller()->GetActionName());
 }
 
-// A helper method to convert to an ExtensionsMenuItemView. This cannot be used
-// to *determine* if a view is an ExtensionsMenuItemView (it should only be used
-// when the view is known to be one). It is only used as an extra measure to
-// prevent bad static casts.
-ExtensionsMenuItemView* GetAsMenuItemView(views::View* view) {
-  DCHECK(views::IsViewClass<ExtensionsMenuItemView>(view));
-  return static_cast<ExtensionsMenuItemView*>(view);
+// A helper method to convert to an InstalledExtensionMenuItemView. This cannot
+// be used to *determine* if a view is an InstalledExtensionMenuItemView (it
+// should only be used when the view is known to be one). It is only used as an
+// extra measure to prevent bad static casts.
+InstalledExtensionMenuItemView* GetAsMenuItemView(views::View* view) {
+  DCHECK(views::IsViewClass<InstalledExtensionMenuItemView>(view));
+  return static_cast<InstalledExtensionMenuItemView*>(view);
 }
 
 }  // namespace
@@ -164,10 +164,11 @@
   // (space for badging). Add the same padding left and right of the icon to
   // visually align the settings icon and text with extension menu items.
   // TODO(pbos): Note that this code relies on CreateBubbleMenuItem() and
-  // ExtensionsMenuItemView using the same horizontal border size and
+  // InstalledExtensionMenuItemView using the same horizontal border size and
   // image-label spacing. This dependency should probably be more explicit.
   constexpr int kSettingsIconHorizontalPadding =
-      (ExtensionsMenuItemView::kIconSize.width() - kSettingsIconSize) / 2;
+      (InstalledExtensionMenuItemView::kIconSize.width() - kSettingsIconSize) /
+      2;
 
   footer->SetBorder(views::CreateEmptyBorder(
       footer->GetInsets() +
@@ -272,7 +273,7 @@
     if (section->menu_items->children().empty())
       return;
 
-    std::vector<ExtensionsMenuItemView*> menu_item_views;
+    std::vector<InstalledExtensionMenuItemView*> menu_item_views;
     for (views::View* view : section->menu_items->children())
       menu_item_views.push_back(GetAsMenuItemView(view));
 
@@ -295,16 +296,16 @@
 
   // The bare `new` is safe here, because InsertMenuItem is guaranteed to
   // be added to the view hierarchy, which takes ownership.
-  auto* item = new ExtensionsMenuItemView(
-      ExtensionsMenuItemView::MenuItemType::kExtensions, browser_,
-      std::move(controller), allow_pinning_);
+  auto* item = new InstalledExtensionMenuItemView(
+      browser_, std::move(controller), allow_pinning_);
   extensions_menu_items_.insert(item);
   InsertMenuItem(item);
   // Sanity check that the item was added.
   DCHECK(Contains(item));
 }
 
-void ExtensionsMenuView::InsertMenuItem(ExtensionsMenuItemView* menu_item) {
+void ExtensionsMenuView::InsertMenuItem(
+    InstalledExtensionMenuItemView* menu_item) {
   DCHECK(!Contains(menu_item))
       << "Trying to insert a menu item that is already added in a section!";
   auto site_interaction = menu_item->view_controller()->GetSiteInteraction(
@@ -329,7 +330,7 @@
 }
 
 void ExtensionsMenuView::Update() {
-  for (ExtensionsMenuItemView* view : extensions_menu_items_)
+  for (InstalledExtensionMenuItemView* view : extensions_menu_items_)
     view->view_controller()->UpdateState();
 
   content::WebContents* const web_contents =
@@ -338,7 +339,7 @@
                                                          Section* section) {
     // Note: Collect the views to move separately, so that we don't change the
     // children of the view during iteration.
-    std::vector<ExtensionsMenuItemView*> views_to_move;
+    std::vector<InstalledExtensionMenuItemView*> views_to_move;
     for (views::View* view : section->menu_items->children()) {
       auto* menu_item = GetAsMenuItemView(view);
       auto site_interaction =
@@ -348,7 +349,7 @@
       views_to_move.push_back(menu_item);
     }
 
-    for (ExtensionsMenuItemView* menu_item : views_to_move) {
+    for (InstalledExtensionMenuItemView* menu_item : views_to_move) {
       section->menu_items->RemoveChildView(menu_item);
       InsertMenuItem(menu_item);
     }
@@ -372,7 +373,7 @@
   // Sanity checks: verify that all extensions are properly sorted and in the
   // correct section.
   auto check_section = [this, web_contents](Section* section) {
-    std::vector<ExtensionsMenuItemView*> menu_items;
+    std::vector<InstalledExtensionMenuItemView*> menu_items;
     for (views::View* view : section->menu_items->children()) {
       auto* menu_item = GetAsMenuItemView(view);
       auto site_interaction =
@@ -395,7 +396,7 @@
   // corresponds to an item in the model (since we already checked that the size
   // is equal for |action_ids| and |extensions_menu_items_|, this implicitly
   // guarantees that we have a view per item in |action_ids| as well).
-  for (ExtensionsMenuItemView* item : extensions_menu_items_) {
+  for (InstalledExtensionMenuItemView* item : extensions_menu_items_) {
     DCHECK(Contains(item));
     DCHECK(base::Contains(action_ids, item->view_controller()->GetId()));
   }
@@ -449,11 +450,12 @@
 void ExtensionsMenuView::OnToolbarActionRemoved(
     const ToolbarActionsModel::ActionId& action_id) {
   auto iter = base::ranges::find_if(
-      extensions_menu_items_, [action_id](const ExtensionsMenuItemView* item) {
+      extensions_menu_items_,
+      [action_id](const InstalledExtensionMenuItemView* item) {
         return item->view_controller()->GetId() == action_id;
       });
   DCHECK(iter != extensions_menu_items_.end());
-  ExtensionsMenuItemView* const view = *iter;
+  InstalledExtensionMenuItemView* const view = *iter;
   DCHECK(Contains(view));
   view->parent()->RemoveChildView(view);
   DCHECK(!Contains(view));
@@ -523,13 +525,13 @@
 }
 
 // static
-std::vector<ExtensionsMenuItemView*>
+std::vector<InstalledExtensionMenuItemView*>
 ExtensionsMenuView::GetSortedItemsForSectionForTesting(
     extensions::SitePermissionsHelper::SiteInteraction site_interaction) {
   const ExtensionsMenuView::Section* section =
       GetExtensionsMenuViewForTesting()->GetSectionForSiteInteraction(
           site_interaction);
-  std::vector<ExtensionsMenuItemView*> menu_item_views;
+  std::vector<InstalledExtensionMenuItemView*> menu_item_views;
   for (views::View* view : section->menu_items->children())
     menu_item_views.push_back(GetAsMenuItemView(view));
   return menu_item_views;
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view.h b/chrome/browser/ui/views/extensions/extensions_menu_view.h
index 534a801..56b028b 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view.h
@@ -29,7 +29,7 @@
 
 class Browser;
 class ExtensionsContainer;
-class ExtensionsMenuItemView;
+class InstalledExtensionMenuItemView;
 
 // This bubble view displays a list of user extensions and a button to get to
 // managing the user's extensions (chrome://extensions).
@@ -65,7 +65,7 @@
   static ExtensionsMenuView* GetExtensionsMenuViewForTesting();
 
   // Returns the children of a section for the given `site_interaction`.
-  static std::vector<ExtensionsMenuItemView*>
+  static std::vector<InstalledExtensionMenuItemView*>
   GetSortedItemsForSectionForTesting(
       extensions::SitePermissionsHelper::SiteInteraction site_interaction);
 
@@ -91,7 +91,8 @@
   void OnToolbarModelInitialized() override;
   void OnToolbarPinnedActionsChanged() override;
 
-  base::flat_set<ExtensionsMenuItemView*> extensions_menu_items_for_testing() {
+  base::flat_set<InstalledExtensionMenuItemView*>
+  extensions_menu_items_for_testing() {
     return extensions_menu_items_;
   }
   views::Button* manage_extensions_button_for_testing() {
@@ -144,7 +145,7 @@
 
   // Inserts the menu item into the appropriate section (but not necessarily at
   // the right spot).
-  void InsertMenuItem(ExtensionsMenuItemView* menu_item);
+  void InsertMenuItem(InstalledExtensionMenuItemView* menu_item);
 
   // Adds a menu item for a newly-added extension.
   void CreateAndInsertNewItem(const ToolbarActionsModel::ActionId& id);
@@ -169,7 +170,7 @@
 
   // A collection of all menu item views in the menu. Note that this is
   // *unordered*, since the menu puts extensions into different sections.
-  base::flat_set<ExtensionsMenuItemView*> extensions_menu_items_;
+  base::flat_set<InstalledExtensionMenuItemView*> extensions_menu_items_;
 
   raw_ptr<views::LabelButton> manage_extensions_button_ = nullptr;
 
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
index 2f0effc..a62dc85 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
@@ -54,7 +54,8 @@
 
 class ExtensionsMenuViewInteractiveUITest : public ExtensionsToolbarUITest {
  public:
-  static base::flat_set<ExtensionsMenuItemView*> GetExtensionsMenuItemViews() {
+  static base::flat_set<InstalledExtensionMenuItemView*>
+  GetInstalledExtensionMenuItemViews() {
     return ExtensionsMenuView::GetExtensionsMenuViewForTesting()
         ->extensions_menu_items_for_testing();
   }
@@ -204,15 +205,15 @@
   }
 
   void TriggerSingleExtensionButton() {
-    auto menu_items = GetExtensionsMenuItemViews();
+    auto menu_items = GetInstalledExtensionMenuItemViews();
     ASSERT_EQ(1u, menu_items.size());
     TriggerExtensionButton((*menu_items.begin())->view_controller()->GetId());
   }
 
   void TriggerExtensionButton(const std::string& id) {
-    auto menu_items = GetExtensionsMenuItemViews();
-    auto iter =
-        base::ranges::find_if(menu_items, [id](ExtensionsMenuItemView* view) {
+    auto menu_items = GetInstalledExtensionMenuItemViews();
+    auto iter = base::ranges::find_if(
+        menu_items, [id](InstalledExtensionMenuItemView* view) {
           return view->view_controller()->GetId() == id;
         });
     ASSERT_TRUE(iter != menu_items.end());
@@ -471,7 +472,7 @@
   ShowUi("");
   VerifyUi();
   EXPECT_EQ(2u, extensions().size());
-  EXPECT_EQ(extensions().size(), GetExtensionsMenuItemViews().size());
+  EXPECT_EQ(extensions().size(), GetInstalledExtensionMenuItemViews().size());
   DismissUi();
 }
 
@@ -501,9 +502,9 @@
   ClickExtensionsMenuButton(incognito_browser());
 
   ASSERT_TRUE(VerifyUi());
-  ASSERT_EQ(1u, GetExtensionsMenuItemViews().size());
+  ASSERT_EQ(1u, GetInstalledExtensionMenuItemViews().size());
   EXPECT_EQ(views::Button::STATE_DISABLED,
-            (*GetExtensionsMenuItemViews().begin())
+            (*GetInstalledExtensionMenuItemViews().begin())
                 ->pin_button_for_testing()
                 ->GetState());
 
@@ -520,15 +521,15 @@
 
   // Pin extension from menu.
   ASSERT_TRUE(VerifyUi());
-  ASSERT_EQ(1u, GetExtensionsMenuItemViews().size());
+  ASSERT_EQ(1u, GetInstalledExtensionMenuItemViews().size());
   ui::MouseEvent click_pressed_event(ui::ET_MOUSE_PRESSED, gfx::Point(),
                                      gfx::Point(), base::TimeTicks(),
                                      ui::EF_LEFT_MOUSE_BUTTON, 0);
   ui::MouseEvent click_released_event(ui::ET_MOUSE_RELEASED, gfx::Point(),
                                       gfx::Point(), base::TimeTicks(),
                                       ui::EF_LEFT_MOUSE_BUTTON, 0);
-  ExtensionsMenuItemView* const menu_item_view =
-      *GetExtensionsMenuItemViews().begin();
+  InstalledExtensionMenuItemView* const menu_item_view =
+      *GetInstalledExtensionMenuItemViews().begin();
   menu_item_view->pin_button_for_testing()->OnMousePressed(click_pressed_event);
   menu_item_view->pin_button_for_testing()->OnMouseReleased(
       click_released_event);
@@ -636,9 +637,9 @@
   LoadTestExtension("extensions/uitest/window_open");
   ClickExtensionsMenuButton();
 
-  auto menu_items = GetExtensionsMenuItemViews();
+  auto menu_items = GetInstalledExtensionMenuItemViews();
   ASSERT_EQ(1u, menu_items.size());
-  ExtensionsMenuItemView* const item_view = *menu_items.begin();
+  InstalledExtensionMenuItemView* const item_view = *menu_items.begin();
   EXPECT_FALSE(item_view->IsContextMenuRunningForTesting());
 
   HoverButton* context_menu_button =
@@ -724,7 +725,7 @@
   // Open the extension menu so we can test the UI when permissions
   // change.
   ClickExtensionsMenuButton();
-  auto menu_items = GetExtensionsMenuItemViews();
+  auto menu_items = GetInstalledExtensionMenuItemViews();
   ASSERT_EQ(1u, menu_items.size());
   auto* item_button =
       (*menu_items.begin())->primary_action_button_for_testing();
@@ -741,7 +742,7 @@
                 u"\n"),
             item_button->GetTooltipText());
 
-  std::vector<ExtensionsMenuItemView*> active_menu_items =
+  std::vector<InstalledExtensionMenuItemView*> active_menu_items =
       ExtensionsMenuView::GetSortedItemsForSectionForTesting(
           extensions::SitePermissionsHelper::SiteInteraction::kActive);
   ASSERT_EQ(1u, active_menu_items.size());
@@ -773,7 +774,7 @@
            l10n_util::GetStringUTF16(IDS_EXTENSIONS_WANTS_ACCESS_TO_SITE)},
           u"\n"),
       item_button->GetTooltipText());
-  std::vector<ExtensionsMenuItemView*> pending_menu_items =
+  std::vector<InstalledExtensionMenuItemView*> pending_menu_items =
       ExtensionsMenuView::GetSortedItemsForSectionForTesting(
           extensions::SitePermissionsHelper::SiteInteraction::kPending);
   ASSERT_EQ(1u, pending_menu_items.size());
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc
index d97fa21..04d05c2 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_view_unittest.cc
@@ -90,14 +90,15 @@
   }
 
   // Asserts there is exactly 1 menu item and then returns it.
-  ExtensionsMenuItemView* GetOnlyMenuItem();
+  InstalledExtensionMenuItemView* GetOnlyMenuItem();
 
-  void ClickPinButton(ExtensionsMenuItemView* menu_item) const;
-  void ClickContextMenuButton(ExtensionsMenuItemView* menu_item) const;
+  void ClickPinButton(InstalledExtensionMenuItemView* menu_item) const;
+  void ClickContextMenuButton(InstalledExtensionMenuItemView* menu_item) const;
 
   std::vector<ToolbarActionView*> GetPinnedExtensionViews();
 
-  ExtensionsMenuItemView* GetExtensionsMenuItemView(const std::string& name);
+  InstalledExtensionMenuItemView* GetInstalledExtensionMenuItemView(
+      const std::string& name);
 
   // Returns a list of the names of the currently pinned extensions, in order
   // from left to right.
@@ -125,8 +126,8 @@
   return extension;
 }
 
-ExtensionsMenuItemView* ExtensionsMenuViewUnitTest::GetOnlyMenuItem() {
-  base::flat_set<ExtensionsMenuItemView*> menu_items =
+InstalledExtensionMenuItemView* ExtensionsMenuViewUnitTest::GetOnlyMenuItem() {
+  base::flat_set<InstalledExtensionMenuItemView*> menu_items =
       extensions_menu()->extensions_menu_items_for_testing();
   if (menu_items.size() != 1u) {
     ADD_FAILURE() << "Not exactly one item; size is: " << menu_items.size();
@@ -136,12 +137,12 @@
 }
 
 void ExtensionsMenuViewUnitTest::ClickPinButton(
-    ExtensionsMenuItemView* menu_item) const {
+    InstalledExtensionMenuItemView* menu_item) const {
   ClickButton(menu_item->pin_button_for_testing());
 }
 
 void ExtensionsMenuViewUnitTest::ClickContextMenuButton(
-    ExtensionsMenuItemView* menu_item) const {
+    InstalledExtensionMenuItemView* menu_item) const {
   ClickButton(menu_item->context_menu_button_for_testing());
 }
 
@@ -168,12 +169,13 @@
   return result;
 }
 
-ExtensionsMenuItemView* ExtensionsMenuViewUnitTest::GetExtensionsMenuItemView(
+InstalledExtensionMenuItemView*
+ExtensionsMenuViewUnitTest::GetInstalledExtensionMenuItemView(
     const std::string& name) {
-  base::flat_set<ExtensionsMenuItemView*> menu_items =
+  base::flat_set<InstalledExtensionMenuItemView*> menu_items =
       extensions_menu()->extensions_menu_items_for_testing();
-  auto iter =
-      base::ranges::find_if(menu_items, [name](ExtensionsMenuItemView* item) {
+  auto iter = base::ranges::find_if(
+      menu_items, [name](InstalledExtensionMenuItemView* item) {
         return base::UTF16ToUTF8(item->view_controller()->GetActionName()) ==
                name;
       });
@@ -204,7 +206,7 @@
   InstallExtensionAndLayout(kExtensionName);
 
   {
-    base::flat_set<ExtensionsMenuItemView*> menu_items =
+    base::flat_set<InstalledExtensionMenuItemView*> menu_items =
         extensions_menu()->extensions_menu_items_for_testing();
     ASSERT_EQ(1u, menu_items.size());
     EXPECT_EQ(kExtensionName,
@@ -224,7 +226,7 @@
   constexpr char kExtensionCName[] = "C Extension";
   InstallExtensionAndLayout(kExtensionCName);
 
-  std::vector<ExtensionsMenuItemView*> menu_items =
+  std::vector<InstalledExtensionMenuItemView*> menu_items =
       ExtensionsMenuView::GetSortedItemsForSectionForTesting(
           extensions::SitePermissionsHelper::SiteInteraction::kNone);
   ASSERT_EQ(4u, menu_items.size());
@@ -246,7 +248,7 @@
   constexpr char kName[] = "Test Name";
   InstallExtensionAndLayout(kName);
 
-  ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+  InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
   ASSERT_TRUE(menu_item);
   ToolbarActionViewController* controller = menu_item->view_controller();
   EXPECT_FALSE(extensions_container()->IsActionVisibleOnToolbar(controller));
@@ -273,7 +275,7 @@
       CreateBrowser(browser()->profile(), browser()->type(),
                     /* hosted_app */ false, /* browser_window */ nullptr));
 
-  ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+  InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
   ASSERT_TRUE(menu_item);
   ClickPinButton(menu_item);
 
@@ -295,7 +297,7 @@
   const extensions::ExtensionId id = InstallExtensionAndLayout(kName)->id();
 
   {
-    ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+    InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
     ASSERT_TRUE(menu_item);
     ClickPinButton(menu_item);
   }
@@ -359,7 +361,7 @@
   ASSERT_EQ(1u, extensions_menu()->extensions_menu_items_for_testing().size());
 
   {
-    ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+    InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
     ClickPinButton(menu_item);
     EXPECT_TRUE(extensions_container()->IsActionVisibleOnToolbar(
         menu_item->view_controller()));
@@ -392,7 +394,7 @@
   scoped_refptr<const extensions::Extension> extension =
       loader.LoadExtension(extension_directory.UnpackedPath());
   LayoutMenuIfNecessary();
-  ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+  InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
   ASSERT_TRUE(menu_item);
   ClickPinButton(menu_item);
 
@@ -422,7 +424,7 @@
 TEST_F(ExtensionsMenuViewUnitTest, PinButtonUserActionWithAccessibility) {
   base::UserActionTester user_action_tester;
   InstallExtensionAndLayout("Test Extension");
-  ExtensionsMenuItemView* menu_item = GetOnlyMenuItem();
+  InstalledExtensionMenuItemView* menu_item = GetOnlyMenuItem();
   ASSERT_NE(nullptr, menu_item);
   views::test::AXEventCounter counter(views::AXEventManager::Get());
   constexpr char kPinButtonUserAction[] = "Extensions.Toolbar.PinButtonPressed";
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
index b8d0542..fac373c3 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.cc
@@ -11,6 +11,7 @@
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/i18n/case_conversion.h"
+#include "base/notreached.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/chrome_pages.h"
@@ -83,50 +84,100 @@
                              std::move(tab_container));
 }
 
-// A helper method to convert to an ExtensionsMenuItemView. This cannot be used
-// to *determine* if a view is an ExtensionsMenuItemView (it should only be used
-// when the view is known to be one). It is only used as an extra measure to
-// prevent bad static casts.
-ExtensionsMenuItemView* GetAsMenuItemView(views::View* view) {
-  DCHECK(views::IsViewClass<ExtensionsMenuItemView>(view));
-  return static_cast<ExtensionsMenuItemView*>(view);
+// Converts a view to a InstalledExtensionsMenuItemView. This cannot
+// be used to *determine* if a view is an InstalledExtensionMenuItemView (it
+// should only be used when the view is known to be one). It is only used as an
+// extra measure to prevent bad static casts.
+InstalledExtensionMenuItemView* GetAsInstalledExtensionMenuItem(
+    views::View* view) {
+  DCHECK(views::IsViewClass<InstalledExtensionMenuItemView>(view));
+  return views::AsViewClass<InstalledExtensionMenuItemView>(view);
 }
 
-// Returns the menu item view of `action_id` if it is a children of
-// `parent_view`.
-ExtensionsMenuItemView* GetMenuItemView(
+// Converts a view to a SiteAccessMenuItemView. This cannot
+// be used to *determine* if a view is an SiteAccessMenuItemView (it
+// should only be used when the view is known to be one). It is only used as an
+// extra measure to prevent bad static casts.
+SiteAccessMenuItemView* GetAsSiteAccessMenuItem(views::View* view) {
+  DCHECK(views::IsViewClass<SiteAccessMenuItemView>(view));
+  return views::AsViewClass<SiteAccessMenuItemView>(view);
+}
+
+// Returns the InstalledExtensionsMenuItemView corresponding to `action_id` if
+// it is a children of `parent_view`. The children of the parent view must be
+// InstalledExtensionsMenuItemView, otherwise it will DCHECK.
+InstalledExtensionMenuItemView* GetInstalledExtensionMenuItem(
     views::View* parent_view,
     const ToolbarActionsModel::ActionId& action_id) {
   for (auto* view : parent_view->children()) {
-    auto* item_view = GetAsMenuItemView(view);
+    auto* item_view = GetAsInstalledExtensionMenuItem(view);
     if (item_view->view_controller()->GetId() == action_id)
       return item_view;
   }
   return nullptr;
 }
 
+// Returns the SiteAccessMenuItemView corresponding to `action_id` if it is a
+// children of `parent_view`. The children of the parent view must be
+// SiteAccessMenuItemView, otherwise it will DCHECK.
+SiteAccessMenuItemView* GetSiteAccessMenuItem(
+    views::View* parent_view,
+    const ToolbarActionsModel::ActionId& action_id) {
+  for (auto* view : parent_view->children()) {
+    auto* item_view = GetAsSiteAccessMenuItem(view);
+    if (item_view->view_controller()->GetId() == action_id)
+      return item_view;
+  }
+  return nullptr;
+}
+
+// Returns the view controller of `view`. The view must be
+// InstalledExtensionMenuItemView or SiteAccessMenuItemView, since both have the
+// same controller, otherwise it will return a nullptr.
+ToolbarActionViewController* GetMenuItemViewController(views::View* view) {
+  if (views::IsViewClass<InstalledExtensionMenuItemView>(view))
+    return GetAsInstalledExtensionMenuItem(view)->view_controller();
+  else if (views::IsViewClass<SiteAccessMenuItemView>(view))
+    return GetAsSiteAccessMenuItem(view)->view_controller();
+  NOTREACHED();
+  return nullptr;
+}
+
 // Returns the current index or insert position of `extension_name` in
 // `parent_view`, based on alphabetical order.
-int FindIndex(const std::u16string extension_name, views::View* parent_view) {
+int FindIndex(views::View* parent_view, const std::u16string extension_name) {
   const auto& children = parent_view->children();
-  return std::find_if(children.begin(), children.end(),
-                      [extension_name](views::View* v) {
-                        return base::i18n::ToLower(extension_name) <=
-                               base::i18n::ToLower(GetAsMenuItemView(v)
-                                                       ->view_controller()
-                                                       ->GetActionName());
-                      }) -
+  return std::find_if(
+             children.begin(), children.end(),
+             [extension_name](views::View* v) {
+               return base::i18n::ToLower(extension_name) <=
+                      base::i18n::ToLower(
+                          GetMenuItemViewController(v)->GetActionName());
+             }) -
          children.begin();
 }
 
-// Updates the `item_view` state and its position under `parent_view`.
-void UpdateMenuItemView(ExtensionsMenuItemView* item_view,
-                        views::View* parent_view) {
-  item_view->Update();
+// Updates the `installed_extension_view` state and its position under
+// `parent_view`.
+void UpdateInstalledExtensionMenuItem(
+    views::View* parent_view,
+    InstalledExtensionMenuItemView* installed_extension_view) {
+  installed_extension_view->Update();
 
   int new_index =
-      FindIndex(item_view->view_controller()->GetActionName(), parent_view);
-  parent_view->ReorderChildView(item_view, new_index);
+      FindIndex(parent_view,
+                installed_extension_view->view_controller()->GetActionName());
+  parent_view->ReorderChildView(installed_extension_view, new_index);
+}
+
+// Updates the `site_access_view` state and its position under `parent_view`.
+void UpdateSiteAccessMenuItem(views::View* parent_view,
+                              SiteAccessMenuItemView* site_access_view) {
+  site_access_view->Update();
+
+  int new_index = FindIndex(
+      parent_view, site_access_view->view_controller()->GetActionName());
+  parent_view->ReorderChildView(site_access_view, new_index);
 }
 
 }  // namespace
@@ -224,32 +275,32 @@
   return g_extensions_dialog;
 }
 
-std::vector<ExtensionsMenuItemView*>
+std::vector<InstalledExtensionMenuItemView*>
 ExtensionsTabbedMenuView::GetInstalledItemsForTesting() const {
-  std::vector<ExtensionsMenuItemView*> menu_item_views;
+  std::vector<InstalledExtensionMenuItemView*> menu_item_views;
   if (IsShowing()) {
     for (views::View* view : installed_items_->children())
-      menu_item_views.push_back(GetAsMenuItemView(view));
+      menu_item_views.push_back(GetAsInstalledExtensionMenuItem(view));
   }
   return menu_item_views;
 }
 
-std::vector<ExtensionsMenuItemView*>
+std::vector<SiteAccessMenuItemView*>
 ExtensionsTabbedMenuView::GetHasAccessItemsForTesting() const {
-  std::vector<ExtensionsMenuItemView*> menu_item_views;
+  std::vector<SiteAccessMenuItemView*> menu_item_views;
   if (IsShowing()) {
     for (views::View* view : has_access_.items->children())
-      menu_item_views.push_back(GetAsMenuItemView(view));
+      menu_item_views.push_back(GetAsSiteAccessMenuItem(view));
   }
   return menu_item_views;
 }
 
-std::vector<ExtensionsMenuItemView*>
+std::vector<SiteAccessMenuItemView*>
 ExtensionsTabbedMenuView::GetRequestsAccessItemsForTesting() const {
-  std::vector<ExtensionsMenuItemView*> menu_item_views;
+  std::vector<SiteAccessMenuItemView*> menu_item_views;
   if (IsShowing()) {
     for (views::View* view : requests_access_.items->children())
-      menu_item_views.push_back(GetAsMenuItemView(view));
+      menu_item_views.push_back(GetAsSiteAccessMenuItem(view));
   }
   return menu_item_views;
 }
@@ -291,7 +342,7 @@
 void ExtensionsTabbedMenuView::OnToolbarActionAdded(
     const ToolbarActionsModel::ActionId& action_id) {
   auto extension_name = toolbar_model_->GetExtensionName(action_id);
-  auto index = FindIndex(extension_name, installed_items_);
+  auto index = FindIndex(installed_items_, extension_name);
   CreateAndInsertInstalledExtension(action_id, index);
 
   MaybeCreateAndInsertSiteAccessItem(action_id);
@@ -302,16 +353,17 @@
 
 void ExtensionsTabbedMenuView::OnToolbarActionRemoved(
     const ToolbarActionsModel::ActionId& action_id) {
-  auto remove_item = [](views::View* parent_view,
-                        const ToolbarActionsModel::ActionId& action_id) {
-    auto* item_view = GetMenuItemView(parent_view, action_id);
+  auto remove_item = [](views::View* parent_view, views::View* item_view) {
     if (item_view)
       parent_view->RemoveChildViewT(item_view);
   };
 
-  remove_item(installed_items_, action_id);
-  remove_item(requests_access_.items, action_id);
-  remove_item(has_access_.items, action_id);
+  remove_item(installed_items_,
+              GetInstalledExtensionMenuItem(installed_items_, action_id));
+  remove_item(requests_access_.items,
+              GetSiteAccessMenuItem(requests_access_.items, action_id));
+  remove_item(has_access_.items,
+              GetSiteAccessMenuItem(has_access_.items, action_id));
 
   UpdateSiteAccessSectionsVisibility();
 
@@ -320,16 +372,25 @@
 
 void ExtensionsTabbedMenuView::OnToolbarActionUpdated(
     const ToolbarActionsModel::ActionId& action_id) {
-  auto update_item = [](views::View* parent_view,
-                        const ToolbarActionsModel::ActionId& action_id) {
-    auto* item_view = GetMenuItemView(parent_view, action_id);
-    if (item_view)
-      UpdateMenuItemView(item_view, parent_view);
-  };
+  auto update_installed_extension_item =
+      [](views::View* parent_view,
+         const ToolbarActionsModel::ActionId& action_id) {
+        auto* item_view = GetInstalledExtensionMenuItem(parent_view, action_id);
+        if (item_view)
+          UpdateInstalledExtensionMenuItem(parent_view, item_view);
+      };
 
-  update_item(installed_items_, action_id);
-  update_item(requests_access_.items, action_id);
-  update_item(has_access_.items, action_id);
+  auto update_site_access_item =
+      [](views::View* parent_view,
+         const ToolbarActionsModel::ActionId& action_id) {
+        auto* item_view = GetSiteAccessMenuItem(parent_view, action_id);
+        if (item_view)
+          UpdateSiteAccessMenuItem(parent_view, item_view);
+      };
+
+  update_installed_extension_item(installed_items_, action_id);
+  update_site_access_item(requests_access_.items, action_id);
+  update_site_access_item(has_access_.items, action_id);
 
   MoveItemsBetweenSectionsIfNecessary();
 
@@ -347,7 +408,7 @@
 
 void ExtensionsTabbedMenuView::OnToolbarPinnedActionsChanged() {
   for (views::View* view : installed_items_->children())
-    GetAsMenuItemView(view)->UpdatePinButton();
+    GetAsInstalledExtensionMenuItem(view)->UpdatePinButton();
 }
 
 void ExtensionsTabbedMenuView::Populate() {
@@ -393,8 +454,8 @@
   has_access_.items->RemoveAllChildViews();
 
   for (views::View* view : installed_items_->children()) {
-    auto* item_view = GetAsMenuItemView(view);
-    UpdateMenuItemView(item_view, installed_items_);
+    auto* item_view = GetAsInstalledExtensionMenuItem(view);
+    UpdateInstalledExtensionMenuItem(installed_items_, item_view);
     MaybeCreateAndInsertSiteAccessItem(item_view->view_controller()->GetId());
   }
 
@@ -537,9 +598,8 @@
   std::unique_ptr<ExtensionActionViewController> controller =
       ExtensionActionViewController::Create(id, browser_,
                                             extensions_container_);
-  auto item = std::make_unique<ExtensionsMenuItemView>(
-      ExtensionsMenuItemView::MenuItemType::kExtensions, browser_,
-      std::move(controller), allow_pinning_);
+  auto item = std::make_unique<InstalledExtensionMenuItemView>(
+      browser_, std::move(controller), allow_pinning_);
   installed_items_->AddChildViewAt(std::move(item), index);
 }
 
@@ -557,20 +617,19 @@
   if (!section)
     return;
 
-  auto item = std::make_unique<ExtensionsMenuItemView>(
-      ExtensionsMenuItemView::MenuItemType::kSiteAccess, browser_,
-      std::move(controller), allow_pinning_);
+  auto item = std::make_unique<SiteAccessMenuItemView>(
+      browser_, std::move(controller), allow_pinning_);
 
   InsertSiteAccessItem(std::move(item), section);
 }
 
 void ExtensionsTabbedMenuView::InsertSiteAccessItem(
-    std::unique_ptr<ExtensionsMenuItemView> item,
+    std::unique_ptr<SiteAccessMenuItemView> item,
     SiteAccessSection* section) {
   DCHECK(section);
 
   int index =
-      FindIndex(item->view_controller()->GetActionName(), section->items);
+      FindIndex(section->items, item->view_controller()->GetActionName());
   section->items->AddChildViewAt(std::move(item), index);
 }
 
@@ -582,9 +641,9 @@
       [web_contents, this](SiteAccessSection* section) {
         // Collect the views to move separately, so that we don't change the
         // children of the view during iteration.
-        std::vector<ExtensionsMenuItemView*> items_to_move;
+        std::vector<SiteAccessMenuItemView*> items_to_move;
         for (views::View* view : section->items->children()) {
-          auto* item_view = GetAsMenuItemView(view);
+          auto* item_view = GetAsSiteAccessMenuItem(view);
           auto site_interaction =
               item_view->view_controller()->GetSiteInteraction(web_contents);
           if (site_interaction == section->site_interaction)
@@ -593,7 +652,7 @@
           items_to_move.push_back(item_view);
         }
 
-        for (ExtensionsMenuItemView* item_view : items_to_move) {
+        for (SiteAccessMenuItemView* item_view : items_to_move) {
           auto item_view_to_move = section->items->RemoveChildViewT(item_view);
           auto site_interaction =
               item_view_to_move->view_controller()->GetSiteInteraction(
@@ -652,10 +711,10 @@
     std::vector<std::u16string> item_names;
     for (views::View* view : parent_view->children()) {
       DCHECK(Contains(view));
-      auto* item_view = GetAsMenuItemView(view);
-      DCHECK(base::Contains(action_ids, item_view->view_controller()->GetId()));
+      auto* view_controller = GetMenuItemViewController(view);
+      DCHECK(base::Contains(action_ids, view_controller->GetId()));
       item_names.push_back(
-          base::i18n::ToLower(item_view->view_controller()->GetActionName()));
+          base::i18n::ToLower(view_controller->GetActionName()));
     }
 
     // Verify that all items are properly sorted.
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
index 7bcb27b..696877c 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view.h
@@ -20,7 +20,8 @@
 class TabbedPane;
 }  // namespace views
 
-class ExtensionsMenuItemView;
+class InstalledExtensionMenuItemView;
+class SiteAccessMenuItemView;
 class ExtensionsContainer;
 class SiteSettingsExpandButton;
 
@@ -64,15 +65,16 @@
 
   // Returns the currently-showing extension items in the extensions tab, if any
   // exists.
-  std::vector<ExtensionsMenuItemView*> GetInstalledItemsForTesting() const;
+  std::vector<InstalledExtensionMenuItemView*> GetInstalledItemsForTesting()
+      const;
 
   // Returns the currently-showing `has_access_` extension items in the site
   // access tab, if any exists.
-  std::vector<ExtensionsMenuItemView*> GetHasAccessItemsForTesting() const;
+  std::vector<SiteAccessMenuItemView*> GetHasAccessItemsForTesting() const;
 
   // Returns the currently-showing `requests_access_` extension items in the
   // site access tab, if any exists.
-  std::vector<ExtensionsMenuItemView*> GetRequestsAccessItemsForTesting() const;
+  std::vector<SiteAccessMenuItemView*> GetRequestsAccessItemsForTesting() const;
 
   // Returns the currently-showing `discover_more_button_` in the extensions
   // tab, if any exists.
@@ -150,7 +152,7 @@
       const ToolbarActionsModel::ActionId& id);
 
   // Adds `item` to the items list of `section`.
-  void InsertSiteAccessItem(std::unique_ptr<ExtensionsMenuItemView> item,
+  void InsertSiteAccessItem(std::unique_ptr<SiteAccessMenuItemView> item,
                             SiteAccessSection* section);
 
   // Moves items between site access sections if their site access status
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
index 7eb30496..fe357af5 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_interactive_uitest.cc
@@ -37,31 +37,31 @@
   const ExtensionsTabbedMenuViewInteractiveUITest& operator=(
       const ExtensionsTabbedMenuViewInteractiveUITest&) = delete;
 
-  std::vector<ExtensionsMenuItemView*> installed_items() {
+  std::vector<InstalledExtensionMenuItemView*> installed_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetInstalledItemsForTesting();
   }
 
-  std::vector<ExtensionsMenuItemView*> requests_access_items() {
+  std::vector<SiteAccessMenuItemView*> requests_access_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetRequestsAccessItemsForTesting();
   }
 
-  std::vector<ExtensionsMenuItemView*> has_access_items() {
+  std::vector<SiteAccessMenuItemView*> has_access_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetHasAccessItemsForTesting();
   }
 
   // Asserts there is exactly one installed menu item and then returns it.
-  ExtensionsMenuItemView* GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* GetOnlyInstalledMenuItem();
 
   // Opens the tabbed menu in the installed tab.
   void ShowInstalledTabInMenu();
   // Opens the tabbed menu in the site access tab.
   void ShowSiteAccessTabInMenu();
 
-  void ClickPrimaryButton(ExtensionsMenuItemView* item);
-  void ClickPinButton(ExtensionsMenuItemView* installed_item);
+  void ClickPrimaryButton(InstalledExtensionMenuItemView* item);
+  void ClickPinButton(InstalledExtensionMenuItemView* installed_item);
   void RightClickExtensionInToolbar(ToolbarActionView* extension);
 
   void ShowUi(const std::string& name) override;
@@ -96,9 +96,9 @@
       features::kExtensionsMenuAccessControl);
 }
 
-ExtensionsMenuItemView*
+InstalledExtensionMenuItemView*
 ExtensionsTabbedMenuViewInteractiveUITest::GetOnlyInstalledMenuItem() {
-  std::vector<ExtensionsMenuItemView*> items = installed_items();
+  std::vector<InstalledExtensionMenuItemView*> items = installed_items();
   if (items.size() != 1) {
     ADD_FAILURE() << "Not exactly one item; size is: " << items.size();
     return nullptr;
@@ -132,13 +132,13 @@
 }
 
 void ExtensionsTabbedMenuViewInteractiveUITest::ClickPrimaryButton(
-    ExtensionsMenuItemView* item) {
+    InstalledExtensionMenuItemView* item) {
   ClickButton(item->primary_action_button_for_testing());
   WaitForAnimation();
 }
 
 void ExtensionsTabbedMenuViewInteractiveUITest::ClickPinButton(
-    ExtensionsMenuItemView* installed_item) {
+    InstalledExtensionMenuItemView* installed_item) {
   ClickButton(installed_item->pin_button_for_testing());
   WaitForAnimation();
 }
diff --git a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
index 82d5ada..324144b5 100644
--- a/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_tabbed_menu_view_unittest.cc
@@ -58,12 +58,25 @@
 };
 
 std::vector<std::string> GetNamesFromMenuItems(
-    std::vector<ExtensionsMenuItemView*> item_views) {
+    std::vector<InstalledExtensionMenuItemView*> item_views) {
   std::vector<std::string> names;
   names.resize(item_views.size());
   std::transform(
       item_views.begin(), item_views.end(), names.begin(),
-      [](ExtensionsMenuItemView* item) {
+      [](InstalledExtensionMenuItemView* item) {
+        return base::UTF16ToUTF8(item->primary_action_button_for_testing()
+                                     ->label_text_for_testing());
+      });
+  return names;
+}
+
+std::vector<std::string> GetNamesFromSiteAccessMenuItems(
+    std::vector<SiteAccessMenuItemView*> item_views) {
+  std::vector<std::string> names;
+  names.resize(item_views.size());
+  std::transform(
+      item_views.begin(), item_views.end(), names.begin(),
+      [](SiteAccessMenuItemView* item) {
         return base::UTF16ToUTF8(item->primary_action_button_for_testing()
                                      ->label_text_for_testing());
       });
@@ -98,25 +111,25 @@
   ExtensionsTabbedMenuView* extensions_tabbed_menu() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting();
   }
-  std::vector<ExtensionsMenuItemView*> installed_items() {
+  std::vector<InstalledExtensionMenuItemView*> installed_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetInstalledItemsForTesting();
   }
-  std::vector<ExtensionsMenuItemView*> has_access_items() {
+  std::vector<SiteAccessMenuItemView*> has_access_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetHasAccessItemsForTesting();
   }
-  std::vector<ExtensionsMenuItemView*> requests_access_items() {
+  std::vector<SiteAccessMenuItemView*> requests_access_items() {
     return ExtensionsTabbedMenuView::GetExtensionsTabbedMenuViewForTesting()
         ->GetRequestsAccessItemsForTesting();
   }
 
   // Asserts there is exactly one installed menu item and then returns it.
-  ExtensionsMenuItemView* GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* GetOnlyInstalledMenuItem();
   // Asserts there is exactly one has access menu item and then returns it.
-  ExtensionsMenuItemView* GetOnlyHasAccessMenuItem();
+  SiteAccessMenuItemView* GetOnlyHasAccessMenuItem();
   // Asserts there is exactly one requests access menu item and then returns it.
-  ExtensionsMenuItemView* GetOnlyRequestsAccessMenuItem();
+  SiteAccessMenuItemView* GetOnlyRequestsAccessMenuItem();
 
   // Opens the tabbed menu in the installed tab.
   void ShowInstalledTabInMenu();
@@ -125,10 +138,12 @@
 
   void ClickSiteAccessButton();
   void ClickExtensionsButton();
-  void ClickPrimaryActionButton(ExtensionsMenuItemView* item);
-  void ClickPinButton(ExtensionsMenuItemView* installed_item);
-  void ClickContextMenuButton(ExtensionsMenuItemView* installed_item);
-  void SelectSiteAccessInCombobox(ExtensionsMenuItemView* site_access_item,
+
+  void ClickPrimaryActionButton(InstalledExtensionMenuItemView* item);
+  void ClickPrimaryActionButton(SiteAccessMenuItemView* item);
+  void ClickPinButton(InstalledExtensionMenuItemView* installed_item);
+  void ClickContextMenuButton(InstalledExtensionMenuItemView* installed_item);
+  void SelectSiteAccessInCombobox(SiteAccessMenuItemView* site_access_item,
                                   int index);
 
   void LayoutMenuIfNecessary() {
@@ -155,9 +170,9 @@
   web_contents_tester_ = AddWebContentsAndGetTester();
 }
 
-ExtensionsMenuItemView*
+InstalledExtensionMenuItemView*
 ExtensionsTabbedMenuViewUnitTest::GetOnlyInstalledMenuItem() {
-  std::vector<ExtensionsMenuItemView*> items = installed_items();
+  std::vector<InstalledExtensionMenuItemView*> items = installed_items();
   if (items.size() != 1u) {
     ADD_FAILURE() << "Not exactly one item; size is: " << items.size();
     return nullptr;
@@ -165,9 +180,9 @@
   return *items.begin();
 }
 
-ExtensionsMenuItemView*
+SiteAccessMenuItemView*
 ExtensionsTabbedMenuViewUnitTest::GetOnlyHasAccessMenuItem() {
-  std::vector<ExtensionsMenuItemView*> items = has_access_items();
+  std::vector<SiteAccessMenuItemView*> items = has_access_items();
   if (items.size() != 1u) {
     ADD_FAILURE() << "Not exactly one item; size is: " << items.size();
     return nullptr;
@@ -175,9 +190,9 @@
   return *items.begin();
 }
 
-ExtensionsMenuItemView*
+SiteAccessMenuItemView*
 ExtensionsTabbedMenuViewUnitTest::GetOnlyRequestsAccessMenuItem() {
-  std::vector<ExtensionsMenuItemView*> items = requests_access_items();
+  std::vector<SiteAccessMenuItemView*> items = requests_access_items();
   if (items.size() != 1u) {
     ADD_FAILURE() << "Not exactly one item; size is: " << items.size();
     return nullptr;
@@ -208,24 +223,30 @@
 }
 
 void ExtensionsTabbedMenuViewUnitTest::ClickPrimaryActionButton(
-    ExtensionsMenuItemView* item) {
+    InstalledExtensionMenuItemView* item) {
+  ClickButton(item->primary_action_button_for_testing());
+  WaitForAnimation();
+}
+
+void ExtensionsTabbedMenuViewUnitTest::ClickPrimaryActionButton(
+    SiteAccessMenuItemView* item) {
   ClickButton(item->primary_action_button_for_testing());
   WaitForAnimation();
 }
 
 void ExtensionsTabbedMenuViewUnitTest::ClickPinButton(
-    ExtensionsMenuItemView* installed_item) {
+    InstalledExtensionMenuItemView* installed_item) {
   ClickButton(installed_item->pin_button_for_testing());
   WaitForAnimation();
 }
 
 void ExtensionsTabbedMenuViewUnitTest::ClickContextMenuButton(
-    ExtensionsMenuItemView* installed_item) {
+    InstalledExtensionMenuItemView* installed_item) {
   ClickButton(installed_item->context_menu_button_for_testing());
 }
 
 void ExtensionsTabbedMenuViewUnitTest::SelectSiteAccessInCombobox(
-    ExtensionsMenuItemView* site_access_item,
+    SiteAccessMenuItemView* site_access_item,
     int index) {
   content::WindowedNotificationObserver permissions_observer(
       extensions::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
@@ -338,7 +359,7 @@
 
   ShowInstalledTabInMenu();
 
-  std::vector<ExtensionsMenuItemView*> items = installed_items();
+  std::vector<InstalledExtensionMenuItemView*> items = installed_items();
   ASSERT_EQ(items.size(), 4u);
 
   // Basic std::sort would do A,C,Z,b however we want A,b,C,Z
@@ -354,7 +375,7 @@
 
   ShowInstalledTabInMenu();
 
-  ExtensionsMenuItemView* installed_item = GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   ASSERT_TRUE(installed_item);
   ToolbarActionViewController* controller = installed_item->view_controller();
   EXPECT_FALSE(extensions_container()->IsActionVisibleOnToolbar(controller));
@@ -383,7 +404,7 @@
 
   ShowInstalledTabInMenu();
 
-  std::vector<ExtensionsMenuItemView*> items = installed_items();
+  std::vector<InstalledExtensionMenuItemView*> items = installed_items();
 
   // Verify the order of the extensions is A,B,C.
   {
@@ -446,7 +467,7 @@
       CreateBrowser(browser()->profile(), browser()->type(),
                     /* hosted_app */ false, /* browser_window */ nullptr));
 
-  ExtensionsMenuItemView* installed_item = GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   ASSERT_TRUE(installed_item);
   ClickPinButton(installed_item);
 
@@ -474,7 +495,7 @@
 
   // Verify the order of the extensions is A,C.
   {
-    std::vector<ExtensionsMenuItemView*> items = installed_items();
+    std::vector<InstalledExtensionMenuItemView*> items = installed_items();
     ASSERT_EQ(items.size(), 2u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionC};
     EXPECT_EQ(GetNamesFromMenuItems(items), expected_names);
@@ -488,7 +509,7 @@
   // Extension should be added in the correct place.
   // Verify the new order is A,B,C.
   {
-    std::vector<ExtensionsMenuItemView*> items = installed_items();
+    std::vector<InstalledExtensionMenuItemView*> items = installed_items();
     ASSERT_EQ(items.size(), 3u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionB,
                                             kExtensionC};
@@ -501,7 +522,7 @@
 
   // Verify the new order is A,C.
   {
-    std::vector<ExtensionsMenuItemView*> items = installed_items();
+    std::vector<InstalledExtensionMenuItemView*> items = installed_items();
     ASSERT_EQ(items.size(), 2u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionC};
     EXPECT_EQ(GetNamesFromMenuItems(items), expected_names);
@@ -515,7 +536,7 @@
 
   ShowInstalledTabInMenu();
 
-  ExtensionsMenuItemView* menu_item = GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* menu_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
   ClickPinButton(menu_item);
 
@@ -551,7 +572,7 @@
 
   ShowInstalledTabInMenu();
 
-  ExtensionsMenuItemView* installed_item = GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
 
   ClickPinButton(installed_item);
@@ -589,7 +610,7 @@
 
   ShowInstalledTabInMenu();
 
-  ExtensionsMenuItemView* installed_item = GetOnlyInstalledMenuItem();
+  InstalledExtensionMenuItemView* installed_item = GetOnlyInstalledMenuItem();
   EXPECT_EQ(installed_items().size(), 1u);
 
   ClickPinButton(installed_item);
@@ -815,10 +836,10 @@
   // Note that extensions installed with all urls permissions have access by
   // default.
   {
-    std::vector<ExtensionsMenuItemView*> has_acess_items = has_access_items();
+    std::vector<SiteAccessMenuItemView*> has_acess_items = has_access_items();
     ASSERT_EQ(has_acess_items.size(), 2u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionC};
-    EXPECT_EQ(GetNamesFromMenuItems(has_acess_items), expected_names);
+    EXPECT_EQ(GetNamesFromSiteAccessMenuItems(has_acess_items), expected_names);
   }
 
   // Add a new extension while the menu is open.
@@ -829,11 +850,11 @@
 
   // Verify the new order is A,B,C under the has access section
   {
-    std::vector<ExtensionsMenuItemView*> has_acess_items = has_access_items();
+    std::vector<SiteAccessMenuItemView*> has_acess_items = has_access_items();
     ASSERT_EQ(has_acess_items.size(), 3u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionB,
                                             kExtensionC};
-    EXPECT_EQ(GetNamesFromMenuItems(has_acess_items), expected_names);
+    EXPECT_EQ(GetNamesFromSiteAccessMenuItems(has_acess_items), expected_names);
   }
 
   // Remove a extension while the menu is open
@@ -842,10 +863,10 @@
 
   // Verify the new order is A,C.
   {
-    std::vector<ExtensionsMenuItemView*> has_acess_items = has_access_items();
+    std::vector<SiteAccessMenuItemView*> has_acess_items = has_access_items();
     ASSERT_EQ(has_acess_items.size(), 2u);
     std::vector<std::string> expected_names{kExtensionA, kExtensionC};
-    EXPECT_EQ(GetNamesFromMenuItems(has_acess_items), expected_names);
+    EXPECT_EQ(GetNamesFromSiteAccessMenuItems(has_acess_items), expected_names);
   }
 }
 
@@ -868,8 +889,9 @@
 
   // Verify site access sections are empty.
   {
-    EXPECT_THAT(GetNamesFromMenuItems(has_access_items()), testing::IsEmpty());
-    EXPECT_THAT(GetNamesFromMenuItems(requests_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(has_access_items()),
+                testing::IsEmpty());
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(requests_access_items()),
                 testing::IsEmpty());
   }
 
@@ -881,9 +903,9 @@
   // Verify the extension is in the "has access" section with "on site"
   // access.
   {
-    EXPECT_THAT(GetNamesFromMenuItems(has_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(has_access_items()),
                 testing::ElementsAre(kExtension));
-    EXPECT_THAT(GetNamesFromMenuItems(requests_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(requests_access_items()),
                 testing::IsEmpty());
     EXPECT_THAT(GetOnlyHasAccessMenuItem()
                     ->site_access_combobox_for_testing()
@@ -899,9 +921,9 @@
   // Verify the extension is still in "has access" section with "on site"
   // access.
   {
-    EXPECT_THAT(GetNamesFromMenuItems(has_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(has_access_items()),
                 testing::ElementsAre(kExtension));
-    EXPECT_THAT(GetNamesFromMenuItems(requests_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(requests_access_items()),
                 testing::IsEmpty());
     EXPECT_EQ(GetOnlyHasAccessMenuItem()
                   ->site_access_combobox_for_testing()
@@ -917,8 +939,9 @@
 
   // Verify site access sections are empty.
   {
-    EXPECT_THAT(GetNamesFromMenuItems(has_access_items()), testing::IsEmpty());
-    EXPECT_THAT(GetNamesFromMenuItems(requests_access_items()),
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(has_access_items()),
+                testing::IsEmpty());
+    EXPECT_THAT(GetNamesFromSiteAccessMenuItems(requests_access_items()),
                 testing::IsEmpty());
   }
 }
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
index a01b4166..20abe26 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -800,8 +800,9 @@
                                TopChromeShownState::kFullyHidden);
 }
 
+// Sheriff 2022/02/25; flaky test crbug/1300462
 IN_PROC_BROWSER_TEST_F(TopControlsSlideControllerTest,
-                       TestFocusEditableElements) {
+                       DISABLED_TestFocusEditableElements) {
   ToggleTabletMode();
   ASSERT_TRUE(GetTabletModeEnabled());
   EXPECT_TRUE(top_controls_slide_controller()->IsEnabled());
diff --git a/chrome/browser/ui/views/hover_button_unittest.cc b/chrome/browser/ui/views/hover_button_unittest.cc
index 5ff19af4..0b61067 100644
--- a/chrome/browser/ui/views/hover_button_unittest.cc
+++ b/chrome/browser/ui/views/hover_button_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/test/views/chrome_views_test_base.h"
@@ -100,7 +99,7 @@
 
 // Tests whether the HoverButton has the correct tooltip and accessible name.
 TEST_F(HoverButtonTest, TooltipAndAccessibleName) {
-  for (size_t i = 0; i < base::size(kTitleSubtitlePairs); ++i) {
+  for (size_t i = 0; i < std::size(kTitleSubtitlePairs); ++i) {
     TitleSubtitlePair pair = kTitleSubtitlePairs[i];
     SCOPED_TRACE(testing::Message() << "Index: " << i << ", expected_tooltip="
                                     << (pair.tooltip ? "true" : "false"));
diff --git a/chrome/browser/ui/views/keyboard_access_browsertest.cc b/chrome/browser/ui/views/keyboard_access_browsertest.cc
index 3628db29..e5dcb386 100644
--- a/chrome/browser/ui/views/keyboard_access_browsertest.cc
+++ b/chrome/browser/ui/views/keyboard_access_browsertest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -259,7 +258,7 @@
   if (n_code == HCBT_ACTIVATE || n_code == HCBT_CREATEWND) {
     wchar_t class_name[MAX_PATH] = {0};
     GetClassName(reinterpret_cast<HWND>(w_param), class_name,
-                 base::size(class_name));
+                 std::size(class_name));
     if (base::LowerCaseEqualsASCII(class_name, "#32768")) {
       // Select the New Tab option and then send the enter key to execute it.
       ::PostMessage(reinterpret_cast<HWND>(w_param), WM_CHAR, 'T', 0);
@@ -311,7 +310,7 @@
   if (n_code == HCBT_ACTIVATE || n_code == HCBT_CREATEWND) {
     wchar_t class_name[MAX_PATH] = {0};
     GetClassName(reinterpret_cast<HWND>(w_param), class_name,
-                 base::size(class_name));
+                 std::size(class_name));
     if (base::LowerCaseEqualsASCII(class_name, "#32768")) {
       // Send 'E' for the Reopen closed tab option.
       ::PostMessage(reinterpret_cast<HWND>(w_param), WM_CHAR, 'E', 0);
diff --git a/chrome/browser/ui/views/layout_provider_unittest.cc b/chrome/browser/ui/views/layout_provider_unittest.cc
index 396c95d..1f5585a 100644
--- a/chrome/browser/ui/views/layout_provider_unittest.cc
+++ b/chrome/browser/ui/views/layout_provider_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -349,7 +348,7 @@
                             {CONTEXT_DIALOG_BODY_TEXT_SMALL, 4, 5},
                             {views::style::CONTEXT_BUTTON_MD, 0, 1}};
 
-  for (size_t i = 0; i < base::size(kExpectedIncreases); ++i) {
+  for (size_t i = 0; i < std::size(kExpectedIncreases); ++i) {
     SCOPED_TRACE(testing::Message() << "Testing index: " << i);
     const auto& increase = kExpectedIncreases[i];
     const gfx::FontList& font = views::style::GetFont(increase.context, kStyle);
@@ -384,7 +383,7 @@
       {views::style::CONTEXT_DIALOG_BODY_TEXT, kBodyLineHeight},
       {CONTEXT_DIALOG_BODY_TEXT_SMALL, kBodyLineHeight}};
 
-  for (size_t i = 0; i < base::size(kHarmonyHeights); ++i) {
+  for (size_t i = 0; i < std::size(kHarmonyHeights); ++i) {
     SCOPED_TRACE(testing::Message() << "Testing index: " << i);
     EXPECT_EQ(kHarmonyHeights[i].line_height,
               views::style::GetLineHeight(kHarmonyHeights[i].context, kStyle));
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index f49e84d..f3f4ae26 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/message_formatter.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_number_conversions.h"
@@ -756,7 +755,7 @@
       autofill::EMAIL_ADDRESS};
   const std::u16string preview =
       state()->contact_profiles()[0]->ConstructInferredLabel(
-          kLabelFields, base::size(kLabelFields), base::size(kLabelFields),
+          kLabelFields, std::size(kLabelFields), std::size(kLabelFields),
           state()->GetApplicationLocale());
   if (state()->contact_profiles().size() == 1) {
     return builder.CreateWithButton(preview,
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
index 11de087..ea90fd3a1 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -731,7 +731,7 @@
                                                                           \
   INSTANTIATE_TEST_SUITE_P(                                               \
       , test_case_name,                                                   \
-      ::testing::Range(size_t(0), base::size(actionable_item_list)));     \
+      ::testing::Range(size_t(0), std::size(actionable_item_list)));      \
                                                                           \
   IN_PROC_BROWSER_TEST_P(test_case_name, test_case_name)
 
diff --git a/chrome/browser/ui/views/settings_reset_prompt_dialog_browsertest.cc b/chrome/browser/ui/views/settings_reset_prompt_dialog_browsertest.cc
index 6c0f8a3..8128dcf 100644
--- a/chrome/browser/ui/views/settings_reset_prompt_dialog_browsertest.cc
+++ b/chrome/browser/ui/views/settings_reset_prompt_dialog_browsertest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ui/views/settings_reset_prompt_dialog.h"
+
 #include <algorithm>
 #include <initializer_list>
 #include <map>
@@ -12,7 +14,6 @@
 #include <vector>
 
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -25,7 +26,6 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
-#include "chrome/browser/ui/views/settings_reset_prompt_dialog.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -71,12 +71,12 @@
             profile,
             std::make_unique<NiceMock<MockSettingsResetPromptConfig>>(),
             std::make_unique<NiceMock<MockProfileResetter>>(profile)) {
-    EXPECT_LE(params.startup_pages, base::size(kStartupUrls));
+    EXPECT_LE(params.startup_pages, std::size(kStartupUrls));
 
     // Set up startup URLs to be returned by member functions based on the
     // constructor arguments.
     for (size_t i = 0;
-         i < std::min(base::size(kStartupUrls), params.startup_pages); ++i) {
+         i < std::min(std::size(kStartupUrls), params.startup_pages); ++i) {
       startup_urls_.push_back(GURL(kStartupUrls[i]));
     }
 
diff --git a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
index 4c11e4862..912f84ae4 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc
@@ -319,11 +319,11 @@
       {kMethodSecondaryActivate, &StatusIconLinuxDbus::OnSecondaryActivate},
   };
 
-  // The barrier requires base::size(methods) + 2 calls.  base::size(methods)
+  // The barrier requires std::size(methods) + 2 calls.  std::size(methods)
   // for each method exported, 1 for |properties_| initialization, and 1 for
   // |menu_| initialization.
   barrier_ =
-      SuccessBarrierCallback(base::size(methods) + 2,
+      SuccessBarrierCallback(std::size(methods) + 2,
                              base::BindOnce(&StatusIconLinuxDbus::OnInitialized,
                                             weak_factory_.GetWeakPtr()));
 
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 3f06591b..1faca985 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -16,7 +16,6 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/dcheck_is_on.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
@@ -4191,7 +4190,7 @@
 };
 
 static_assert(
-    base::size(kDragPoints) == base::size(kDeviceScaleFactorExpectations),
+    std::size(kDragPoints) == std::size(kDeviceScaleFactorExpectations),
     "kDragPoints and kDeviceScaleFactorExpectations must have the same "
     "number of elements");
 
@@ -4211,7 +4210,7 @@
               test->GetCursorDeviceScaleFactor());
   }
 
-  if (index < base::size(kDragPoints)) {
+  if (index < std::size(kDragPoints)) {
     ASSERT_TRUE(test->DragInputToNotifyWhenDone(
         kDragPoints[index], base::BindOnce(&CursorDeviceScaleFactorStep, test,
                                            not_attached_tab_strip, index + 1)));
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
index 703ce1f..2a33a6501 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -318,7 +318,7 @@
     delayed_show_timer_.Start(
         FROM_HERE, GetShowDelay(tab->width()),
         base::BindOnce(&TabHoverCardController::ShowHoverCard,
-                       base::Unretained(this), true, tab));
+                       weak_ptr_factory_.GetWeakPtr(), true, tab));
   } else {
     // Just in case, cancel the timer. This shouldn't cancel a delayed capture
     // since delayed capture only happens when the hover card already exists,
@@ -395,6 +395,24 @@
   }
 }
 
+void TabHoverCardController::OnViewVisibilityChanged(
+    views::View* observed_view,
+    views::View* starting_view) {
+  // Only care about target tab becoming invisible.
+  if (observed_view != target_tab_)
+    return;
+  // Visibility comes from `starting_view` or the widget, if no starting view;
+  // see documentation for ViewObserver::OnViewVisibilityChanged().
+  const bool visible = starting_view
+                           ? starting_view->GetVisible()
+                           : (observed_view->GetWidget() &&
+                              observed_view->GetWidget()->IsVisible());
+  // If visibility changed to false, treat it as if the target tab had gone
+  // away.
+  if (!visible)
+    OnViewIsDeleting(observed_view);
+}
+
 size_t TabHoverCardController::GetTabCount() const {
   return tab_count_metrics::TabCount();
 }
@@ -416,21 +434,21 @@
       TabHoverCardBubbleView::kHoverCardSlideDuration);
   slide_progressed_subscription_ = slide_animator_->AddSlideProgressedCallback(
       base::BindRepeating(&TabHoverCardController::OnSlideAnimationProgressed,
-                          base::Unretained(this)));
+                          weak_ptr_factory_.GetWeakPtr()));
   slide_complete_subscription_ = slide_animator_->AddSlideCompleteCallback(
       base::BindRepeating(&TabHoverCardController::OnSlideAnimationComplete,
-                          base::Unretained(this)));
+                          weak_ptr_factory_.GetWeakPtr()));
   fade_animator_ =
       std::make_unique<views::WidgetFadeAnimator>(hover_card_->GetWidget());
   fade_complete_subscription_ = fade_animator_->AddFadeCompleteCallback(
       base::BindRepeating(&TabHoverCardController::OnFadeAnimationEnded,
-                          base::Unretained(this)));
+                          weak_ptr_factory_.GetWeakPtr()));
 
   if (!thumbnail_observer_ && AreHoverCardImagesEnabled()) {
     thumbnail_observer_ = std::make_unique<TabHoverCardThumbnailObserver>();
     thumbnail_subscription_ = thumbnail_observer_->AddCallback(
         base::BindRepeating(&TabHoverCardController::OnPreviewImageAvaialble,
-                            base::Unretained(this)));
+                            weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h
index 886844a..ec88136 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h
@@ -10,6 +10,7 @@
 #include "base/callback_list.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
@@ -68,6 +69,8 @@
 
   // views::ViewObserver:
   void OnViewIsDeleting(views::View* observed_view) override;
+  void OnViewVisibilityChanged(views::View* observed_view,
+                               views::View* starting_view) override;
 
   // TabHoverCardMetrics::Delegate:
   size_t GetTabCount() const override;
@@ -145,6 +148,7 @@
 
   // Ensure that this timer is destroyed before anything else is cleaned up.
   base::OneShotTimer delayed_show_timer_;
+  base::WeakPtrFactory<TabHoverCardController> weak_ptr_factory_{this};
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_HOVER_CARD_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
index 7a68c3b..e4ac866 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
+++ b/chrome/browser/ui/views/try_chrome_dialog_win/try_chrome_dialog.cc
@@ -14,7 +14,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
@@ -773,7 +772,7 @@
   POINT polygon[7];
   properties_->region_creator(window_size, dialog_bounds, arrow_bounds,
                               arrow_border_insets, &polygon[0]);
-  HRGN region = ::CreatePolygonRgn(&polygon[0], base::size(polygon), WINDING);
+  HRGN region = ::CreatePolygonRgn(&polygon[0], std::size(polygon), WINDING);
   ::SetWindowRgn(hwnd, region, FALSE);
 }
 
@@ -992,7 +991,7 @@
 TryChromeDialog::Result TryChromeDialog::Show(
     size_t group,
     ActiveModalDialogListener listener) {
-  if (group >= base::size(kExperiments)) {
+  if (group >= std::size(kExperiments)) {
     // Exit immediately given bogus values; see TryChromeDialogBrowserTest test.
     return NOT_NOW;
   }
@@ -1018,7 +1017,7 @@
     : group_(group),
       delegate_(delegate),
       context_(std::make_unique<Context>()) {
-  DCHECK_LT(group, base::size(kExperiments));
+  DCHECK_LT(group, std::size(kExperiments));
   DCHECK(delegate);
 }
 
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
index e6a7073..342ed001 100644
--- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc
+++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -32,6 +32,7 @@
 namespace {
 
 const char kTabGroupTutorialMetricPrefix[] = "TabGroup";
+constexpr char kTabGroupHeaderElementName[] = "TabGroupHeader";
 
 }  // namespace
 
@@ -186,6 +187,20 @@
         std::string(), HelpBubbleArrow::kTopCenter);
     description.steps.emplace_back(create_tabgroup_step);
 
+    // Getting the new tab group (hidden step).
+    TutorialDescription::Step new_tab_group_step(
+        0, 0, ui::InteractionSequence::StepType::kShown,
+        kTabGroupHeaderElementId, std::string(), HelpBubbleArrow::kNone,
+        ui::CustomElementEventType(), /* must_remain_visible =*/true,
+        /* transition_only_on_event =*/true,
+        base::BindRepeating(
+            [](ui::InteractionSequence* sequence, ui::TrackedElement* element) {
+              sequence->NameElement(
+                  element, base::StringPiece(kTabGroupHeaderElementName));
+              return true;
+            }));
+    description.steps.emplace_back(std::move(new_tab_group_step));
+
     // The menu step.
     TutorialDescription::Step bubble_menu_edit_step(
         0, IDS_TUTORIAL_TAB_GROUP_EDIT_BUBBLE,
@@ -219,8 +234,8 @@
     // Click to collapse the tab group.
     TutorialDescription::Step collapse_step(
         0, IDS_TUTORIAL_TAB_GROUP_COLLAPSE,
-        ui::InteractionSequence::StepType::kShown, kTabGroupHeaderElementId,
-        std::string(), HelpBubbleArrow::kTopCenter);
+        ui::InteractionSequence::StepType::kShown, ui::ElementIdentifier(),
+        kTabGroupHeaderElementName, HelpBubbleArrow::kTopCenter);
     description.steps.emplace_back(std::move(collapse_step));
 
     // Completion of the tutorial.
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
index 2e270f8..aab80ec 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest.cc
@@ -65,10 +65,9 @@
 
 // Automated tests:
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_30SiteA_24_12SiteA_32SiteA_12SiteA_37SiteA_20) {
+    WebAppIntegration_30SiteA_24_12SiteA_32SiteA_12SiteA_37SiteA_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -185,7 +184,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_30SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
+    WebAppIntegration_30SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -296,10 +295,9 @@
   helper_.CheckLaunchIconShown();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_31SiteA_24_12SiteA_32SiteA_12SiteA_34SiteA_24) {
+    WebAppIntegration_31SiteA_24_12SiteA_32SiteA_12SiteA_34SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -401,7 +399,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
+    WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -616,7 +614,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
+    WebAppIntegration_47SiteA_24_12SiteA_28_36SiteA_34SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -657,10 +655,9 @@
   helper_.CheckTabCreated();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_50SiteA_11SiteA_37SiteA_18) {
+    WebAppIntegration_47SiteA_24_12SiteA_50SiteA_11SiteA_37SiteA_18) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -674,9 +671,8 @@
 }
 
 // TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
-IN_PROC_BROWSER_TEST_F(
-    WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_37SiteAFoo_17_20) {
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
+                       WebAppIntegration_47SiteA_24_12SiteA_37SiteAFoo_17_20) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1079,17 +1075,9 @@
   helper_.CheckAppInListWindowed("SiteA");
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Win7.
-#if BUILDFLAG(IS_WIN)
-#define MAYBE_WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA \
-  DISABLED_WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA
-#else
-#define MAYBE_WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA \
-  WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA
-#endif
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    MAYBE_WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA) {
+    WebAppIntegration_48SiteA_11SiteA_31SiteA_12SiteA_24_44SiteA_12SiteA) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1129,10 +1117,8 @@
   helper_.CheckLaunchIconNotShown();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
-IN_PROC_BROWSER_TEST_F(
-    WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_48SiteA_11SiteA_51SiteA_34SiteA_24) {
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
+                       WebAppIntegration_48SiteA_11SiteA_51SiteA_34SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1385,9 +1371,8 @@
   helper_.CheckLaunchIconShown();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
-                       DISABLED_WebAppIntegration_49SiteC_12SiteC_34SiteC_24) {
+                       WebAppIntegration_49SiteC_12SiteC_34SiteC_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1524,7 +1509,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_30SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_30SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1539,7 +1524,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_30SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
+    WebAppIntegration_30SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1553,9 +1538,8 @@
 }
 
 // TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
-IN_PROC_BROWSER_TEST_F(
-    WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_30SiteA_24_12SiteA_35SiteA_24_26) {
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
+                       WebAppIntegration_30SiteA_24_12SiteA_35SiteA_24_26) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1582,10 +1566,9 @@
   helper_.CheckWindowCreated();
 }
 
-// Test is flaky. See https://crbug.com/1280125
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_31SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_31SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1598,17 +1581,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1281083): Flaky on Win7.
-#if BUILDFLAG(IS_WIN)
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25 \
-  DISABLED_WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25
-#else
-#define MAYBE_WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25 \
-  WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25
-#endif
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    MAYBE_WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
+    WebAppIntegration_31SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1634,10 +1609,9 @@
   helper_.CheckWindowDisplayStandalone();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_32SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_47SiteA_24_12SiteA_32SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1650,10 +1624,9 @@
   helper_.CheckWindowCreated();
 }
 
-// Test is flaky. See https://crbug.com/1280125
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_47SiteA_24_12SiteA_48SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1668,7 +1641,7 @@
 
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_47SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
+    WebAppIntegration_47SiteA_24_12SiteA_28_36SiteA_35SiteA_25) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1730,10 +1703,9 @@
   helper_.CheckWindowCreated();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_29SiteA_11SiteA_51SiteA_12SiteA_35SiteA_24) {
+    WebAppIntegration_29SiteA_11SiteA_51SiteA_12SiteA_35SiteA_24) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1890,10 +1862,8 @@
   helper_.CheckAppNavigationIsStartUrl();
 }
 
-// crbug.com/1264574 - Disabled due to flakiness.
-IN_PROC_BROWSER_TEST_F(
-    WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_33SiteA_12SiteA_39SiteB_27_14) {
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
+                       WebAppIntegration_33SiteA_12SiteA_39SiteB_27_14) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1904,10 +1874,8 @@
   helper_.CheckAppNavigationIsStartUrl();
 }
 
-// crbug.com/1264681 - disabled due to flakiness.
-IN_PROC_BROWSER_TEST_F(
-    WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_49SiteA_12SiteA_39SiteB_27_14) {
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTest,
+                       WebAppIntegration_49SiteA_12SiteA_39SiteB_27_14) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
@@ -1934,10 +1902,9 @@
   helper_.CheckLaunchIconNotShown();
 }
 
-// TODO(crbug.com/1279704): Test is consistently failing on Mac and Win7.
 IN_PROC_BROWSER_TEST_F(
     WebAppIntegrationBrowserTest,
-    DISABLED_WebAppIntegration_31SiteA_24_12SiteA_10SiteA_15SiteA_37SiteA_18_19) {
+    WebAppIntegration_31SiteA_24_12SiteA_10SiteA_15SiteA_37SiteA_18_19) {
   // Test contents are generated by script. Please do not modify!
   // See `chrome/test/webapps/README.md` for more info.
   // Sheriffs: Disabling this test is supported.
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc
index 00a8eb7..0169cca 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc
@@ -34,10 +34,10 @@
                        CheckRunOnOsLoginModeOnPolicyAppWorks) {
   helper_.InstallPolicyAppTabbedNoShortcut("SiteA");
   helper_.CheckAppInListTabbed("SiteA");
-  helper_.EnableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeEnabled("SiteA");
-  helper_.DisableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeDisabled("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.DisableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginDisabled("SiteA");
   // Clear out installed app
   helper_.UninstallPolicyApp("SiteA");
 }
@@ -46,10 +46,10 @@
                        CheckRunOnOsLoginModeOnNormalAppWorks) {
   helper_.InstallCreateShortcutWindowed("SiteA");
   helper_.CheckPlatformShortcutAndIcon("SiteA");
-  helper_.EnableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeEnabled("SiteA");
-  helper_.DisableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeDisabled("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.DisableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginDisabled("SiteA");
   // Clear out installed app
   helper_.UninstallFromList("SiteA");
   helper_.CheckPlatformShortcutNotExists("SiteA");
@@ -57,25 +57,52 @@
 
 IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
                        CheckRunOnOsLoginWorksOnPolicyAppAllowed) {
-  helper_.InstallPolicyAppOsLoginModeAllowed("SiteA");
-  helper_.EnableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeEnabled("SiteA");
-  helper_.DisableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeDisabled("SiteA");
+  helper_.InstallPolicyAppWindowedShortcut("SiteA");
+  helper_.ApplyRunOnOsLoginPolicyAllowed("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.DisableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginDisabled("SiteA");
   helper_.UninstallPolicyApp("SiteA");
   helper_.CheckPlatformShortcutNotExists("SiteA");
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
                        CheckRunOnOsLoginWorksOnPolicyAppBlocked) {
-  helper_.InstallPolicyAppOsLoginModeBlocked("SiteA");
-  helper_.EnableRunOnOSLoginMode("SiteA");
-  helper_.CheckRunOnOSLoginModeDisabled("SiteA");
+  helper_.InstallPolicyAppWindowedShortcut("SiteA");
+  helper_.ApplyRunOnOsLoginPolicyBlocked("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginDisabled("SiteA");
   helper_.UninstallPolicyApp("SiteA");
   helper_.CheckPlatformShortcutNotExists("SiteA");
 }
 
 IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
+                       CheckRunOnOsLoginWorksOnPolicyAppRunWindowed) {
+  helper_.InstallPolicyAppWindowedShortcut("SiteA");
+  helper_.ApplyRunOnOsLoginPolicyRunWindowed("SiteA");
+  helper_.DisableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.UninstallPolicyApp("SiteA");
+  helper_.CheckPlatformShortcutNotExists("SiteA");
+}
+
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
+                       CheckRunOnOsLoginWorksOnBlockedAfterUserTurnOn) {
+  helper_.InstallCreateShortcutWindowed("SiteA");
+  helper_.CheckAppInListWindowed("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.ApplyRunOnOsLoginPolicyBlocked("SiteA");
+  helper_.EnableRunOnOSLogin("SiteA");
+  helper_.CheckRunOnOSLoginDisabled("SiteA");
+  helper_.RemoveRunOnOsLoginPolicy("SiteA");
+  helper_.CheckRunOnOSLoginEnabled("SiteA");
+  helper_.UninstallFromList("SiteA");
+  helper_.CheckPlatformShortcutNotExists("SiteA");
+}
+
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
                        CheckLaunchFromShortcut) {
   helper_.InstallCreateShortcutWindowed("SiteA");
   helper_.CheckWindowCreated();
@@ -113,6 +140,15 @@
   helper_.CheckAppNotInList("SiteA");
 }
 
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
+                       CheckAppSettingsAppState) {
+  helper_.InstallCreateShortcutWindowed("SiteA");
+  helper_.CheckAppInListWindowed("SiteA");
+  helper_.CheckAppSettingsAppState("SiteA");
+  helper_.UninstallFromMenu("SiteA");
+  helper_.CheckAppNotInList("SiteA");
+}
+
 // Generated tests:
 
 IN_PROC_BROWSER_TEST_F(
@@ -174,5 +210,64 @@
   helper_.CheckAppNotInList("SiteA");
 }
 
+IN_PROC_BROWSER_TEST_F(
+    WebAppIntegrationBrowserTestMacWinLinux,
+    WebAppIntegration_30SiteA_24_12SiteA_98SiteA_15SiteA_37SiteA_18_19) {
+  // Test contents are generated by script. Please do not modify!
+  // See `chrome/test/webapps/README.md` for more info.
+  // Sheriffs: Disabling this test is supported.
+  helper_.InstallCreateShortcutWindowed("SiteA");
+  helper_.CheckWindowCreated();
+  helper_.CheckAppInListWindowed("SiteA");
+  helper_.UninstallFromAppSettings("SiteA");
+  helper_.CheckAppNotInList("SiteA");
+  helper_.NavigateBrowser("SiteA");
+  helper_.CheckInstallIconShown();
+  helper_.CheckLaunchIconNotShown();
+}
+
+IN_PROC_BROWSER_TEST_F(
+    WebAppIntegrationBrowserTestMacWinLinux,
+    WebAppIntegration_31SiteA_24_12SiteA_98SiteA_15SiteA_37SiteA_18_19) {
+  // Test contents are generated by script. Please do not modify!
+  // See `chrome/test/webapps/README.md` for more info.
+  // Sheriffs: Disabling this test is supported.
+  helper_.InstallOmniboxIcon("SiteA");
+  helper_.CheckWindowCreated();
+  helper_.CheckAppInListWindowed("SiteA");
+  helper_.UninstallFromAppSettings("SiteA");
+  helper_.CheckAppNotInList("SiteA");
+  helper_.NavigateBrowser("SiteA");
+  helper_.CheckInstallIconShown();
+  helper_.CheckLaunchIconNotShown();
+}
+
+IN_PROC_BROWSER_TEST_F(
+    WebAppIntegrationBrowserTestMacWinLinux,
+    WebAppIntegration_47SiteA_24_12SiteA_98SiteA_15SiteA_37SiteA_18_19) {
+  // Test contents are generated by script. Please do not modify!
+  // See `chrome/test/webapps/README.md` for more info.
+  // Sheriffs: Disabling this test is supported.
+  helper_.InstallMenuOption("SiteA");
+  helper_.CheckWindowCreated();
+  helper_.CheckAppInListWindowed("SiteA");
+  helper_.UninstallFromAppSettings("SiteA");
+  helper_.CheckAppNotInList("SiteA");
+  helper_.NavigateBrowser("SiteA");
+  helper_.CheckInstallIconShown();
+  helper_.CheckLaunchIconNotShown();
+}
+
+IN_PROC_BROWSER_TEST_F(WebAppIntegrationBrowserTestMacWinLinux,
+                       WebAppIntegration_30SiteC_12SiteC_98SiteC_15SiteA) {
+  // Test contents are generated by script. Please do not modify!
+  // See `chrome/test/webapps/README.md` for more info.
+  // Sheriffs: Disabling this test is supported.
+  helper_.InstallCreateShortcutWindowed("SiteC");
+  helper_.CheckAppInListWindowed("SiteC");
+  helper_.UninstallFromAppSettings("SiteC");
+  helper_.CheckAppNotInList("SiteA");
+}
+
 }  // namespace
 }  // namespace web_app
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
index e5820a7..d34b9608 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -549,14 +549,14 @@
   AfterStateChangeAction();
 }
 
-void WebAppIntegrationTestDriver::DisableRunOnOSLoginMode(
+void WebAppIntegrationTestDriver::DisableRunOnOSLogin(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
   SetRunOnOsLoginMode(site_mode, apps::mojom::RunOnOsLoginMode::kNotRun);
   AfterStateChangeAction();
 }
 
-void WebAppIntegrationTestDriver::EnableRunOnOSLoginMode(
+void WebAppIntegrationTestDriver::EnableRunOnOSLogin(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
   SetRunOnOsLoginMode(site_mode, apps::mojom::RunOnOsLoginMode::kWindowed);
@@ -657,58 +657,74 @@
 void WebAppIntegrationTestDriver::InstallPolicyAppTabbedNoShortcut(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerTabValue),
-      /*create_shortcut=*/false, apps::mojom::RunOnOsLoginPtr());
+  InstallPolicyAppInternal(site_mode,
+                           base::Value(kDefaultLaunchContainerTabValue),
+                           /*create_shortcut=*/false);
   AfterStateChangeAction();
 }
 
 void WebAppIntegrationTestDriver::InstallPolicyAppTabbedShortcut(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerTabValue),
-      /*create_shortcut=*/true, apps::mojom::RunOnOsLoginPtr());
+  InstallPolicyAppInternal(site_mode,
+                           base::Value(kDefaultLaunchContainerTabValue),
+                           /*create_shortcut=*/true);
   AfterStateChangeAction();
 }
 
 void WebAppIntegrationTestDriver::InstallPolicyAppWindowedNoShortcut(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerWindowValue),
-      /*create_shortcut=*/false, apps::mojom::RunOnOsLoginPtr());
+  InstallPolicyAppInternal(site_mode,
+                           base::Value(kDefaultLaunchContainerWindowValue),
+                           /*create_shortcut=*/false);
   AfterStateChangeAction();
 }
 
 void WebAppIntegrationTestDriver::InstallPolicyAppWindowedShortcut(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerWindowValue),
-      /*create_shortcut=*/true, apps::mojom::RunOnOsLoginPtr());
+  InstallPolicyAppInternal(site_mode,
+                           base::Value(kDefaultLaunchContainerWindowValue),
+                           /*create_shortcut=*/true);
   AfterStateChangeAction();
 }
 
-void WebAppIntegrationTestDriver::InstallPolicyAppOsLoginModeAllowed(
+void WebAppIntegrationTestDriver::ApplyRunOnOsLoginPolicyAllowed(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerTabValue),
-      /*create_shortcut=*/true,
-      apps::mojom::RunOnOsLogin::New(apps::mojom::RunOnOsLoginMode::kNotRun,
-                                     /*is_managed=*/false));
+  ApplyRunOnOsLoginPolicy(site_mode, kAllowed);
   AfterStateChangeAction();
 }
 
-void WebAppIntegrationTestDriver::InstallPolicyAppOsLoginModeBlocked(
+void WebAppIntegrationTestDriver::ApplyRunOnOsLoginPolicyBlocked(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
-  InstallPolicyAppInternal(
-      site_mode, base::Value(kDefaultLaunchContainerTabValue),
-      /*create_shortcut=*/true,
-      apps::mojom::RunOnOsLogin::New(apps::mojom::RunOnOsLoginMode::kNotRun,
-                                     /*is_managed=*/true));
+  ApplyRunOnOsLoginPolicy(site_mode, kBlocked);
+  AfterStateChangeAction();
+}
+
+void WebAppIntegrationTestDriver::ApplyRunOnOsLoginPolicyRunWindowed(
+    const std::string& site_mode) {
+  BeforeStateChangeAction(__FUNCTION__);
+  ApplyRunOnOsLoginPolicy(site_mode, kRunWindowed);
+  AfterStateChangeAction();
+}
+
+void WebAppIntegrationTestDriver::RemoveRunOnOsLoginPolicy(
+    const std::string& site_mode) {
+  BeforeStateChangeAction(__FUNCTION__);
+  base::RunLoop run_loop;
+  web_app::SetRunOnOsLoginOsHooksChangedCallbackForTesting(
+      run_loop.QuitClosure());
+  GURL url = GetAppStartURL(site_mode);
+  {
+    DictionaryPrefUpdate updateDict(profile()->GetPrefs(),
+                                    prefs::kWebAppSettings);
+    base::Value* dict = updateDict.Get();
+    dict->RemoveKey(std::move(url.spec()));
+  }
+  run_loop.Run();
   AfterStateChangeAction();
 }
 
@@ -898,6 +914,34 @@
 #endif
 }
 
+void WebAppIntegrationTestDriver::CheckAppSettingsAppState(
+    const std::string& site_mode) {
+#if !BUILDFLAG(IS_CHROMEOS)
+  BeforeStateCheckAction(__FUNCTION__);
+  absl::optional<AppState> app_state = GetAppBySiteMode(
+      after_state_change_action_state_.get(), profile(), site_mode);
+  ASSERT_TRUE(app_state.has_value())
+      << "No app installed for site: " << site_mode;
+
+  auto app_management_page_handler = CreateAppManagementPageHandler(profile());
+
+  app_management::mojom::AppPtr app;
+  app_management_page_handler.GetApp(
+      app_state->id,
+      base::BindLambdaForTesting([&](app_management::mojom::AppPtr result) {
+        app = std::move(result);
+      }));
+
+  EXPECT_EQ(app->id, app_state->id);
+  EXPECT_EQ(app->title.value(), app_state->name);
+  EXPECT_EQ(app->window_mode, app_state->window_mode);
+  EXPECT_EQ(app->run_on_os_login->login_mode, app_state->run_on_os_login_mode);
+  AfterStateCheckAction();
+#else
+  NOTREACHED() << "Not implemented on Chrome OS.";
+#endif
+}
+
 void WebAppIntegrationTestDriver::NavigateBrowser(
     const std::string& site_mode) {
   BeforeStateChangeAction(__FUNCTION__);
@@ -1148,7 +1192,7 @@
   if (web_contents->GetURL() !=
       GURL("chrome://app-settings/" + app_state->id)) {
     OpenAppSettingsFromChromeApps(site_mode);
-    CheckBrowserNavigationIsAppSettings("SiteA");
+    CheckBrowserNavigationIsAppSettings(site_mode);
   }
 
   web_contents = browser()->tab_strip_model()->GetActiveWebContents();
@@ -1499,7 +1543,7 @@
   AfterStateCheckAction();
 }
 
-void WebAppIntegrationTestDriver::CheckRunOnOSLoginModeEnabled(
+void WebAppIntegrationTestDriver::CheckRunOnOSLoginEnabled(
     const std::string& site_mode) {
   BeforeStateCheckAction(__FUNCTION__);
   absl::optional<AppState> app_state = GetAppBySiteMode(
@@ -1510,7 +1554,7 @@
   AfterStateCheckAction();
 }
 
-void WebAppIntegrationTestDriver::CheckRunOnOSLoginModeDisabled(
+void WebAppIntegrationTestDriver::CheckRunOnOSLoginDisabled(
     const std::string& site_mode) {
   BeforeStateCheckAction(__FUNCTION__);
   absl::optional<AppState> app_state = GetAppBySiteMode(
@@ -1628,7 +1672,8 @@
 
 void WebAppIntegrationTestDriver::BeforeStateChangeAction(
     const char* function) {
-  LOG(INFO) << "BeforeStateChangeAction: " << function;
+  LOG(INFO) << "BeforeStateChangeAction: "
+            << std::string(executing_action_level_, ' ') << function;
   ++executing_action_level_;
   std::unique_ptr<StateSnapshot> current_state = ConstructStateSnapshot();
   if (after_state_change_action_state_) {
@@ -1664,8 +1709,9 @@
 }
 
 void WebAppIntegrationTestDriver::BeforeStateCheckAction(const char* function) {
-  LOG(INFO) << "BeforeStateCheckAction: " << function;
   ++executing_action_level_;
+  LOG(INFO) << "BeforeStateCheckAction: "
+            << std::string(executing_action_level_, ' ') << function;
   DCHECK(after_state_change_action_state_);
 }
 
@@ -1824,8 +1870,7 @@
 void WebAppIntegrationTestDriver::InstallPolicyAppInternal(
     const std::string& site_mode,
     base::Value default_launch_container,
-    const bool create_shortcut,
-    const apps::mojom::RunOnOsLoginPtr os_login_mode) {
+    const bool create_shortcut) {
   GURL url = GetAppStartURL(site_mode);
   WebAppTestInstallWithOsHooksObserver observer(profile());
   observer.BeginListening();
@@ -1838,22 +1883,28 @@
     ListPrefUpdate update(profile()->GetPrefs(),
                           prefs::kWebAppInstallForceList);
     update->Append(item.Clone());
-
-    if (os_login_mode) {
-      base::Value dictItem(base::Value::Type::DICTIONARY);
-      if (os_login_mode->is_managed)
-        dictItem.SetKey(kRunOnOsLogin, base::Value(kBlocked));
-      else
-        dictItem.SetKey(kRunOnOsLogin, base::Value(kAllowed));
-      DictionaryPrefUpdate updateDict(profile()->GetPrefs(),
-                                      prefs::kWebAppSettings);
-      base::Value* dict = updateDict.Get();
-      dict->SetKey(std::move(url.spec()), std::move(dictItem));
-    }
   }
   active_app_id_ = observer.Wait();
 }
 
+void WebAppIntegrationTestDriver::ApplyRunOnOsLoginPolicy(
+    const std::string& site_mode,
+    const char* policy) {
+  base::RunLoop run_loop;
+  web_app::SetRunOnOsLoginOsHooksChangedCallbackForTesting(
+      run_loop.QuitClosure());
+  GURL url = GetAppStartURL(site_mode);
+  {
+    base::Value dictItem(base::Value::Type::DICTIONARY);
+    dictItem.SetKey(kRunOnOsLogin, base::Value(policy));
+    DictionaryPrefUpdate updateDict(profile()->GetPrefs(),
+                                    prefs::kWebAppSettings);
+    base::Value* dict = updateDict.Get();
+    dict->SetKey(std::move(url.spec()), std::move(dictItem));
+  }
+  run_loop.Run();
+}
+
 void WebAppIntegrationTestDriver::UninstallPolicyAppById(const AppId& id) {
   base::RunLoop run_loop;
   WebAppInstallManagerObserverAdapter observer(profile());
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
index 995e9df..196b457 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -148,8 +148,8 @@
   void AcceptAppIdUpdateDialog();
   void CloseCustomToolbar();
   void ClosePwa();
-  void DisableRunOnOSLoginMode(const std::string& site_mode);
-  void EnableRunOnOSLoginMode(const std::string& site_mode);
+  void DisableRunOnOSLogin(const std::string& site_mode);
+  void EnableRunOnOSLogin(const std::string& site_mode);
   void InstallCreateShortcutTabbed(const std::string& site_mode);
   void InstallCreateShortcutWindowed(const std::string& site_mode);
   void InstallMenuOption(const std::string& site_mode);
@@ -160,8 +160,10 @@
   void InstallPolicyAppWindowedNoShortcut(const std::string& site_mode);
   void InstallPolicyAppWindowedShortcut(const std::string& site_mode);
   // These functions install apps which are tabbed and creates shortcuts.
-  void InstallPolicyAppOsLoginModeAllowed(const std::string& site_mode);
-  void InstallPolicyAppOsLoginModeBlocked(const std::string& site_mode);
+  void ApplyRunOnOsLoginPolicyAllowed(const std::string& site_mode);
+  void ApplyRunOnOsLoginPolicyBlocked(const std::string& site_mode);
+  void ApplyRunOnOsLoginPolicyRunWindowed(const std::string& site_mode);
+  void RemoveRunOnOsLoginPolicy(const std::string& site_mode);
   void LaunchFromChromeApps(const std::string& site_mode);
   void LaunchFromLaunchIcon(const std::string& site_mode);
   void LaunchFromMenuOption(const std::string& site_mode);
@@ -195,6 +197,7 @@
   void CheckAppInListTabbed(const std::string& site_mode);
   void CheckAppNavigationIsStartUrl();
   void CheckBrowserNavigationIsAppSettings(const std::string& site_mode);
+  void CheckAppSettingsAppState(const std::string& site_mode);
   void CheckAppNotInList(const std::string& site_mode);
   void CheckAppTitleSiteA(const std::string& title);
   void CheckAppWindowMode(const std::string& site_mode,
@@ -209,8 +212,8 @@
   void CheckCustomToolbar();
   void CheckPlatformShortcutAndIcon(const std::string& site_mode);
   void CheckPlatformShortcutNotExists(const std::string& site_mode);
-  void CheckRunOnOSLoginModeEnabled(const std::string& site_mode);
-  void CheckRunOnOSLoginModeDisabled(const std::string& site_mode);
+  void CheckRunOnOSLoginEnabled(const std::string& site_mode);
+  void CheckRunOnOSLoginDisabled(const std::string& site_mode);
   void CheckUserDisplayModeInternal(DisplayMode display_mode);
   void CheckWindowClosed();
   void CheckWindowCreated();
@@ -249,11 +252,11 @@
   GURL GetURLForSiteMode(const std::string& site_mode);
   void InstallCreateShortcut(bool open_in_window);
 
-  void InstallPolicyAppInternal(
-      const std::string& site_mode,
-      base::Value default_launch_container,
-      const bool create_shortcut,
-      const apps::mojom::RunOnOsLoginPtr os_login_mode);
+  void InstallPolicyAppInternal(const std::string& site_mode,
+                                base::Value default_launch_container,
+                                const bool create_shortcut);
+  void ApplyRunOnOsLoginPolicy(const std::string& site_mode,
+                               const char* policy);
 
   void UninstallPolicyAppById(const AppId& id);
   // This action only works if no navigations to the given app_url occur
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc
index 003bc60..52f29a4 100644
--- a/chrome/browser/ui/webui/about_ui.cc
+++ b/chrome/browser/ui/webui/about_ui.cc
@@ -132,15 +132,15 @@
 // Returns country to region map with EU, EMEA and APAC countries.
 CountryRegionMap CreateCountryRegionMap() {
   CountryRegionMap region_map;
-  for (size_t i = 0; i < base::size(kApacCountries); ++i) {
+  for (size_t i = 0; i < std::size(kApacCountries); ++i) {
     region_map.emplace(kApacCountries[i], kApac);
   }
 
-  for (size_t i = 0; i < base::size(kEmeaCountries); ++i) {
+  for (size_t i = 0; i < std::size(kEmeaCountries); ++i) {
     region_map.emplace(kEmeaCountries[i], kEmea);
   }
 
-  for (size_t i = 0; i < base::size(kEuCountries); ++i) {
+  for (size_t i = 0; i < std::size(kEuCountries); ++i) {
     region_map.emplace(kEuCountries[i], kEu);
   }
   return region_map;
diff --git a/chrome/browser/ui/webui/certificates_handler.cc b/chrome/browser/ui/webui/certificates_handler.cc
index 5b21eee4..17dd716d 100644
--- a/chrome/browser/ui/webui/certificates_handler.cc
+++ b/chrome/browser/ui/webui/certificates_handler.cc
@@ -291,70 +291,70 @@
 }
 
 void CertificatesHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "viewCertificate",
       base::BindRepeating(&CertificatesHandler::HandleViewCertificate,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCaCertificateTrust",
       base::BindRepeating(&CertificatesHandler::HandleGetCATrust,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "editCaCertificateTrust",
       base::BindRepeating(&CertificatesHandler::HandleEditCATrust,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "cancelImportExportCertificate",
       base::BindRepeating(&CertificatesHandler::HandleCancelImportExportProcess,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "exportPersonalCertificate",
       base::BindRepeating(&CertificatesHandler::HandleExportPersonal,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "exportPersonalCertificatePasswordSelected",
       base::BindRepeating(
           &CertificatesHandler::HandleExportPersonalPasswordSelected,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importPersonalCertificate",
       base::BindRepeating(&CertificatesHandler::HandleImportPersonal,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importPersonalCertificatePasswordSelected",
       base::BindRepeating(
           &CertificatesHandler::HandleImportPersonalPasswordSelected,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importCaCertificate",
       base::BindRepeating(&CertificatesHandler::HandleImportCA,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importCaCertificateTrustSelected",
       base::BindRepeating(&CertificatesHandler::HandleImportCATrustSelected,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importServerCertificate",
       base::BindRepeating(&CertificatesHandler::HandleImportServer,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "exportCertificate",
       base::BindRepeating(&CertificatesHandler::HandleExportCertificate,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "deleteCertificate",
       base::BindRepeating(&CertificatesHandler::HandleDeleteCertificate,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "refreshCertificates",
       base::BindRepeating(&CertificatesHandler::HandleRefreshCertificates,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
index 13a3914..6399714 100644
--- a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
@@ -42,7 +42,7 @@
                                         weak_ptr_factory_.GetWeakPtr()));
 }
 
-void CryptohomeWebUIHandler::OnPageLoaded(base::Value::ConstListView args) {
+void CryptohomeWebUIHandler::OnPageLoaded(const base::Value::List& args) {
   UserDataAuthClient* userdataauth_client = UserDataAuthClient::Get();
   CryptohomePkcs11Client* cryptohome_pkcs11_client =
       CryptohomePkcs11Client::Get();
diff --git a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.h b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.h
index 935dbfe0..c63e02c 100644
--- a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.h
+++ b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.h
@@ -37,7 +37,7 @@
 
  private:
   // This method is called from JavaScript.
-  void OnPageLoaded(base::Value::ConstListView args);
+  void OnPageLoaded(const base::Value::List& args);
 
   void GotIsTPMTokenEnabledOnUIThread(bool is_tpm_token_enabled);
 
diff --git a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
index 386518ef..39ddda6 100644
--- a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
@@ -263,36 +263,36 @@
 
   // WebUIMessageHandler override.
   void RegisterMessages() override {
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "pageLoaded",
         base::BindRepeating(&DriveInternalsWebUIHandler::OnPageLoaded,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "periodicUpdate",
         base::BindRepeating(&DriveInternalsWebUIHandler::OnPeriodicUpdate,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "setVerboseLoggingEnabled",
         base::BindRepeating(
             &DriveInternalsWebUIHandler::SetVerboseLoggingEnabled,
             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "enableTracing",
         base::BindRepeating(&DriveInternalsWebUIHandler::SetTracingEnabled,
                             weak_ptr_factory_.GetWeakPtr(), true));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "disableTracing",
         base::BindRepeating(&DriveInternalsWebUIHandler::SetTracingEnabled,
                             weak_ptr_factory_.GetWeakPtr(), false));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "restartDrive",
         base::BindRepeating(&DriveInternalsWebUIHandler::RestartDrive,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "resetDriveFileSystem",
         base::BindRepeating(&DriveInternalsWebUIHandler::ResetDriveFileSystem,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "zipLogs",
         base::BindRepeating(&DriveInternalsWebUIHandler::ZipDriveFsLogs,
                             weak_ptr_factory_.GetWeakPtr()));
@@ -300,31 +300,31 @@
 
   void RegisterDeveloperMessages() {
     CHECK(developer_mode_);
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "setStartupArguments",
         base::BindRepeating(&DriveInternalsWebUIHandler::SetStartupArguments,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "enableNetworking",
         base::BindRepeating(&DriveInternalsWebUIHandler::SetNetworkingEnabled,
                             weak_ptr_factory_.GetWeakPtr(), true));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "disableNetworking",
         base::BindRepeating(&DriveInternalsWebUIHandler::SetNetworkingEnabled,
                             weak_ptr_factory_.GetWeakPtr(), false));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "enableForcePauseSyncing",
         base::BindRepeating(&DriveInternalsWebUIHandler::ForcePauseSyncing,
                             weak_ptr_factory_.GetWeakPtr(), true));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "disableForcePauseSyncing",
         base::BindRepeating(&DriveInternalsWebUIHandler::ForcePauseSyncing,
                             weak_ptr_factory_.GetWeakPtr(), false));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "dumpAccountSettings",
         base::BindRepeating(&DriveInternalsWebUIHandler::DumpAccountSettings,
                             weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "loadAccountSettings",
         base::BindRepeating(&DriveInternalsWebUIHandler::LoadAccountSettings,
                             weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc
index 39b835ae..7bb4d2b 100644
--- a/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc
@@ -120,15 +120,15 @@
 }
 
 void EduAccountLoginHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isNetworkReady",
       base::BindRepeating(&EduAccountLoginHandler::HandleIsNetworkReady,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getParents",
       base::BindRepeating(&EduAccountLoginHandler::HandleGetParents,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "parentSignin",
       base::BindRepeating(&EduAccountLoginHandler::HandleParentSignin,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index e8056ec..3fc5dfe 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -460,75 +460,75 @@
 }
 
 void DeviceEmulatorMessageHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInitialize, base::BindRepeating(&DeviceEmulatorMessageHandler::Init,
                                        base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRequestPowerInfo,
       base::BindRepeating(&DeviceEmulatorMessageHandler::RequestPowerInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdateBatteryPercent,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdateBatteryPercent,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdateBatteryState,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdateBatteryState,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdateTimeToEmpty,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdateTimeToEmpty,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdateTimeToFull,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdateTimeToFull,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdatePowerSources,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdatePowerSources,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdatePowerSourceId,
       base::BindRepeating(&DeviceEmulatorMessageHandler::UpdatePowerSourceId,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRequestAudioNodes,
       base::BindRepeating(
           &DeviceEmulatorMessageHandler::HandleRequestAudioNodes,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInsertAudioNode,
       base::BindRepeating(&DeviceEmulatorMessageHandler::HandleInsertAudioNode,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRemoveAudioNode,
       base::BindRepeating(&DeviceEmulatorMessageHandler::HandleRemoveAudioNode,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kBluetoothDiscoverFunction,
       base::BindRepeating(
           &DeviceEmulatorMessageHandler::HandleRequestBluetoothDiscover,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kBluetoothPairFunction,
       base::BindRepeating(
           &DeviceEmulatorMessageHandler::HandleRequestBluetoothPair,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRequestBluetoothInfo,
       base::BindRepeating(
           &DeviceEmulatorMessageHandler::HandleRequestBluetoothInfo,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRemoveBluetoothDevice,
       base::BindRepeating(
           &DeviceEmulatorMessageHandler::HandleRemoveBluetoothDevice,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kSetHasTouchpad,
       base::BindRepeating(&DeviceEmulatorMessageHandler::HandleSetHasTouchpad,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kSetHasMouse,
       base::BindRepeating(&DeviceEmulatorMessageHandler::HandleSetHasMouse,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/chromeos/image_source.cc b/chrome/browser/ui/webui/chromeos/image_source.cc
index a20c506..6b800c7 100644
--- a/chrome/browser/ui/webui/chromeos/image_source.cc
+++ b/chrome/browser/ui/webui/chromeos/image_source.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/memory/ref_counted_memory.h"
@@ -105,7 +104,7 @@
   if (components.empty())
     return false;
 
-  for (size_t i = 0; i < base::size(kAllowlistedDirectories); i++) {
+  for (size_t i = 0; i < std::size(kAllowlistedDirectories); i++) {
     if (components[0] == kAllowlistedDirectories[i])
       return true;
   }
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_network_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_network_handler.cc
index 451bf39..8905027 100644
--- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_network_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_network_handler.cc
@@ -58,21 +58,21 @@
 NetworkConfigMessageHandler::~NetworkConfigMessageHandler() = default;
 
 void NetworkConfigMessageHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInitialize, base::BindRepeating(&NetworkConfigMessageHandler::Initialize,
                                        weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kAddNetwork, base::BindRepeating(&NetworkConfigMessageHandler::AddNetwork,
                                        weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kShowNetworkDetails,
       base::BindRepeating(&NetworkConfigMessageHandler::ShowNetworkDetails,
                           weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kShowNetworkConfig,
       base::BindRepeating(&NetworkConfigMessageHandler::ShowNetworkConfig,
                           weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kGetHostname,
       base::BindRepeating(&NetworkConfigMessageHandler::GetHostname,
                           weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
index a5a45c17..df30d05 100644
--- a/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/in_session_password_change/lock_screen_reauth_handler.cc
@@ -333,21 +333,21 @@
 }
 
 void LockScreenReauthHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initialize",
       base::BindRepeating(&LockScreenReauthHandler::HandleInitialize,
                           weak_factory_.GetWeakPtr()));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "authenticatorLoaded",
       base::BindRepeating(&LockScreenReauthHandler::HandleAuthenticatorLoaded,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "completeAuthentication",
       base::BindRepeating(
           &LockScreenReauthHandler::HandleCompleteAuthentication,
           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateUserPassword",
       base::BindRepeating(&LockScreenReauthHandler::HandleUpdateUserPassword,
                           weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
index 3d24f700..b88452a1 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_userlist_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "ash/components/proximity_auth/screenlock_bridge.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/ash/login/screens/user_selection_screen.h"
@@ -64,7 +63,7 @@
         this, TestingBrowserProcess::GetGlobal()->local_state());
     fake_user_manager_->set_multi_profile_user_controller(controller_.get());
 
-    for (size_t i = 0; i < base::size(kUsersPublic); ++i)
+    for (size_t i = 0; i < std::size(kUsersPublic); ++i)
       fake_user_manager_->AddPublicAccountUser(
           AccountId::FromUserEmail(kUsersPublic[i]));
 
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc
index 2cf902b..2f5895a 100644
--- a/chrome/browser/ui/webui/chromeos/network_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -169,7 +169,7 @@
   ~NetworkDiagnosticsMessageHandler() override = default;
 
   void RegisterMessages() override {
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "OpenFeedbackDialog",
         base::BindRepeating(
             &NetworkDiagnosticsMessageHandler::OpenFeedbackDialog,
@@ -201,59 +201,59 @@
 
   // WebUIMessageHandler implementation.
   void RegisterMessages() override {
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kAddNetwork,
         base::BindRepeating(&NetworkConfigMessageHandler::AddNetwork,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kGetNetworkProperties,
         base::BindRepeating(
             &NetworkConfigMessageHandler::GetShillNetworkProperties,
             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kGetDeviceProperties,
         base::BindRepeating(
             &NetworkConfigMessageHandler::GetShillDeviceProperties,
             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kGetEthernetEAP,
         base::BindRepeating(&NetworkConfigMessageHandler::GetShillEthernetEAP,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kOpenCellularActivationUi,
         base::BindRepeating(
             &NetworkConfigMessageHandler::OpenCellularActivationUi,
             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kResetESimCache,
         base::BindRepeating(&NetworkConfigMessageHandler::ResetESimCache,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kDisableESimProfile,
         base::BindRepeating(
             &NetworkConfigMessageHandler::DisableActiveESimProfile,
             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kResetEuicc,
         base::BindRepeating(&NetworkConfigMessageHandler::ResetEuicc,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kShowNetworkDetails,
         base::BindRepeating(&NetworkConfigMessageHandler::ShowNetworkDetails,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kShowNetworkConfig,
         base::BindRepeating(&NetworkConfigMessageHandler::ShowNetworkConfig,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kShowAddNewWifiNetworkDialog,
         base::BindRepeating(&NetworkConfigMessageHandler::ShowAddNewWifi,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kGetHostname,
         base::BindRepeating(&NetworkConfigMessageHandler::GetHostname,
                             base::Unretained(this)));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         kSetHostname,
         base::BindRepeating(&NetworkConfigMessageHandler::SetHostname,
                             base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc
index ab1f9ba..f272bed 100644
--- a/chrome/browser/ui/webui/crashes_ui.cc
+++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -127,19 +127,19 @@
 void CrashesDOMHandler::RegisterMessages() {
   upload_list_->Load(base::BindOnce(&CrashesDOMHandler::OnUploadListAvailable,
                                     base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       crash_reporter::kCrashesUIRequestCrashList,
       base::BindRepeating(&CrashesDOMHandler::HandleRequestCrashes,
                           base::Unretained(this)));
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       crash_reporter::kCrashesUIRequestCrashUpload,
       base::BindRepeating(&CrashesDOMHandler::HandleRequestUploads,
                           base::Unretained(this)));
 #endif
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       crash_reporter::kCrashesUIRequestSingleCrashUpload,
       base::BindRepeating(&CrashesDOMHandler::HandleRequestSingleCrashUpload,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/fileicon_source_unittest.cc b/chrome/browser/ui/webui/fileicon_source_unittest.cc
index ea50c96..10be77b 100644
--- a/chrome/browser/ui/webui/fileicon_source_unittest.cc
+++ b/chrome/browser/ui/webui/fileicon_source_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/webui/fileicon_source.h"
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/strcat.h"
 #include "build/build_config.h"
@@ -119,7 +118,7 @@
   ui::test::ScopedSetSupportedResourceScaleFactors scoped_supported(
       supported_scale_factors);
 
-  for (unsigned i = 0; i < base::size(kBasicExpectations); i++) {
+  for (unsigned i = 0; i < std::size(kBasicExpectations); i++) {
     auto source = std::make_unique<TestFileIconSource>();
     content::URLDataSource::GotDataCallback callback;
     EXPECT_CALL(
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc
index 275a990..df749a3d 100644
--- a/chrome/browser/ui/webui/inspect_ui.cc
+++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -203,72 +203,72 @@
 };
 
 void InspectMessageHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiInitUICommand,
       base::BindRepeating(&InspectMessageHandler::HandleInitUICommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiInspectCommand,
       base::BindRepeating(&InspectMessageHandler::HandleInspectCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiInspectFallbackCommand,
       base::BindRepeating(&InspectMessageHandler::HandleInspectFallbackCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiActivateCommand,
       base::BindRepeating(&InspectMessageHandler::HandleActivateCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiCloseCommand,
       base::BindRepeating(&InspectMessageHandler::HandleCloseCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiPauseCommand,
       base::BindRepeating(&InspectMessageHandler::HandlePauseCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiDiscoverUsbDevicesEnabledCommand,
       base::BindRepeating(&InspectMessageHandler::HandleBooleanPrefChanged,
                           base::Unretained(this),
                           &prefs::kDevToolsDiscoverUsbDevicesEnabled[0]));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiPortForwardingEnabledCommand,
       base::BindRepeating(&InspectMessageHandler::HandleBooleanPrefChanged,
                           base::Unretained(this),
                           &prefs::kDevToolsPortForwardingEnabled[0]));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiPortForwardingConfigCommand,
       base::BindRepeating(
           &InspectMessageHandler::HandlePortForwardingConfigCommand,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiDiscoverTCPTargetsEnabledCommand,
       base::BindRepeating(&InspectMessageHandler::HandleBooleanPrefChanged,
                           base::Unretained(this),
                           &prefs::kDevToolsDiscoverTCPTargetsEnabled[0]));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiLaunchUIDevToolsCommand,
       base::BindRepeating(&InspectMessageHandler::HandleLaunchUIDevToolsCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiTCPDiscoveryConfigCommand,
       base::BindRepeating(
           &InspectMessageHandler::HandleTCPDiscoveryConfigCommand,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiOpenNodeFrontendCommand,
       base::BindRepeating(&InspectMessageHandler::HandleOpenNodeFrontendCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiReloadCommand,
       base::BindRepeating(&InspectMessageHandler::HandleReloadCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiOpenCommand,
       base::BindRepeating(&InspectMessageHandler::HandleOpenCommand,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kInspectUiInspectBrowser,
       base::BindRepeating(&InspectMessageHandler::HandleInspectBrowserCommand,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/local_state/local_state_ui.cc b/chrome/browser/ui/webui/local_state/local_state_ui.cc
index c2d9ca5..a49436d 100644
--- a/chrome/browser/ui/webui/local_state/local_state_ui.cc
+++ b/chrome/browser/ui/webui/local_state/local_state_ui.cc
@@ -59,7 +59,7 @@
 }
 
 void LocalStateUIHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestJson",
       base::BindRepeating(&LocalStateUIHandler::HandleRequestJson,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index ffacd8c..a6f35fed 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -105,46 +105,46 @@
 void NetInternalsMessageHandler::RegisterMessages() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "reloadProxySettings",
       base::BindRepeating(&NetInternalsMessageHandler::OnReloadProxySettings,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearBadProxies",
       base::BindRepeating(&NetInternalsMessageHandler::OnClearBadProxies,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearHostResolverCache",
       base::BindRepeating(&NetInternalsMessageHandler::OnClearHostResolverCache,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "domainSecurityPolicyDelete",
       base::BindRepeating(
           &NetInternalsMessageHandler::OnDomainSecurityPolicyDelete,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "hstsQuery", base::BindRepeating(&NetInternalsMessageHandler::OnHSTSQuery,
                                        base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "hstsAdd", base::BindRepeating(&NetInternalsMessageHandler::OnHSTSAdd,
                                      base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "expectCTQuery",
       base::BindRepeating(&NetInternalsMessageHandler::OnExpectCTQuery,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "expectCTAdd",
       base::BindRepeating(&NetInternalsMessageHandler::OnExpectCTAdd,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "expectCTTestReport",
       base::BindRepeating(&NetInternalsMessageHandler::OnExpectCTTestReport,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "closeIdleSockets",
       base::BindRepeating(&NetInternalsMessageHandler::OnCloseIdleSockets,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "flushSocketPools",
       base::BindRepeating(&NetInternalsMessageHandler::OnFlushSocketPools,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
index c195014..7a5fb6d 100644
--- a/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
+++ b/chrome/browser/ui/webui/ntp_tiles_internals_ui.cc
@@ -119,7 +119,7 @@
 void ChromeNTPTilesInternalsMessageHandlerClient::RegisterMessageCallback(
     const std::string& message,
     base::RepeatingCallback<void(base::Value::ConstListView)> callback) {
-  web_ui()->RegisterMessageCallback(message, std::move(callback));
+  web_ui()->RegisterDeprecatedMessageCallback2(message, std::move(callback));
 }
 
 void ChromeNTPTilesInternalsMessageHandlerClient::
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_posix_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_posix_unittest.cc
index 353c4da..d4e907a 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_posix_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_posix_unittest.cc
@@ -79,7 +79,7 @@
 
     scoped_refptr<base::RefCountedMemory> dummy_data =
         base::MakeRefCounted<base::RefCountedStaticMemory>(
-            &kDummyData, base::size(kDummyData));
+            &kDummyData, std::size(kDummyData));
     StartPrint(u"dummy-job-title", /*settings=*/base::Value(), dummy_data,
                base::DoNothing());
     run_loop_->Run();
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 4bb509a..f3e67b7 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -622,7 +622,7 @@
   return result;
 }
 
-void PrintPreviewHandler::HandleGetPrinters(base::Value::ConstListView args) {
+void PrintPreviewHandler::HandleGetPrinters(const base::Value::List& args) {
   CHECK_GE(args.size(), 2u);
   std::string callback_id = args[0].GetString();
   CHECK(!callback_id.empty());
@@ -652,7 +652,7 @@
 }
 
 void PrintPreviewHandler::HandleGetPrinterCapabilities(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   // Validate that we have a valid callback_id
   if (args.size() < 1 || !args[0].is_string() || args[0].GetString().empty()) {
     RejectJavascriptCallback(base::Value(""), base::Value());
@@ -690,7 +690,7 @@
                      weak_factory_.GetWeakPtr(), callback_id));
 }
 
-void PrintPreviewHandler::HandleGetPreview(base::Value::ConstListView args) {
+void PrintPreviewHandler::HandleGetPreview(const base::Value::List& args) {
   DCHECK_EQ(2U, args.size());
   std::string callback_id;
   std::string json_str;
@@ -740,7 +740,7 @@
     settings.SetKey(kSettingHeaderFooterTitle,
                     base::Value(initiator->GetTitle()));
 
-    url::Replacements<char> url_sanitizer;
+    GURL::Replacements url_sanitizer;
     url_sanitizer.ClearUsername();
     url_sanitizer.ClearPassword();
     const GURL& initiator_url = initiator->GetLastCommittedURL();
@@ -762,7 +762,7 @@
   last_preview_settings_ = std::move(settings);
 }
 
-void PrintPreviewHandler::HandlePrint(base::Value::ConstListView args) {
+void PrintPreviewHandler::HandlePrint(const base::Value::List& args) {
   ReportRegeneratePreviewRequestCountBeforePrint(
       regenerate_preview_request_count_);
   CHECK(args[0].is_string());
@@ -825,20 +825,19 @@
                                      weak_factory_.GetWeakPtr(), callback_id));
 }
 
-void PrintPreviewHandler::HandleHidePreview(
-    base::Value::ConstListView /*args*/) {
+void PrintPreviewHandler::HandleHidePreview(const base::Value::List& /*args*/) {
   print_preview_ui()->OnHidePreviewDialog();
 }
 
 void PrintPreviewHandler::HandleCancelPendingPrintRequest(
-    base::Value::ConstListView /*args*/) {
+    const base::Value::List& /*args*/) {
   WebContents* initiator = GetInitiator();
   if (initiator)
     ClearInitiatorDetails();
   ShowPrintErrorDialog();
 }
 
-void PrintPreviewHandler::HandleSaveAppState(base::Value::ConstListView args) {
+void PrintPreviewHandler::HandleSaveAppState(const base::Value::List& args) {
   std::string data_to_save;
   PrintPreviewStickySettings* sticky_settings =
       PrintPreviewStickySettings::GetInstance();
@@ -849,7 +848,7 @@
   sticky_settings->SaveInPrefs(GetPrefs());
 }
 
-void PrintPreviewHandler::HandleSignin(base::Value::ConstListView /*args*/) {
+void PrintPreviewHandler::HandleSignin(const base::Value::List& /*args*/) {
   Profile* profile = Profile::FromWebUI(web_ui());
   DCHECK(profile);
 
@@ -878,7 +877,7 @@
 
 #if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
 void PrintPreviewHandler::HandleShowSystemDialog(
-    base::Value::ConstListView /*args*/) {
+    const base::Value::List& /*args*/) {
   ReportUserActionHistogram(
       UserActionBuckets::kFallbackToAdvancedSettingsDialog);
 
@@ -899,7 +898,7 @@
 #endif
 
 void PrintPreviewHandler::HandleClosePreviewDialog(
-    base::Value::ConstListView /*args*/) {
+    const base::Value::List& /*args*/) {
   ReportUserActionHistogram(UserActionBuckets::kCancel);
 
   ReportRegeneratePreviewRequestCountBeforeCancel(
@@ -934,7 +933,7 @@
 }
 
 void PrintPreviewHandler::HandleGetInitialSettings(
-    base::Value::ConstListView args) {
+    const base::Value::List& args) {
   CHECK(args[0].is_string());
   std::string callback_id = args[0].GetString();
   CHECK(!callback_id.empty());
@@ -1196,7 +1195,7 @@
 
 void PrintPreviewHandler::OnPrintRequestCancelled() {
   base::Value empty(base::Value::Type::LIST);
-  HandleCancelPendingPrintRequest(empty.GetListDeprecated());
+  HandleCancelPendingPrintRequest(empty.GetList());
 }
 
 void PrintPreviewHandler::ClearInitiatorDetails() {
@@ -1305,8 +1304,7 @@
   GetPdfPrinterHandler()->SetPdfSavedClosureForTesting(std::move(closure));
 }
 
-void PrintPreviewHandler::HandleManagePrinters(
-    base::Value::ConstListView args) {
+void PrintPreviewHandler::HandleManagePrinters(const base::Value::List& args) {
 #if BUILDFLAG(IS_CHROMEOS)
   if (!local_printer_) {
     LOG(ERROR) << "Local printer not available";
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index e57d7db..055305fb 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -168,57 +168,57 @@
 
   // Gets the list of printers. First element of |args| is the Javascript
   // callback, second element of |args| is the printer type to fetch.
-  void HandleGetPrinters(base::Value::ConstListView args);
+  void HandleGetPrinters(const base::Value::List& args);
 
   // Asks the initiator renderer to generate a preview.  First element of |args|
   // is a job settings JSON string.
-  void HandleGetPreview(base::Value::ConstListView args);
+  void HandleGetPreview(const base::Value::List& args);
 
   // Gets the job settings from Web UI and initiate printing. First element of
   // |args| is a job settings JSON string.
-  void HandlePrint(base::Value::ConstListView args);
+  void HandlePrint(const base::Value::List& args);
 
   // Handles the request to hide the preview dialog for printing.
   // |args| is unused.
-  void HandleHidePreview(base::Value::ConstListView args);
+  void HandleHidePreview(const base::Value::List& args);
 
   // Handles the request to cancel the pending print request. |args| is unused.
-  void HandleCancelPendingPrintRequest(base::Value::ConstListView args);
+  void HandleCancelPendingPrintRequest(const base::Value::List& args);
 
   // Handles a request to store data that the web ui wishes to persist.
   // First element of |args| is the data to persist.
-  void HandleSaveAppState(base::Value::ConstListView args);
+  void HandleSaveAppState(const base::Value::List& args);
 
   // Gets the printer capabilities. Fist element of |args| is the Javascript
   // callback, second element is the printer ID of the printer whose
   // capabilities are requested, and the third element is the type of the
   // printer whose capabilities are requested.
-  void HandleGetPrinterCapabilities(base::Value::ConstListView args);
+  void HandleGetPrinterCapabilities(const base::Value::List& args);
 
 #if BUILDFLAG(ENABLE_BASIC_PRINT_DIALOG)
   // Asks the initiator renderer to show the native print system dialog. |args|
   // is unused.
-  void HandleShowSystemDialog(base::Value::ConstListView args);
+  void HandleShowSystemDialog(const base::Value::List& args);
 #endif
 
   // Opens a new tab to allow the user to add an account to sign into cloud
   // print. |args| is unused.
-  void HandleSignin(base::Value::ConstListView args);
+  void HandleSignin(const base::Value::List& args);
 
   // Called when the tab opened by HandleSignIn() is closed.
   void OnSignInTabClosed();
 
   // Gathers UMA stats when the print preview dialog is about to close.
   // |args| is unused.
-  void HandleClosePreviewDialog(base::Value::ConstListView args);
+  void HandleClosePreviewDialog(const base::Value::List& args);
 
   // Asks the browser for several settings that are needed before the first
   // preview is displayed.
-  void HandleGetInitialSettings(base::Value::ConstListView args);
+  void HandleGetInitialSettings(const base::Value::List& args);
 
   // Opens printer settings in the Chrome OS Settings App or OS's printer manger
   // dialog. |args| is unused.
-  void HandleManagePrinters(base::Value::ConstListView args);
+  void HandleManagePrinters(const base::Value::List& args);
 
   void SendInitialSettings(const std::string& callback_id,
                            base::Value policies,
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.cc
index 8f4c323..797df5416 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.cc
@@ -128,34 +128,34 @@
 PrintPreviewHandlerChromeOS::~PrintPreviewHandlerChromeOS() = default;
 
 void PrintPreviewHandlerChromeOS::RegisterMessages() {
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "setupPrinter",
       base::BindRepeating(&PrintPreviewHandlerChromeOS::HandlePrinterSetup,
                           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "getAccessToken",
       base::BindRepeating(&PrintPreviewHandlerChromeOS::HandleGetAccessToken,
                           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "grantExtensionPrinterAccess",
       base::BindRepeating(
           &PrintPreviewHandlerChromeOS::HandleGrantExtensionPrinterAccess,
           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "getEulaUrl",
       base::BindRepeating(&PrintPreviewHandlerChromeOS::HandleGetEulaUrl,
                           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "requestPrinterStatus",
       base::BindRepeating(
           &PrintPreviewHandlerChromeOS::HandleRequestPrinterStatusUpdate,
           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "choosePrintServers",
       base::BindRepeating(
           &PrintPreviewHandlerChromeOS::HandleChoosePrintServers,
           base::Unretained(this)));
-  web_ui()->RegisterDeprecatedMessageCallback(
+  web_ui()->RegisterMessageCallback(
       "getPrintServersConfig",
       base::BindRepeating(
           &PrintPreviewHandlerChromeOS::HandleGetPrintServersConfig,
@@ -180,11 +180,11 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleGrantExtensionPrinterAccess(
-    const base::ListValue* args) {
-  DCHECK(args->GetListDeprecated()[0].is_string() &&
-         args->GetListDeprecated()[1].is_string());
-  std::string callback_id = args->GetListDeprecated()[0].GetString();
-  std::string printer_id = args->GetListDeprecated()[1].GetString();
+    const base::Value::List& args) {
+  DCHECK(args[0].is_string());
+  DCHECK(args[1].is_string());
+  std::string callback_id = args[0].GetString();
+  std::string printer_id = args[1].GetString();
   DCHECK(!callback_id.empty());
   MaybeAllowJavascript();
 
@@ -198,14 +198,13 @@
 // |args| is expected to contain a string with representing the callback id
 // followed by a list of arguments the first of which should be the printer id.
 void PrintPreviewHandlerChromeOS::HandlePrinterSetup(
-    const base::ListValue* args) {
+    const base::Value::List& args) {
   std::string callback_id;
   std::string printer_name;
   MaybeAllowJavascript();
-  if (args->GetListDeprecated()[0].is_string() &&
-      args->GetListDeprecated()[1].is_string()) {
-    callback_id = args->GetListDeprecated()[0].GetString();
-    printer_name = args->GetListDeprecated()[1].GetString();
+  if (args[0].is_string() && args[1].is_string()) {
+    callback_id = args[0].GetString();
+    printer_name = args[1].GetString();
   }
 
   if (callback_id.empty() || printer_name.empty()) {
@@ -222,10 +221,10 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleGetAccessToken(
-    const base::ListValue* args) {
-  DCHECK(args->GetListDeprecated()[0].is_string());
+    const base::Value::List& args) {
+  DCHECK(args[0].is_string());
 
-  std::string callback_id = args->GetListDeprecated()[0].GetString();
+  std::string callback_id = args[0].GetString();
   DCHECK(!callback_id.empty());
   MaybeAllowJavascript();
 
@@ -237,12 +236,12 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleGetEulaUrl(
-    const base::ListValue* args) {
-  CHECK_EQ(2U, args->GetListDeprecated().size());
+    const base::Value::List& args) {
+  CHECK_EQ(2U, args.size());
   MaybeAllowJavascript();
 
-  const std::string& callback_id = args->GetListDeprecated()[0].GetString();
-  const std::string& destination_id = args->GetListDeprecated()[1].GetString();
+  const std::string& callback_id = args[0].GetString();
+  const std::string& destination_id = args[1].GetString();
 
   PrinterHandler* handler = GetPrinterHandler(mojom::PrinterType::kLocal);
   handler->StartGetEulaUrl(
@@ -326,11 +325,11 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleRequestPrinterStatusUpdate(
-    const base::ListValue* args) {
-  CHECK_EQ(2U, args->GetListDeprecated().size());
+    const base::Value::List& args) {
+  CHECK_EQ(2U, args.size());
 
-  const std::string& callback_id = args->GetListDeprecated()[0].GetString();
-  const std::string& printer_id = args->GetListDeprecated()[1].GetString();
+  const std::string& callback_id = args[0].GetString();
+  const std::string& printer_id = args[1].GetString();
 
   MaybeAllowJavascript();
   PrinterHandler* handler = GetPrinterHandler(mojom::PrinterType::kLocal);
@@ -341,12 +340,12 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleChoosePrintServers(
-    const base::ListValue* args) {
-  CHECK_EQ(1U, args->GetListDeprecated().size());
+    const base::Value::List& args) {
+  CHECK_EQ(1U, args.size());
 
-  const base::Value& val = args->GetListDeprecated()[0];
+  const base::Value& val = args[0];
   std::vector<std::string> print_server_ids;
-  for (const auto& id : val.GetListDeprecated()) {
+  for (const auto& id : val.GetList()) {
     print_server_ids.push_back(id.GetString());
   }
   MaybeAllowJavascript();
@@ -359,9 +358,9 @@
 }
 
 void PrintPreviewHandlerChromeOS::HandleGetPrintServersConfig(
-    const base::ListValue* args) {
-  CHECK(args->GetListDeprecated()[0].is_string());
-  std::string callback_id = args->GetListDeprecated()[0].GetString();
+    const base::Value::List& args) {
+  CHECK(args[0].is_string());
+  std::string callback_id = args[0].GetString();
   CHECK(!callback_id.empty());
   MaybeAllowJavascript();
   if (!local_printer_) {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.h b/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.h
index e2159ef..edd4d575 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_chromeos.h
@@ -68,16 +68,16 @@
 
   // Grants an extension access to a provisional printer.  First element of
   // |args| is the provisional printer ID.
-  void HandleGrantExtensionPrinterAccess(const base::ListValue* args);
+  void HandleGrantExtensionPrinterAccess(const base::Value::List& args);
 
   // Performs printer setup. First element of |args| is the printer name.
-  void HandlePrinterSetup(const base::ListValue* args);
+  void HandlePrinterSetup(const base::Value::List& args);
 
   // Generates new token and sends back to UI.
-  void HandleGetAccessToken(const base::ListValue* args);
+  void HandleGetAccessToken(const base::Value::List& args);
 
   // Gets the EULA URL.
-  void HandleGetEulaUrl(const base::ListValue* args);
+  void HandleGetEulaUrl(const base::Value::List& args);
 
   // Send OAuth2 access token.
   void SendAccessToken(const std::string& callback_id,
@@ -100,7 +100,7 @@
                                  const base::DictionaryValue& printer_info);
 
   // Called to initiate a status request for a printer.
-  void HandleRequestPrinterStatusUpdate(const base::ListValue* args);
+  void HandleRequestPrinterStatusUpdate(const base::Value::List& args);
 
   // crosapi::mojom::PrintServerObserver Implementation
   void OnPrintServersChanged(
@@ -109,10 +109,10 @@
 
   // Loads printers corresponding to the print server(s).  First element of
   // |args| is the print server IDs.
-  void HandleChoosePrintServers(const base::ListValue* args);
+  void HandleChoosePrintServers(const base::Value::List& args);
 
   // Gets the list of print servers and fetching mode.
-  void HandleGetPrintServersConfig(const base::ListValue* args);
+  void HandleGetPrintServersConfig(const base::Value::List& args);
 
   // Holds token service to get OAuth2 access tokens.
   std::unique_ptr<AccessTokenService> token_service_;
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 895deb5..716bed9 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
@@ -11,7 +11,6 @@
 
 #include "base/base64.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/number_formatting.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
@@ -177,7 +176,7 @@
 
   // All other PrintPreview.PrintSettings buckets should be empty.
   histograms.ExpectTotalCount("PrintPreview.PrintSettings",
-                              base::size(kPopulatedPrintSettingsBuckets));
+                              std::size(kPopulatedPrintSettingsBuckets));
 
   const UserActionBuckets user_action = GetUserActionForPrinterType(type);
   histograms.ExpectBucketCount("PrintPreview.UserAction", user_action, 1);
@@ -469,7 +468,7 @@
       browser_process->SetApplicationLocale(locale);
       base::test::ScopedRestoreICUDefaultLocale scoped_locale(locale);
       base::ResetFormattersForTesting();
-      handler()->HandleGetInitialSettings(args.GetListDeprecated());
+      handler()->HandleGetInitialSettings(args.GetList());
     }
     // Reset again now that |scoped_locale| has been destroyed.
     browser_process->SetApplicationLocale(original_locale);
@@ -629,7 +628,7 @@
     base::Value args(base::Value::Type::LIST);
     args.Append(callback_id_in);
     args.Append(static_cast<int>(type));
-    handler()->HandleGetPrinters(args.GetListDeprecated());
+    handler()->HandleGetPrinters(args.GetList());
   }
 
   // Validates that the printers-added Web UI event has been fired for
@@ -645,8 +644,7 @@
         static_cast<mojom::PrinterType>(add_data.arg2()->GetInt());
     EXPECT_EQ(expected_type, type);
     ASSERT_TRUE(add_data.arg3());
-    base::Value::ConstListView printer_list =
-        add_data.arg3()->GetListDeprecated();
+    const base::Value::List& printer_list = add_data.arg3()->GetList();
     ASSERT_EQ(printer_list.size(), 1u);
     EXPECT_TRUE(printer_list[0].FindKeyOfType("printer_name",
                                               base::Value::Type::STRING));
@@ -661,7 +659,7 @@
     args.Append(callback_id_in);
     args.Append(printer_name);
     args.Append(static_cast<int>(type));
-    handler()->HandleGetPrinterCapabilities(args.GetListDeprecated());
+    handler()->HandleGetPrinterCapabilities(args.GetList());
   }
 
   // Validates that a printer capabilities promise was resolved/rejected.
@@ -1080,7 +1078,7 @@
   Initialize();
 
   // Check all three printer types that implement
-  for (size_t i = 0; i < base::size(kFetchableTypes); i++) {
+  for (size_t i = 0; i < std::size(kFetchableTypes); i++) {
     mojom::PrinterType type = kFetchableTypes[i];
     std::string callback_id_in =
         "test-callback-id-" + base::NumberToString(i + 1);
@@ -1116,7 +1114,7 @@
   Initialize();
 
   size_t expected_callbacks = 1;
-  for (size_t i = 0; i < base::size(kFetchableTypes); i++) {
+  for (size_t i = 0; i < std::size(kFetchableTypes); i++) {
     mojom::PrinterType type = kFetchableTypes[i];
     std::string callback_id_in =
         "test-callback-id-" + base::NumberToString(i + 1);
@@ -1152,7 +1150,7 @@
 
   // Check all four printer types that implement
   // PrinterHandler::StartGetCapability().
-  for (size_t i = 0; i < base::size(kAllSupportedTypes); i++) {
+  for (size_t i = 0; i < std::size(kAllSupportedTypes); i++) {
     mojom::PrinterType type = kAllSupportedTypes[i];
     std::string callback_id_in =
         "test-callback-id-" + base::NumberToString(i + 1);
@@ -1169,19 +1167,19 @@
 
   // Run through the loop again, this time with a printer that has no
   // capabilities.
-  for (size_t i = 0; i < base::size(kAllSupportedTypes); i++) {
+  for (size_t i = 0; i < std::size(kAllSupportedTypes); i++) {
     mojom::PrinterType type = kAllSupportedTypes[i];
     std::string callback_id_in =
         "test-callback-id-" +
-        base::NumberToString(i + base::size(kAllSupportedTypes) + 1);
+        base::NumberToString(i + std::size(kAllSupportedTypes) + 1);
     handler()->reset_calls();
     SendGetPrinterCapabilities(type, callback_id_in, kEmptyPrinterName);
     EXPECT_TRUE(handler()->CalledOnlyForType(type));
 
     // Start with 1 call from initial settings plus
-    // base::size(kAllSupportedTypes) from first loop, then add 1 more for each
+    // std::size(kAllSupportedTypes) from first loop, then add 1 more for each
     // loop iteration.
-    ASSERT_EQ(1u + base::size(kAllSupportedTypes) + (i + 1),
+    ASSERT_EQ(1u + std::size(kAllSupportedTypes) + (i + 1),
               web_ui()->call_data().size());
 
     ValidatePrinterCapabilities(callback_id_in, /*expect_resolved=*/false);
@@ -1206,7 +1204,7 @@
 
   // Check all four printer types that implement
   // PrinterHandler::StartGetCapability().
-  for (size_t i = 0; i < base::size(kAllSupportedTypes); i++) {
+  for (size_t i = 0; i < std::size(kAllSupportedTypes); i++) {
     mojom::PrinterType type = kAllSupportedTypes[i];
     std::string callback_id_in =
         "test-callback-id-" + base::NumberToString(i + 1);
@@ -1228,7 +1226,7 @@
   Initialize();
 
   // All printer types can print.
-  for (size_t i = 0; i < base::size(kAllTypes); i++) {
+  for (size_t i = 0; i < std::size(kAllTypes); i++) {
     base::HistogramTester histograms;
     handler()->reset_calls();
 
@@ -1239,7 +1237,7 @@
         "test-callback-id-" + base::NumberToString(2 * i + 1);
     base::Value preview_list_args =
         ConstructPreviewArgs(preview_callback_id, preview_ticket);
-    handler()->HandleGetPreview(preview_list_args.GetListDeprecated());
+    handler()->HandleGetPreview(preview_list_args.GetList());
 
     // Send printing request.
     mojom::PrinterType type = kAllTypes[i];
@@ -1251,7 +1249,7 @@
     std::string json;
     base::JSONWriter::Write(print_ticket, &json);
     print_args.Append(json);
-    handler()->HandlePrint(print_args.GetListDeprecated());
+    handler()->HandlePrint(print_args.GetList());
 
     CheckHistograms(histograms, type);
 
@@ -1288,7 +1286,7 @@
   base::Value print_ticket = GetPrintPreviewTicket();
   base::Value list_args =
       ConstructPreviewArgs("test-callback-id-1", print_ticket);
-  handler()->HandleGetPreview(list_args.GetListDeprecated());
+  handler()->HandleGetPreview(list_args.GetList());
   run_loop.Run();
 
   // Verify that the preview was requested from the renderer with the
@@ -1318,7 +1316,7 @@
   const char callback_id_in[] = "test-callback-id-1";
   base::Value print_ticket = GetPrintPreviewTicket();
   base::Value list_args = ConstructPreviewArgs(callback_id_in, print_ticket);
-  handler()->HandleGetPreview(list_args.GetListDeprecated());
+  handler()->HandleGetPreview(list_args.GetList());
   run_loop.Run();
   const base::Value& preview_params = print_render_frame.GetSettings();
 
@@ -1427,7 +1425,7 @@
 
   // Check all four printer types that implement
   // PrinterHandler::StartGetCapability().
-  for (size_t i = 0; i < base::size(kAllSupportedTypes); i++) {
+  for (size_t i = 0; i < std::size(kAllSupportedTypes); i++) {
     mojom::PrinterType type = kAllSupportedTypes[i];
     handler()->reset_calls();
     base::Value args(base::Value::Type::LIST);
@@ -1436,7 +1434,7 @@
     args.Append(callback_id_in);
     args.Append(kDummyPrinterName);
     args.Append(static_cast<int>(type));
-    handler()->HandleGetPrinterCapabilities(args.GetListDeprecated());
+    handler()->HandleGetPrinterCapabilities(args.GetList());
     EXPECT_TRUE(handler()->CalledOnlyForType(type));
 
     // Start with 1 call from initial settings, then add 1 more for each loop
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
index 2730f45..b19a972 100644
--- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
+++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
@@ -23,12 +23,12 @@
 }
 
 void PrivacySandboxDialogHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "dialogActionOccurred",
       base::BindRepeating(
           &PrivacySandboxDialogHandler::HandleDialogActionOccurred,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resizeDialog",
       base::BindRepeating(&PrivacySandboxDialogHandler::HandleResizeDialog,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
index 3f86125..e8790f0 100644
--- a/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
+++ b/chrome/browser/ui/webui/sanitized_image_source_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/webui/sanitized_image_source.h"
 
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/strcat.h"
@@ -185,7 +184,7 @@
 
   // Encode a URL so that it can be used as a param value.
   url::RawCanonOutputT<char> encoded_url;
-  url::EncodeURIComponent(kImageUrl, base::size(kImageUrl), &encoded_url);
+  url::EncodeURIComponent(kImageUrl, std::size(kImageUrl), &encoded_url);
   EXPECT_GT(encoded_url.length(), 0);
   auto encoded_url_str =
       base::StringPiece(encoded_url.data(), encoded_url.length());
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index 75ffa8f..13f38231 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -268,77 +268,77 @@
 }
 
 void AboutHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "aboutPageReady", base::BindRepeating(&AboutHandler::HandlePageReady,
                                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "refreshUpdateStatus",
       base::BindRepeating(&AboutHandler::HandleRefreshUpdateStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openFeedbackDialog",
       base::BindRepeating(&AboutHandler::HandleOpenFeedbackDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openHelpPage", base::BindRepeating(&AboutHandler::HandleOpenHelpPage,
                                           base::Unretained(this)));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openDiagnostics",
       base::BindRepeating(&AboutHandler::HandleOpenDiagnostics,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openFirmwareUpdatesPage",
       base::BindRepeating(&AboutHandler::HandleOpenFirmwareUpdates,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openOsHelpPage", base::BindRepeating(&AboutHandler::HandleOpenOsHelpPage,
                                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setChannel", base::BindRepeating(&AboutHandler::HandleSetChannel,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestUpdate", base::BindRepeating(&AboutHandler::HandleRequestUpdate,
                                            base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestUpdateOverCellular",
       base::BindRepeating(&AboutHandler::HandleRequestUpdateOverCellular,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getVersionInfo", base::BindRepeating(&AboutHandler::HandleGetVersionInfo,
                                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getRegulatoryInfo",
       base::BindRepeating(&AboutHandler::HandleGetRegulatoryInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getChannelInfo", base::BindRepeating(&AboutHandler::HandleGetChannelInfo,
                                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "canChangeChannel",
       base::BindRepeating(&AboutHandler::HandleCanChangeChannel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "refreshTPMFirmwareUpdateStatus",
       base::BindRepeating(&AboutHandler::HandleRefreshTPMFirmwareUpdateStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getEndOfLifeInfo",
       base::BindRepeating(&AboutHandler::HandleGetEndOfLifeInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "launchReleaseNotes",
       base::BindRepeating(&AboutHandler::HandleLaunchReleaseNotes,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "checkInternetConnection",
       base::BindRepeating(&AboutHandler::HandleCheckInternetConnection,
                           base::Unretained(this)));
 #endif
 #if BUILDFLAG(IS_MAC)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "promoteUpdater", base::BindRepeating(&AboutHandler::PromoteUpdater,
                                             base::Unretained(this)));
 #endif
diff --git a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
index c48e3f38..d8ef993 100644
--- a/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
+++ b/chrome/browser/ui/webui/settings/accessibility_main_handler.cc
@@ -26,11 +26,11 @@
 AccessibilityMainHandler::~AccessibilityMainHandler() = default;
 
 void AccessibilityMainHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "a11yPageReady",
       base::BindRepeating(&AccessibilityMainHandler::HandleA11yPageReady,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "confirmA11yImageLabels",
       base::BindRepeating(
           &AccessibilityMainHandler::HandleCheckAccessibilityImageLabels,
diff --git a/chrome/browser/ui/webui/settings/appearance_handler.cc b/chrome/browser/ui/webui/settings/appearance_handler.cc
index 392c06664..c952297 100644
--- a/chrome/browser/ui/webui/settings/appearance_handler.cc
+++ b/chrome/browser/ui/webui/settings/appearance_handler.cc
@@ -25,14 +25,14 @@
 void AppearanceHandler::OnJavascriptDisallowed() {}
 
 void AppearanceHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "useDefaultTheme",
       base::BindRepeating(&AppearanceHandler::HandleUseDefaultTheme,
                           base::Unretained(this)));
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
 #if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS_LACROS)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "useSystemTheme",
       base::BindRepeating(&AppearanceHandler::HandleUseSystemTheme,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits.h b/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits.h
index 24714f7..780affc 100644
--- a/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits.h
+++ b/chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_type_mojom_traits.h
@@ -47,7 +47,7 @@
 };
 
 template <>
-struct CloneTraits<apps::PermissionPtr, false> {
+struct CloneTraits<apps::PermissionPtr> {
   static apps::PermissionPtr Clone(const apps::PermissionPtr& input) {
     return input->Clone();
   }
diff --git a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
index 7ab0886..5ae6944 100644
--- a/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
+++ b/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
@@ -63,30 +63,30 @@
 BrowserLifetimeHandler::~BrowserLifetimeHandler() {}
 
 void BrowserLifetimeHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "restart", base::BindRepeating(&BrowserLifetimeHandler::HandleRestart,
                                      base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "relaunch", base::BindRepeating(&BrowserLifetimeHandler::HandleRelaunch,
                                       base::Unretained(this)));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "signOutAndRestart",
       base::BindRepeating(&BrowserLifetimeHandler::HandleSignOutAndRestart,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "factoryReset",
       base::BindRepeating(&BrowserLifetimeHandler::HandleFactoryReset,
                           base::Unretained(this)));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "shouldShowRelaunchConfirmationDialog",
       base::BindRepeating(
           &BrowserLifetimeHandler::HandleShouldShowRelaunchConfirmationDialog,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getRelaunchConfirmationDialogDescription",
       base::BindRepeating(&BrowserLifetimeHandler::
                               HandleGetRelaunchConfirmationDialogDescription,
diff --git a/chrome/browser/ui/webui/settings/captions_handler.cc b/chrome/browser/ui/webui/settings/captions_handler.cc
index 9794a20f..8449926 100644
--- a/chrome/browser/ui/webui/settings/captions_handler.cc
+++ b/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -41,11 +41,11 @@
 }
 
 void CaptionsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openSystemCaptionsDialog",
       base::BindRepeating(&CaptionsHandler::HandleOpenSystemCaptionsDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "liveCaptionSectionReady",
       base::BindRepeating(&CaptionsHandler::HandleLiveCaptionSectionReady,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
index 3dc8515..73e85aac 100644
--- a/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
+++ b/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
@@ -110,37 +110,37 @@
 }
 
 void ChromeCleanupHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "registerChromeCleanerObserver",
       base::BindRepeating(
           &ChromeCleanupHandler::HandleRegisterChromeCleanerObserver,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startScanning",
       base::BindRepeating(&ChromeCleanupHandler::HandleStartScanning,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "restartComputer",
       base::BindRepeating(&ChromeCleanupHandler::HandleRestartComputer,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startCleanup",
       base::BindRepeating(&ChromeCleanupHandler::HandleStartCleanup,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifyShowDetails",
       base::BindRepeating(&ChromeCleanupHandler::HandleNotifyShowDetails,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifyChromeCleanupLearnMoreClicked",
       base::BindRepeating(
           &ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getMoreItemsPluralString",
       base::BindRepeating(&ChromeCleanupHandler::HandleGetMoreItemsPluralString,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getItemsToRemovePluralString",
       base::BindRepeating(
           &ChromeCleanupHandler::HandleGetItemsToRemovePluralString,
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
index 0d0642e..ef88c3f 100644
--- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -54,32 +54,32 @@
 }
 
 void AccessibilityHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showChromeVoxSettings",
       base::BindRepeating(&AccessibilityHandler::HandleShowChromeVoxSettings,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showSelectToSpeakSettings",
       base::BindRepeating(
           &AccessibilityHandler::HandleShowSelectToSpeakSettings,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setStartupSoundEnabled",
       base::BindRepeating(&AccessibilityHandler::HandleSetStartupSoundEnabled,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "recordSelectedShowShelfNavigationButtonValue",
       base::BindRepeating(
           &AccessibilityHandler::
               HandleRecordSelectedShowShelfNavigationButtonsValue,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "manageA11yPageReady",
       base::BindRepeating(&AccessibilityHandler::HandleManageA11yPageReady,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showChromeVoxTutorial",
       base::BindRepeating(&AccessibilityHandler::HandleShowChromeVoxTutorial,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
index 9bde33c..7238f52 100644
--- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -207,32 +207,32 @@
   if (!profile_)
     profile_ = Profile::FromWebUI(web_ui());
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAccounts",
       base::BindRepeating(&AccountManagerUIHandler::HandleGetAccounts,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addAccount",
       base::BindRepeating(&AccountManagerUIHandler::HandleAddAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "reauthenticateAccount",
       base::BindRepeating(&AccountManagerUIHandler::HandleReauthenticateAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "migrateAccount",
       base::BindRepeating(&AccountManagerUIHandler::HandleMigrateAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeAccount",
       base::BindRepeating(&AccountManagerUIHandler::HandleRemoveAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showWelcomeDialogIfRequired",
       base::BindRepeating(
           &AccountManagerUIHandler::HandleShowWelcomeDialogIfRequired,
           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "changeArcAvailability",
       base::BindRepeating(&AccountManagerUIHandler::HandleChangeArcAvailability,
                           weak_factory_.GetWeakPtr()));
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 848bb5702..db3066d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
@@ -135,22 +135,22 @@
 AmbientModeHandler::~AmbientModeHandler() = default;
 
 void AmbientModeHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestSettings",
       base::BindRepeating(&AmbientModeHandler::HandleRequestSettings,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestAlbums",
       base::BindRepeating(&AmbientModeHandler::HandleRequestAlbums,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setSelectedTemperatureUnit",
       base::BindRepeating(&AmbientModeHandler::HandleSetSelectedTemperatureUnit,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setSelectedAlbums",
       base::BindRepeating(&AmbientModeHandler::HandleSetSelectedAlbums,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
index c68a968f..97cce9e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
@@ -29,11 +29,11 @@
 
 void AndroidAppsHandler::RegisterMessages() {
   // Note: requestAndroidAppsInfo must be called before observers will be added.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestAndroidAppsInfo",
       base::BindRepeating(&AndroidAppsHandler::HandleRequestAndroidAppsInfo,
                           weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showAndroidAppsSettings",
       base::BindRepeating(&AndroidAppsHandler::ShowAndroidAppsSettings,
                           weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler.cc
index efe1078..487c226 100644
--- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler.cc
@@ -31,11 +31,11 @@
 BluetoothHandler::~BluetoothHandler() {}
 
 void BluetoothHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kIsDeviceBlockedByPolicy,
       base::BindRepeating(&BluetoothHandler::HandleIsDeviceBlockedByPolicy,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRequestFastPairDeviceSupport,
       base::BindRepeating(&BluetoothHandler::HandleRequestFastPairDeviceSupport,
                           base::Unretained(this)));
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 c1c9915..c88bc38 100644
--- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -12,7 +12,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
@@ -87,25 +86,25 @@
 ChangePictureHandler::~ChangePictureHandler() = default;
 
 void ChangePictureHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "chooseFile", base::BindRepeating(&ChangePictureHandler::HandleChooseFile,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "photoTaken", base::BindRepeating(&ChangePictureHandler::HandlePhotoTaken,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "discardPhoto",
       base::BindRepeating(&ChangePictureHandler::HandleDiscardPhoto,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onChangePicturePageInitialized",
       base::BindRepeating(&ChangePictureHandler::HandlePageInitialized,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "selectImage",
       base::BindRepeating(&ChangePictureHandler::HandleSelectImage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestSelectedImage",
       base::BindRepeating(&ChangePictureHandler::HandleRequestSelectedImage,
                           base::Unretained(this)));
@@ -168,7 +167,7 @@
   std::string raw_data;
   base::StringPiece url(image_url);
   const char kDataUrlPrefix[] = "data:image/png;base64,";
-  const size_t kDataUrlPrefixLength = base::size(kDataUrlPrefix) - 1;
+  const size_t kDataUrlPrefixLength = std::size(kDataUrlPrefix) - 1;
   if (!base::StartsWith(url, kDataUrlPrefix) ||
       !base::Base64Decode(url.substr(kDataUrlPrefixLength), &raw_data)) {
     LOG(WARNING) << "Invalid image URL";
diff --git a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
index ac86c69..5d77773d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -53,121 +53,121 @@
 }
 
 void CrostiniHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniInstallerView",
       base::BindRepeating(&CrostiniHandler::HandleRequestCrostiniInstallerView,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestRemoveCrostini",
       base::BindRepeating(&CrostiniHandler::HandleRequestRemoveCrostini,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "exportCrostiniContainer",
       base::BindRepeating(&CrostiniHandler::HandleExportCrostiniContainer,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importCrostiniContainer",
       base::BindRepeating(&CrostiniHandler::HandleImportCrostiniContainer,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniInstallerStatus",
       base::BindRepeating(
           &CrostiniHandler::HandleCrostiniInstallerStatusRequest,
           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniExportImportOperationStatus",
       base::BindRepeating(
           &CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest,
           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestArcAdbSideloadStatus",
       base::BindRepeating(&CrostiniHandler::HandleQueryArcAdbRequest,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCanChangeArcAdbSideloading",
       base::BindRepeating(
           &CrostiniHandler::HandleCanChangeArcAdbSideloadingRequest,
           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "enableArcAdbSideload",
       base::BindRepeating(&CrostiniHandler::HandleEnableArcAdbRequest,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "disableArcAdbSideload",
       base::BindRepeating(&CrostiniHandler::HandleDisableArcAdbRequest,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniContainerUpgradeView",
       base::BindRepeating(&CrostiniHandler::HandleRequestContainerUpgradeView,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniUpgraderDialogStatus",
       base::BindRepeating(
           &CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest,
           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestCrostiniContainerUpgradeAvailable",
       base::BindRepeating(
           &CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest,
           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addCrostiniPortForward",
       base::BindRepeating(&CrostiniHandler::HandleAddCrostiniPortForward,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCrostiniDiskInfo",
       base::BindRepeating(&CrostiniHandler::HandleGetCrostiniDiskInfo,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resizeCrostiniDisk",
       base::BindRepeating(&CrostiniHandler::HandleResizeCrostiniDisk,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeCrostiniPortForward",
       base::BindRepeating(&CrostiniHandler::HandleRemoveCrostiniPortForward,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeAllCrostiniPortForwards",
       base::BindRepeating(&CrostiniHandler::HandleRemoveAllCrostiniPortForwards,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "activateCrostiniPortForward",
       base::BindRepeating(&CrostiniHandler::HandleActivateCrostiniPortForward,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "deactivateCrostiniPortForward",
       base::BindRepeating(&CrostiniHandler::HandleDeactivateCrostiniPortForward,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCrostiniActivePorts",
       base::BindRepeating(&CrostiniHandler::HandleGetCrostiniActivePorts,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "checkCrostiniIsRunning",
       base::BindRepeating(&CrostiniHandler::HandleCheckCrostiniIsRunning,
                           handler_weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "shutdownCrostini",
       base::BindRepeating(&CrostiniHandler::HandleShutdownCrostini,
                           handler_weak_ptr_factory_.GetWeakPtr()));
   if (crostini::CrostiniFeatures::Get()->IsMultiContainerAllowed(profile_)) {
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "createContainer",
         base::BindRepeating(&CrostiniHandler::HandleCreateContainer,
                             handler_weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "deleteContainer",
         base::BindRepeating(&CrostiniHandler::HandleDeleteContainer,
                             handler_weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "requestContainerInfo",
         base::BindRepeating(&CrostiniHandler::HandleRequestContainerInfo,
                             handler_weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "setContainerBadgeColor",
         base::BindRepeating(&CrostiniHandler::HandleSetContainerBadgeColor,
                             handler_weak_ptr_factory_.GetWeakPtr()));
-    web_ui()->RegisterMessageCallback(
+    web_ui()->RegisterDeprecatedMessageCallback2(
         "stopContainer",
         base::BindRepeating(&CrostiniHandler::HandleStopContainer,
                             handler_weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index cab349cb..ef5ac94 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -278,81 +278,81 @@
 CupsPrintersHandler::~CupsPrintersHandler() = default;
 
 void CupsPrintersHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCupsSavedPrintersList",
       base::BindRepeating(&CupsPrintersHandler::HandleGetCupsSavedPrintersList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCupsEnterprisePrintersList",
       base::BindRepeating(
           &CupsPrintersHandler::HandleGetCupsEnterprisePrintersList,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateCupsPrinter",
       base::BindRepeating(&CupsPrintersHandler::HandleUpdateCupsPrinter,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeCupsPrinter",
       base::BindRepeating(&CupsPrintersHandler::HandleRemoveCupsPrinter,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addCupsPrinter",
       base::BindRepeating(&CupsPrintersHandler::HandleAddCupsPrinter,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "reconfigureCupsPrinter",
       base::BindRepeating(&CupsPrintersHandler::HandleReconfigureCupsPrinter,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getPrinterInfo",
       base::BindRepeating(&CupsPrintersHandler::HandleGetPrinterInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCupsPrinterManufacturersList",
       base::BindRepeating(
           &CupsPrintersHandler::HandleGetCupsPrinterManufacturers,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCupsPrinterModelsList",
       base::BindRepeating(&CupsPrintersHandler::HandleGetCupsPrinterModels,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "selectPPDFile",
       base::BindRepeating(&CupsPrintersHandler::HandleSelectPPDFile,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startDiscoveringPrinters",
       base::BindRepeating(&CupsPrintersHandler::HandleStartDiscovery,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "stopDiscoveringPrinters",
       base::BindRepeating(&CupsPrintersHandler::HandleStopDiscovery,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getPrinterPpdManufacturerAndModel",
       base::BindRepeating(
           &CupsPrintersHandler::HandleGetPrinterPpdManufacturerAndModel,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addDiscoveredPrinter",
       base::BindRepeating(&CupsPrintersHandler::HandleAddDiscoveredPrinter,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "cancelPrinterSetUp",
       base::BindRepeating(&CupsPrintersHandler::HandleSetUpCancel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getEulaUrl", base::BindRepeating(&CupsPrintersHandler::HandleGetEulaUrl,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "queryPrintServer",
       base::BindRepeating(&CupsPrintersHandler::HandleQueryPrintServer,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openPrintManagementApp",
       base::BindRepeating(&CupsPrintersHandler::HandleOpenPrintManagementApp,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openScanningApp",
       base::BindRepeating(&CupsPrintersHandler::HandleOpenScanningApp,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
index 3dc254b3..e4fb308 100644
--- a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -69,18 +69,18 @@
 DateTimeHandler::~DateTimeHandler() = default;
 
 void DateTimeHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "dateTimePageReady",
       base::BindRepeating(&DateTimeHandler::HandleDateTimePageReady,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getTimeZones", base::BindRepeating(&DateTimeHandler::HandleGetTimeZones,
                                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showSetDateTimeUI",
       base::BindRepeating(&DateTimeHandler::HandleShowSetDateTimeUI,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "handleShowParentAccessForTimeZone",
       base::BindRepeating(&DateTimeHandler::HandleShowParentAccessForTimeZone,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc
index b51601f..0671e9df 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc
@@ -24,12 +24,12 @@
 }
 
 void DisplayHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "highlightDisplay",
       base::BindRepeating(&DisplayHandler::HandleHighlightDisplay,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "dragDisplayDelta",
       base::BindRepeating(&DisplayHandler::HandleDragDisplayDelta,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
index 90395f89..a9698da 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -66,15 +66,15 @@
 KeyboardHandler::~KeyboardHandler() = default;
 
 void KeyboardHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeKeyboardSettings",
       base::BindRepeating(&KeyboardHandler::HandleInitialize,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showKeyboardShortcutViewer",
       base::BindRepeating(&KeyboardHandler::HandleShowKeyboardShortcutViewer,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeKeyboardWatcher",
       base::BindRepeating(&KeyboardHandler::HandleKeyboardChange,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_name_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_name_handler.cc
index a0cb89e1..9922cc5 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_name_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_name_handler.cc
@@ -40,12 +40,12 @@
 }
 
 void DeviceNameHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifyReadyForDeviceName",
       base::BindRepeating(&DeviceNameHandler::HandleNotifyReadyForDeviceName,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "attemptSetDeviceName",
       base::BindRepeating(&DeviceNameHandler::HandleAttemptSetDeviceName,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
index b3b22e0..e75133a 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
@@ -16,7 +16,7 @@
 PointerHandler::~PointerHandler() {}
 
 void PointerHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializePointerSettings",
       base::BindRepeating(&PointerHandler::HandleInitialize,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
index 67da805..ff33e55 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
@@ -139,22 +139,22 @@
 PowerHandler::~PowerHandler() {}
 
 void PowerHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updatePowerStatus",
       base::BindRepeating(&PowerHandler::HandleUpdatePowerStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setPowerSource", base::BindRepeating(&PowerHandler::HandleSetPowerSource,
                                             base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestPowerManagementSettings",
       base::BindRepeating(&PowerHandler::HandleRequestPowerManagementSettings,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setLidClosedBehavior",
       base::BindRepeating(&PowerHandler::HandleSetLidClosedBehavior,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setIdleBehavior",
       base::BindRepeating(&PowerHandler::HandleSetIdleBehavior,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
index fc0d990d..fdee6e51 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -85,22 +85,22 @@
 void StorageHandler::RegisterMessages() {
   DCHECK(web_ui());
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateAndroidEnabled",
       base::BindRepeating(&StorageHandler::HandleUpdateAndroidEnabled,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateStorageInfo",
       base::BindRepeating(&StorageHandler::HandleUpdateStorageInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openMyFiles", base::BindRepeating(&StorageHandler::HandleOpenMyFiles,
                                          base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openArcStorage",
       base::BindRepeating(&StorageHandler::HandleOpenArcStorage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateExternalStorages",
       base::BindRepeating(&StorageHandler::HandleUpdateExternalStorages,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
index a85a847a..4d2ec03 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
@@ -38,24 +38,24 @@
 
   // Note: initializeStylusSettings must be called before observers will be
   // added.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeStylusSettings",
       base::BindRepeating(&StylusHandler::HandleInitialize,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestNoteTakingApps",
       base::BindRepeating(&StylusHandler::HandleRequestApps,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setPreferredNoteTakingApp",
       base::BindRepeating(&StylusHandler::HandleSetPreferredNoteTakingApp,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setPreferredNoteTakingAppEnabledOnLockScreen",
       base::BindRepeating(
           &StylusHandler::HandleSetPreferredNoteTakingAppEnabledOnLockScreen,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showPlayStoreApps",
       base::BindRepeating(&StylusHandler::HandleShowPlayStoreApps,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
index 609c49c..11638dc 100644
--- a/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
@@ -64,38 +64,38 @@
 
 void FingerprintHandler::RegisterMessages() {
   // Note: getFingerprintsList must be called before observers will be added.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getFingerprintsList",
       base::BindRepeating(&FingerprintHandler::HandleGetFingerprintsList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getNumFingerprints",
       base::BindRepeating(&FingerprintHandler::HandleGetNumFingerprints,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startEnroll", base::BindRepeating(&FingerprintHandler::HandleStartEnroll,
                                          base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "cancelCurrentEnroll",
       base::BindRepeating(&FingerprintHandler::HandleCancelCurrentEnroll,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getEnrollmentLabel",
       base::BindRepeating(&FingerprintHandler::HandleGetEnrollmentLabel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeEnrollment",
       base::BindRepeating(&FingerprintHandler::HandleRemoveEnrollment,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "changeEnrollmentLabel",
       base::BindRepeating(&FingerprintHandler::HandleChangeEnrollmentLabel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startAuthentication",
       base::BindRepeating(&FingerprintHandler::HandleStartAuthentication,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "endCurrentAuthentication",
       base::BindRepeating(&FingerprintHandler::HandleEndCurrentAuthentication,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc b/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
index bdfad8c..a1b57216 100644
--- a/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
@@ -51,20 +51,20 @@
 }
 
 void GoogleAssistantHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showGoogleAssistantSettings",
       base::BindRepeating(
           &GoogleAssistantHandler::HandleShowGoogleAssistantSettings,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "retrainAssistantVoiceModel",
       base::BindRepeating(&GoogleAssistantHandler::HandleRetrainVoiceModel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "syncVoiceModelStatus",
       base::BindRepeating(&GoogleAssistantHandler::HandleSyncVoiceModelStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeGoogleAssistantPage",
       base::BindRepeating(&GoogleAssistantHandler::HandleInitialized,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc b/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc
index 5292baa..819719d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/guest_os_handler.cc
@@ -42,21 +42,21 @@
 GuestOsHandler::~GuestOsHandler() = default;
 
 void GuestOsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getGuestOsSharedPathsDisplayText",
       base::BindRepeating(
           &GuestOsHandler::HandleGetGuestOsSharedPathsDisplayText,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeGuestOsSharedPath",
       base::BindRepeating(&GuestOsHandler::HandleRemoveGuestOsSharedPath,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifyGuestOsSharedUsbDevicesPageReady",
       base::BindRepeating(
           &GuestOsHandler::HandleNotifyGuestOsSharedUsbDevicesPageReady,
           weak_ptr_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setGuestOsUsbDeviceShared",
       base::BindRepeating(&GuestOsHandler::HandleSetGuestOsUsbDeviceShared,
                           weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc b/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
index d2e8f12..f9e906d2 100644
--- a/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
@@ -78,24 +78,24 @@
 }
 
 void InternetHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kAddThirdPartyVpnMessage,
       base::BindRepeating(&InternetHandler::AddThirdPartyVpn,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kConfigureThirdPartyVpnMessage,
       base::BindRepeating(&InternetHandler::ConfigureThirdPartyVpn,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kRequestGmsCoreNotificationsDisabledDeviceNames,
       base::BindRepeating(
           &InternetHandler::RequestGmsCoreNotificationsDisabledDeviceNames,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kShowCarrierAccountDetail,
       base::BindRepeating(&InternetHandler::ShowCarrierAccountDetail,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kShowCellularSetupUI,
       base::BindRepeating(&InternetHandler::ShowCellularSetupUI,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
index caab949..cf73500 100644
--- a/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -693,6 +693,8 @@
       {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER},
       {"networkPrimaryUserControlled",
        IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED},
+      {"networkA11yManagedByAdministrator",
+       IDS_SETTINGS_INTERNET_A11Y_MANAGED_BY_ADMINISTRATOR},
       {"networkDetailMenuRemoveESim",
        IDS_SETTINGS_INTERNET_NETWORK_MENU_REMOVE},
       {"networkDetailMenuRenameESim",
diff --git a/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc b/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
index 8135116..eff2c42 100644
--- a/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.cc
@@ -200,24 +200,24 @@
 }
 
 void KerberosAccountsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getKerberosAccounts",
       base::BindRepeating(&KerberosAccountsHandler::HandleGetKerberosAccounts,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addKerberosAccount",
       base::BindRepeating(&KerberosAccountsHandler::HandleAddKerberosAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeKerberosAccount",
       base::BindRepeating(&KerberosAccountsHandler::HandleRemoveKerberosAccount,
                           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "validateKerberosConfig",
       base::BindRepeating(
           &KerberosAccountsHandler::HandleValidateKerberosConfig,
           weak_factory_.GetWeakPtr()));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setAsActiveKerberosAccount",
       base::BindRepeating(
           &KerberosAccountsHandler::HandleSetAsActiveKerberosAccount,
diff --git a/chrome/browser/ui/webui/settings/chromeos/metrics_consent_handler.cc b/chrome/browser/ui/webui/settings/chromeos/metrics_consent_handler.cc
index f89e601..b56ca9c1 100644
--- a/chrome/browser/ui/webui/settings/chromeos/metrics_consent_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/metrics_consent_handler.cc
@@ -36,12 +36,12 @@
 MetricsConsentHandler::~MetricsConsentHandler() = default;
 
 void MetricsConsentHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kUpdateMetricsConsent,
       base::BindRepeating(&MetricsConsentHandler::HandleUpdateMetricsConsent,
                           weak_ptr_factory_.GetWeakPtr()));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kGetMetricsConsentState,
       base::BindRepeating(&MetricsConsentHandler::HandleGetMetricsConsentState,
                           weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
index f020b1b..828e6150 100644
--- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc
@@ -101,59 +101,59 @@
 MultideviceHandler::~MultideviceHandler() {}
 
 void MultideviceHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showMultiDeviceSetupDialog",
       base::BindRepeating(&MultideviceHandler::HandleShowMultiDeviceSetupDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getPageContentData",
       base::BindRepeating(&MultideviceHandler::HandleGetPageContent,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setFeatureEnabledState",
       base::BindRepeating(&MultideviceHandler::HandleSetFeatureEnabledState,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeHostDevice",
       base::BindRepeating(&MultideviceHandler::HandleRemoveHostDevice,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "retryPendingHostSetup",
       base::BindRepeating(&MultideviceHandler::HandleRetryPendingHostSetup,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setUpAndroidSms",
       base::BindRepeating(&MultideviceHandler::HandleSetUpAndroidSms,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSmartLockSignInEnabled",
       base::BindRepeating(&MultideviceHandler::HandleGetSmartLockSignInEnabled,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setSmartLockSignInEnabled",
       base::BindRepeating(&MultideviceHandler::HandleSetSmartLockSignInEnabled,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSmartLockSignInAllowed",
       base::BindRepeating(&MultideviceHandler::HandleGetSmartLockSignInAllowed,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAndroidSmsInfo",
       base::BindRepeating(&MultideviceHandler::HandleGetAndroidSmsInfo,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "attemptNotificationSetup",
       base::BindRepeating(&MultideviceHandler::HandleAttemptNotificationSetup,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "cancelNotificationSetup",
       base::BindRepeating(&MultideviceHandler::HandleCancelNotificationSetup,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "attemptAppsSetup",
       base::BindRepeating(&MultideviceHandler::HandleAttemptAppsSetup,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "cancelAppsSetup",
       base::BindRepeating(&MultideviceHandler::HandleCancelAppsSetup,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc b/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
index 6301680..155231e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
@@ -35,13 +35,13 @@
 ParentalControlsHandler::~ParentalControlsHandler() = default;
 
 void ParentalControlsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showAddSupervisionDialog",
       base::BindRepeating(
           &ParentalControlsHandler::HandleShowAddSupervisionDialog,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "launchFamilyLinkSettings",
       base::BindRepeating(
           &ParentalControlsHandler::HandleLaunchFamilyLinkSettings,
diff --git a/chrome/browser/ui/webui/settings/chromeos/peripheral_data_access_handler.cc b/chrome/browser/ui/webui/settings/chromeos/peripheral_data_access_handler.cc
index e84167ad..4a3f01b 100644
--- a/chrome/browser/ui/webui/settings/chromeos/peripheral_data_access_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/peripheral_data_access_handler.cc
@@ -73,13 +73,13 @@
 PeripheralDataAccessHandler::~PeripheralDataAccessHandler() = default;
 
 void PeripheralDataAccessHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isThunderboltSupported",
       base::BindRepeating(
           &PeripheralDataAccessHandler::HandleThunderboltSupported,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getPolicyState",
       base::BindRepeating(&PeripheralDataAccessHandler::HandleGetPolicyState,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc
index b85399f3..07698d5 100644
--- a/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc
@@ -19,7 +19,7 @@
 
 void PersonalizationHubHandler::RegisterMessages() {
   DCHECK(ash::features::IsPersonalizationHubEnabled());
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openPersonalizationHub",
       base::BindRepeating(
           &PersonalizationHubHandler::HandleOpenPersonalizationHub,
diff --git a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
index b44c172..cc0b3c9 100644
--- a/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
@@ -24,12 +24,12 @@
 PluginVmHandler::~PluginVmHandler() = default;
 
 void PluginVmHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isRelaunchNeededForNewPermissions",
       base::BindRepeating(
           &PluginVmHandler::HandleIsRelaunchNeededForNewPermissions,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "relaunchPluginVm",
       base::BindRepeating(&PluginVmHandler::HandleRelaunchPluginVm,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
index e79dfa7..059283c 100644
--- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -263,9 +263,7 @@
     UpdateRemoveFingerprintSearchTags();
   }
 
-  if (chromeos::features::IsPciguardUiEnabled()) {
-    updater.AddSearchTags(GetPciguardSearchConcepts());
-  }
+  updater.AddSearchTags(GetPciguardSearchConcepts());
 
   // Conditionally adds search tags concepts based on the subset of smart
   // privacy functionality enabled.
@@ -349,9 +347,6 @@
   html_source->AddString("peripheralDataAccessLearnMoreURL",
                          chrome::kPeripheralDataAccessHelpURL);
 
-  html_source->AddBoolean("pciguardUiEnabled",
-                          chromeos::features::IsPciguardUiEnabled());
-
   html_source->AddBoolean("showSecureDnsSetting", IsSecureDnsAvailable());
   html_source->AddBoolean("showSecureDnsOsSettingLink", false);
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc b/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
index 9fcced9..a9367e2 100644
--- a/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
@@ -22,11 +22,11 @@
 QuickUnlockHandler::~QuickUnlockHandler() = default;
 
 void QuickUnlockHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "RequestPinLoginState",
       base::BindRepeating(&QuickUnlockHandler::HandleRequestPinLoginState,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "RequestQuickUnlockDisabledByPolicy",
       base::BindRepeating(
           &QuickUnlockHandler::HandleQuickUnlockDisabledByPolicy,
diff --git a/chrome/browser/ui/webui/settings/chromeos/switch_access_handler.cc b/chrome/browser/ui/webui/settings/chromeos/switch_access_handler.cc
index 581cf03..19db1762 100644
--- a/chrome/browser/ui/webui/settings/chromeos/switch_access_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/switch_access_handler.cc
@@ -86,18 +86,18 @@
 }
 
 void SwitchAccessHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "refreshAssignmentsFromPrefs",
       base::BindRepeating(
           &SwitchAccessHandler::HandleRefreshAssignmentsFromPrefs,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifySwitchAccessActionAssignmentPaneActive",
       base::BindRepeating(
           &SwitchAccessHandler::
               HandleNotifySwitchAccessActionAssignmentPaneActive,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "notifySwitchAccessActionAssignmentPaneInactive",
       base::BindRepeating(
           &SwitchAccessHandler::
diff --git a/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc b/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc
index d642a15d..84d5d6d 100644
--- a/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/tts_handler.cc
@@ -155,18 +155,18 @@
 }
 
 void TtsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAllTtsVoiceData",
       base::BindRepeating(&TtsHandler::HandleGetAllTtsVoiceData,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getTtsExtensions",
       base::BindRepeating(&TtsHandler::HandleGetTtsExtensions,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "previewTtsVoice", base::BindRepeating(&TtsHandler::HandlePreviewTtsVoice,
                                              base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "wakeTtsEngine",
       base::BindRepeating(&TtsHandler::WakeTtsEngine, base::Unretained(this)));
 }
diff --git a/chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.cc b/chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.cc
index 199fef4..4c793766 100644
--- a/chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.cc
@@ -19,17 +19,17 @@
 void WallpaperHandler::OnJavascriptDisallowed() {}
 
 void WallpaperHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openWallpaperManager",
       base::BindRepeating(&WallpaperHandler::HandleOpenWallpaperManager,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isWallpaperSettingVisible",
       base::BindRepeating(&WallpaperHandler::HandleIsWallpaperSettingVisible,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isWallpaperPolicyControlled",
       base::BindRepeating(&WallpaperHandler::HandleIsWallpaperPolicyControlled,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/downloads_handler.cc b/chrome/browser/ui/webui/settings/downloads_handler.cc
index c36c212..119796d 100644
--- a/chrome/browser/ui/webui/settings/downloads_handler.cc
+++ b/chrome/browser/ui/webui/settings/downloads_handler.cc
@@ -42,26 +42,26 @@
 }
 
 void DownloadsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeDownloads",
       base::BindRepeating(&DownloadsHandler::HandleInitialize,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resetAutoOpenFileTypes",
       base::BindRepeating(&DownloadsHandler::HandleResetAutoOpenFileTypes,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "selectDownloadLocation",
       base::BindRepeating(&DownloadsHandler::HandleSelectDownloadLocation,
                           base::Unretained(this)));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getDownloadLocationText",
       base::BindRepeating(&DownloadsHandler::HandleGetDownloadLocationText,
                           base::Unretained(this)));
 #endif
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setDownloadsConnectionAccountLink",
       base::BindRepeating(
           &DownloadsHandler::HandleSetDownloadsConnectionAccountLink,
diff --git a/chrome/browser/ui/webui/settings/extension_control_handler.cc b/chrome/browser/ui/webui/settings/extension_control_handler.cc
index c0fde8e..0d0a118 100644
--- a/chrome/browser/ui/webui/settings/extension_control_handler.cc
+++ b/chrome/browser/ui/webui/settings/extension_control_handler.cc
@@ -19,7 +19,7 @@
 ExtensionControlHandler::~ExtensionControlHandler() {}
 
 void ExtensionControlHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "disableExtension",
       base::BindRepeating(&ExtensionControlHandler::HandleDisableExtension,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/font_handler.cc b/chrome/browser/ui/webui/settings/font_handler.cc
index 1bde43b9..2d113ce 100644
--- a/chrome/browser/ui/webui/settings/font_handler.cc
+++ b/chrome/browser/ui/webui/settings/font_handler.cc
@@ -38,7 +38,7 @@
 FontHandler::~FontHandler() {}
 
 void FontHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "fetchFontsData", base::BindRepeating(&FontHandler::HandleFetchFontsData,
                                             base::Unretained(this)));
 }
diff --git a/chrome/browser/ui/webui/settings/hats_handler.cc b/chrome/browser/ui/webui/settings/hats_handler.cc
index 8011b19..652b51a 100644
--- a/chrome/browser/ui/webui/settings/hats_handler.cc
+++ b/chrome/browser/ui/webui/settings/hats_handler.cc
@@ -48,7 +48,7 @@
 HatsHandler::~HatsHandler() = default;
 
 void HatsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "trustSafetyInteractionOccurred",
       base::BindRepeating(&HatsHandler::HandleTrustSafetyInteractionOccurred,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/import_data_handler.cc b/chrome/browser/ui/webui/settings/import_data_handler.cc
index 11d89743..9c3d6769 100644
--- a/chrome/browser/ui/webui/settings/import_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/import_data_handler.cc
@@ -55,14 +55,14 @@
 void ImportDataHandler::RegisterMessages() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeImportDialog",
       base::BindRepeating(&ImportDataHandler::HandleInitializeImportDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importData", base::BindRepeating(&ImportDataHandler::HandleImportData,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "importFromBookmarksFile",
       base::BindRepeating(&ImportDataHandler::HandleImportFromBookmarksFile,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/incompatible_applications_handler_win.cc b/chrome/browser/ui/webui/settings/incompatible_applications_handler_win.cc
index 67e2838..3c4981ac 100644
--- a/chrome/browser/ui/webui/settings/incompatible_applications_handler_win.cc
+++ b/chrome/browser/ui/webui/settings/incompatible_applications_handler_win.cc
@@ -28,27 +28,27 @@
 IncompatibleApplicationsHandler::~IncompatibleApplicationsHandler() = default;
 
 void IncompatibleApplicationsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestIncompatibleApplicationsList",
       base::BindRepeating(&IncompatibleApplicationsHandler::
                               HandleRequestIncompatibleApplicationsList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "startApplicationUninstallation",
       base::BindRepeating(&IncompatibleApplicationsHandler::
                               HandleStartApplicationUninstallation,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSubtitlePluralString",
       base::BindRepeating(
           &IncompatibleApplicationsHandler::HandleGetSubtitlePluralString,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSubtitleNoAdminRightsPluralString",
       base::BindRepeating(&IncompatibleApplicationsHandler::
                               HandleGetSubtitleNoAdminRightsPluralString,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getListTitlePluralString",
       base::BindRepeating(
           &IncompatibleApplicationsHandler::HandleGetListTitlePluralString,
diff --git a/chrome/browser/ui/webui/settings/languages_handler.cc b/chrome/browser/ui/webui/settings/languages_handler.cc
index bebc625..edbc3e89 100644
--- a/chrome/browser/ui/webui/settings/languages_handler.cc
+++ b/chrome/browser/ui/webui/settings/languages_handler.cc
@@ -33,11 +33,11 @@
 LanguagesHandler::~LanguagesHandler() = default;
 
 void LanguagesHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getProspectiveUILanguage",
       base::BindRepeating(&LanguagesHandler::HandleGetProspectiveUILanguage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setProspectiveUILanguage",
       base::BindRepeating(&LanguagesHandler::HandleSetProspectiveUILanguage,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
index 7ee58803..3cbc69f6 100644
--- a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
+++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
@@ -30,11 +30,11 @@
 MetricsReportingHandler::~MetricsReportingHandler() {}
 
 void MetricsReportingHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getMetricsReporting",
       base::BindRepeating(&MetricsReportingHandler::HandleGetMetricsReporting,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setMetricsReportingEnabled",
       base::BindRepeating(
           &MetricsReportingHandler::HandleSetMetricsReportingEnabled,
diff --git a/chrome/browser/ui/webui/settings/native_certificates_handler.cc b/chrome/browser/ui/webui/settings/native_certificates_handler.cc
index 8676588..db9fe39 100644
--- a/chrome/browser/ui/webui/settings/native_certificates_handler.cc
+++ b/chrome/browser/ui/webui/settings/native_certificates_handler.cc
@@ -17,7 +17,7 @@
 NativeCertificatesHandler::~NativeCertificatesHandler() {}
 
 void NativeCertificatesHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showManageSSLCertificates",
       base::BindRepeating(
           &NativeCertificatesHandler::HandleShowManageSSLCertificates,
diff --git a/chrome/browser/ui/webui/settings/on_startup_handler.cc b/chrome/browser/ui/webui/settings/on_startup_handler.cc
index 93f0bf18..bb1f77d 100644
--- a/chrome/browser/ui/webui/settings/on_startup_handler.cc
+++ b/chrome/browser/ui/webui/settings/on_startup_handler.cc
@@ -39,11 +39,11 @@
 }
 
 void OnStartupHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getNtpExtension",
       base::BindRepeating(&OnStartupHandler::HandleGetNtpExtension,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "validateStartupPage",
       base::BindRepeating(&OnStartupHandler::HandleValidateStartupPage,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index ba04fa3..33cc05b99 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -225,72 +225,72 @@
 
 void PeopleHandler::RegisterMessages() {
   InitializeSyncBlocker();
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupDidClosePage",
       base::BindRepeating(&PeopleHandler::OnDidClosePage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupSetDatatypes",
       base::BindRepeating(&PeopleHandler::HandleSetDatatypes,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupSetEncryptionPassphrase",
       base::BindRepeating(&PeopleHandler::HandleSetEncryptionPassphrase,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupSetDecryptionPassphrase",
       base::BindRepeating(&PeopleHandler::HandleSetDecryptionPassphrase,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupShowSetupUI",
       base::BindRepeating(&PeopleHandler::HandleShowSyncSetupUI,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupGetSyncStatus",
       base::BindRepeating(&PeopleHandler::HandleGetSyncStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncPrefsDispatch",
       base::BindRepeating(&PeopleHandler::HandleSyncPrefsDispatch,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncTrustedVaultBannerStateDispatch",
       base::BindRepeating(&PeopleHandler::HandleTrustedVaultBannerStateDispatch,
                           base::Unretained(this)));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "AttemptUserExit",
       base::BindRepeating(&PeopleHandler::HandleAttemptUserExit,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "TurnOnSync", base::BindRepeating(&PeopleHandler::HandleTurnOnSync,
                                         base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "TurnOffSync", base::BindRepeating(&PeopleHandler::HandleTurnOffSync,
                                          base::Unretained(this)));
 #else
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupStartSignIn",
       base::BindRepeating(&PeopleHandler::HandleStartSignin,
                           base::Unretained(this)));
 #endif
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupSignout", base::BindRepeating(&PeopleHandler::HandleSignout,
                                               base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupPauseSync", base::BindRepeating(&PeopleHandler::HandlePauseSync,
                                                 base::Unretained(this)));
 #endif
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupGetStoredAccounts",
       base::BindRepeating(&PeopleHandler::HandleGetStoredAccounts,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncSetupStartSyncingWithEmail",
       base::BindRepeating(&PeopleHandler::HandleStartSyncingWithEmail,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "SyncStartKeyRetrieval",
       base::BindRepeating(&PeopleHandler::HandleStartKeyRetrieval,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/privacy_sandbox_handler.cc b/chrome/browser/ui/webui/settings/privacy_sandbox_handler.cc
index 254a1266..1a727dd 100644
--- a/chrome/browser/ui/webui/settings/privacy_sandbox_handler.cc
+++ b/chrome/browser/ui/webui/settings/privacy_sandbox_handler.cc
@@ -67,26 +67,26 @@
 PrivacySandboxHandler::~PrivacySandboxHandler() = default;
 
 void PrivacySandboxHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getFlocId", base::BindRepeating(&PrivacySandboxHandler::HandleGetFlocId,
                                        base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resetFlocId",
       base::BindRepeating(&PrivacySandboxHandler::HandleResetFlocId,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setFledgeJoiningAllowed",
       base::BindRepeating(&PrivacySandboxHandler::HandleSetFledgeJoiningAllowed,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getFledgeState",
       base::BindRepeating(&PrivacySandboxHandler::HandleGetFledgeState,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setTopicAllowed",
       base::BindRepeating(&PrivacySandboxHandler::HandleSetTopicAllowed,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getTopicsState",
       base::BindRepeating(&PrivacySandboxHandler::HandleGetTopicsState,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc
index d280ef5b..b7033cd 100644
--- a/chrome/browser/ui/webui/settings/profile_info_handler.cc
+++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -45,12 +45,12 @@
 ProfileInfoHandler::~ProfileInfoHandler() {}
 
 void ProfileInfoHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getProfileInfo",
       base::BindRepeating(&ProfileInfoHandler::HandleGetProfileInfo,
                           base::Unretained(this)));
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getProfileStatsCount",
       base::BindRepeating(&ProfileInfoHandler::HandleGetProfileStats,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
index a32e7a4..39db2b7 100644
--- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
+++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
@@ -69,41 +69,41 @@
 }
 
 void ProtocolHandlersHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "observeProtocolHandlers",
       base::BindRepeating(
           &ProtocolHandlersHandler::HandleObserveProtocolHandlers,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "observeProtocolHandlersEnabledState",
       base::BindRepeating(
           &ProtocolHandlersHandler::HandleObserveProtocolHandlersEnabledState,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeHandler",
       base::BindRepeating(&ProtocolHandlersHandler::HandleRemoveHandler,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setHandlersEnabled",
       base::BindRepeating(&ProtocolHandlersHandler::HandleSetHandlersEnabled,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setDefault",
       base::BindRepeating(&ProtocolHandlersHandler::HandleSetDefault,
                           base::Unretained(this)));
 
   // Web App Protocol Handlers register message callbacks:
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "observeAppProtocolHandlers",
       base::BindRepeating(
           &ProtocolHandlersHandler::HandleObserveAppProtocolHandlers,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeAppAllowedHandler",
       base::BindRepeating(
           &ProtocolHandlersHandler::HandleRemoveAllowedAppHandler,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeAppDisallowedHandler",
       base::BindRepeating(
           &ProtocolHandlersHandler::HandleRemoveDisallowedAppHandler,
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 91322a9..e24cb444 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -97,33 +97,33 @@
 }
 
 void ResetSettingsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "performResetProfileSettings",
       base::BindRepeating(&ResetSettingsHandler::HandleResetProfileSettings,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onShowResetProfileDialog",
       base::BindRepeating(&ResetSettingsHandler::OnShowResetProfileDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getReportedSettings",
       base::BindRepeating(&ResetSettingsHandler::HandleGetReportedSettings,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onHideResetProfileDialog",
       base::BindRepeating(&ResetSettingsHandler::OnHideResetProfileDialog,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onHideResetProfileBanner",
       base::BindRepeating(&ResetSettingsHandler::OnHideResetProfileBanner,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getTriggeredResetToolName",
       base::BindRepeating(
           &ResetSettingsHandler::HandleGetTriggeredResetToolName,
           base::Unretained(this)));
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onPowerwashDialogShow",
       base::BindRepeating(&ResetSettingsHandler::OnShowPowerwashDialog,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chrome/browser/ui/webui/settings/safety_check_handler.cc
index d911b24..6f029b3 100644
--- a/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -1056,11 +1056,11 @@
 void SafetyCheckHandler::RegisterMessages() {
   // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
   // won't release ownership until destruction.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kPerformSafetyCheck,
       base::BindRepeating(&SafetyCheckHandler::HandlePerformSafetyCheck,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       kGetParentRanDisplayString,
       base::BindRepeating(&SafetyCheckHandler::HandleGetParentRanDisplayString,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index 70932cc..9c5c7416 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -57,37 +57,37 @@
 }
 
 void SearchEnginesHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSearchEnginesList",
       base::BindRepeating(&SearchEnginesHandler::HandleGetSearchEnginesList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setDefaultSearchEngine",
       base::BindRepeating(&SearchEnginesHandler::HandleSetDefaultSearchEngine,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setIsActiveSearchEngine",
       base::BindRepeating(&SearchEnginesHandler::HandleSetIsActiveSearchEngine,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeSearchEngine",
       base::BindRepeating(&SearchEnginesHandler::HandleRemoveSearchEngine,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "validateSearchEngineInput",
       base::BindRepeating(
           &SearchEnginesHandler::HandleValidateSearchEngineInput,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "searchEngineEditStarted",
       base::BindRepeating(&SearchEnginesHandler::HandleSearchEngineEditStarted,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "searchEngineEditCancelled",
       base::BindRepeating(
           &SearchEnginesHandler::HandleSearchEngineEditCancelled,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "searchEngineEditCompleted",
       base::BindRepeating(
           &SearchEnginesHandler::HandleSearchEngineEditCompleted,
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index e1c2ca33..b936147 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h"
 
 #include <stddef.h>
+
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -90,17 +90,17 @@
 ClearBrowsingDataHandler::~ClearBrowsingDataHandler() = default;
 
 void ClearBrowsingDataHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getInstalledApps",
       base::BindRepeating(
           &ClearBrowsingDataHandler::GetRecentlyLaunchedInstalledApps,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearBrowsingData",
       base::BindRepeating(&ClearBrowsingDataHandler::HandleClearBrowsingData,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "initializeClearBrowsingData",
       base::BindRepeating(&ClearBrowsingDataHandler::HandleInitialize,
                           base::Unretained(this)));
@@ -328,7 +328,7 @@
         BrowsingDataType::CACHE,          BrowsingDataType::COOKIES,
         BrowsingDataType::FORM_DATA,      BrowsingDataType::HOSTED_APPS_DATA,
     };
-    static size_t num_other_types = base::size(other_types);
+    static size_t num_other_types = std::size(other_types);
     int checked_other_types =
         std::count_if(other_types, other_types + num_other_types,
                       [&data_types](BrowsingDataType type) {
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
index c75e456..f84bef0 100644
--- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/number_formatting.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -82,7 +81,7 @@
   };
   // Before optimizing, consider the data size and the cost of L2 cache misses.
   // A linear search over a couple dozen integers is very fast.
-  for (size_t i = 0; i < base::size(kCategoryLabels); ++i) {
+  for (size_t i = 0; i < std::size(kCategoryLabels); ++i) {
     if (kCategoryLabels[i].node_type == node_type) {
       return kCategoryLabels[i].id;
     }
@@ -140,39 +139,39 @@
 }
 
 void CookiesViewHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.getDisplayList",
       base::BindRepeating(&CookiesViewHandler::HandleGetDisplayList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.removeAll",
       base::BindRepeating(&CookiesViewHandler::HandleRemoveAll,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.removeShownItems",
       base::BindRepeating(&CookiesViewHandler::HandleRemoveShownItems,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.removeItem",
       base::BindRepeating(&CookiesViewHandler::HandleRemoveItem,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.getCookieDetails",
       base::BindRepeating(&CookiesViewHandler::HandleGetCookieDetails,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.getNumCookiesString",
       base::BindRepeating(&CookiesViewHandler::HandleGetNumCookiesString,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.removeSite",
       base::BindRepeating(&CookiesViewHandler::HandleRemoveSite,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.removeThirdPartyCookies",
       base::BindRepeating(&CookiesViewHandler::HandleRemoveThirdParty,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "localData.reload",
       base::BindRepeating(&CookiesViewHandler::HandleReloadCookies,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
index 2cca3ff..052bc31 100644
--- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -33,11 +33,11 @@
 DefaultBrowserHandler::~DefaultBrowserHandler() = default;
 
 void DefaultBrowserHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestDefaultBrowserState",
       base::BindRepeating(&DefaultBrowserHandler::RequestDefaultBrowserState,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setAsDefaultBrowser",
       base::BindRepeating(&DefaultBrowserHandler::SetAsDefaultBrowser,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index e0fbbfc3..b6c753f7 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -53,34 +53,34 @@
 ManageProfileHandler::~ManageProfileHandler() {}
 
 void ManageProfileHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAvailableIcons",
       base::BindRepeating(&ManageProfileHandler::HandleGetAvailableIcons,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setProfileIconToGaiaAvatar",
       base::BindRepeating(
           &ManageProfileHandler::HandleSetProfileIconToGaiaAvatar,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setProfileIconToDefaultAvatar",
       base::BindRepeating(
           &ManageProfileHandler::HandleSetProfileIconToDefaultAvatar,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setProfileName",
       base::BindRepeating(&ManageProfileHandler::HandleSetProfileName,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "requestProfileShortcutStatus",
       base::BindRepeating(
           &ManageProfileHandler::HandleRequestProfileShortcutStatus,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addProfileShortcut",
       base::BindRepeating(&ManageProfileHandler::HandleAddProfileShortcut,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeProfileShortcut",
       base::BindRepeating(&ManageProfileHandler::HandleRemoveProfileShortcut,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
index 64d9bef6..4e731a5 100644
--- a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
@@ -44,12 +44,12 @@
 }
 
 void MediaDevicesSelectionHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getDefaultCaptureDevices",
       base::BindRepeating(
           &MediaDevicesSelectionHandler::GetDefaultCaptureDevices,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setDefaultCaptureDevice",
       base::BindRepeating(
           &MediaDevicesSelectionHandler::SetDefaultCaptureDevice,
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
index 56aa0c6..3bd2357 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -58,26 +58,26 @@
 SecureDnsHandler::~SecureDnsHandler() = default;
 
 void SecureDnsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSecureDnsResolverList",
       base::BindRepeating(&SecureDnsHandler::HandleGetSecureDnsResolverList,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getSecureDnsSetting",
       base::BindRepeating(&SecureDnsHandler::HandleGetSecureDnsSetting,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isValidConfig",
       base::BindRepeating(&SecureDnsHandler::HandleIsValidConfig,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "probeConfig", base::BindRepeating(&SecureDnsHandler::HandleProbeConfig,
                                          base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "recordUserDropdownInteraction",
       base::BindRepeating(
           &SecureDnsHandler::HandleRecordUserDropdownInteraction,
diff --git a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index 21aba07..73d4a84 100644
--- a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -95,15 +95,15 @@
 SecurityKeysPINHandler::~SecurityKeysPINHandler() = default;
 
 void SecurityKeysPINHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyStartSetPIN",
       base::BindRepeating(&SecurityKeysPINHandler::HandleStartSetPIN,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeySetPIN",
       base::BindRepeating(&SecurityKeysPINHandler::HandleSetPIN,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyPINClose",
       base::BindRepeating(&HandleClose,
                           base::BindRepeating(&SecurityKeysPINHandler::Close,
@@ -202,15 +202,15 @@
 SecurityKeysResetHandler::~SecurityKeysResetHandler() = default;
 
 void SecurityKeysResetHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyReset",
       base::BindRepeating(&SecurityKeysResetHandler::HandleReset,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCompleteReset",
       base::BindRepeating(&SecurityKeysResetHandler::HandleCompleteReset,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyResetClose",
       base::BindRepeating(&HandleClose,
                           base::BindRepeating(&SecurityKeysResetHandler::Close,
@@ -344,28 +344,28 @@
 }
 
 void SecurityKeysCredentialHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementStart",
       base::BindRepeating(&SecurityKeysCredentialHandler::HandleStart,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementPIN",
       base::BindRepeating(&SecurityKeysCredentialHandler::HandlePIN,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementEnumerate",
       base::BindRepeating(&SecurityKeysCredentialHandler::HandleEnumerate,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementDelete",
       base::BindRepeating(&SecurityKeysCredentialHandler::HandleDelete,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementUpdate",
       base::BindRepeating(
           &SecurityKeysCredentialHandler::HandleUpdateUserInformation,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyCredentialManagementClose",
       base::BindRepeating(
           &HandleClose,
@@ -682,41 +682,41 @@
 }
 
 void SecurityKeysBioEnrollmentHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollStart",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleStart,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollProvidePIN",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleProvidePIN,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollGetSensorInfo",
       base::BindRepeating(
           &SecurityKeysBioEnrollmentHandler::HandleGetSensorInfo,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollEnumerate",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleEnumerate,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollStartEnrolling",
       base::BindRepeating(
           &SecurityKeysBioEnrollmentHandler::HandleStartEnrolling,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollDelete",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleDelete,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollRename",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleRename,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollCancel",
       base::BindRepeating(&SecurityKeysBioEnrollmentHandler::HandleCancel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyBioEnrollClose",
       base::BindRepeating(
           &HandleClose,
@@ -1012,15 +1012,15 @@
 void SecurityKeysPhonesHandler::OnJavascriptDisallowed() {}
 
 void SecurityKeysPhonesHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyPhonesEnumerate",
       base::BindRepeating(&SecurityKeysPhonesHandler::HandleEnumerate,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyPhonesDelete",
       base::BindRepeating(&SecurityKeysPhonesHandler::HandleDelete,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "securityKeyPhonesRename",
       base::BindRepeating(&SecurityKeysPhonesHandler::HandleRename,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
index a1ee929..d3f3116 100644
--- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -30,23 +30,23 @@
   if (Profile::FromWebUI(web_ui())->IsOffTheRecord())
     return;
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "addStartupPage",
       base::BindRepeating(&StartupPagesHandler::HandleAddStartupPage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "editStartupPage",
       base::BindRepeating(&StartupPagesHandler::HandleEditStartupPage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "onStartupPrefsPageLoad",
       base::BindRepeating(&StartupPagesHandler::HandleOnStartupPrefsPageLoad,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeStartupPage",
       base::BindRepeating(&StartupPagesHandler::HandleRemoveStartupPage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setStartupPagesToCurrentPages",
       base::BindRepeating(
           &StartupPagesHandler::HandleSetStartupPagesToCurrentPages,
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 34e369a..248f608 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -506,114 +506,114 @@
 }
 
 void SiteSettingsHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "fetchUsageTotal",
       base::BindRepeating(&SiteSettingsHandler::HandleFetchUsageTotal,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearUnpartitionedUsage",
       base::BindRepeating(&SiteSettingsHandler::HandleClearUnpartitionedUsage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearPartitionedUsage",
       base::BindRepeating(&SiteSettingsHandler::HandleClearPartitionedUsage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setDefaultValueForContentType",
       base::BindRepeating(
           &SiteSettingsHandler::HandleSetDefaultValueForContentType,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getDefaultValueForContentType",
       base::BindRepeating(
           &SiteSettingsHandler::HandleGetDefaultValueForContentType,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAllSites",
       base::BindRepeating(&SiteSettingsHandler::HandleGetAllSites,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCategoryList",
       base::BindRepeating(&SiteSettingsHandler::HandleGetCategoryList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getCookieSettingDescription",
       base::BindRepeating(
           &SiteSettingsHandler::HandleGetCookieSettingDescription,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getRecentSitePermissions",
       base::BindRepeating(&SiteSettingsHandler::HandleGetRecentSitePermissions,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getFormattedBytes",
       base::BindRepeating(&SiteSettingsHandler::HandleGetFormattedBytes,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getExceptionList",
       base::BindRepeating(&SiteSettingsHandler::HandleGetExceptionList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getChooserExceptionList",
       base::BindRepeating(&SiteSettingsHandler::HandleGetChooserExceptionList,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getOriginPermissions",
       base::BindRepeating(&SiteSettingsHandler::HandleGetOriginPermissions,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setOriginPermissions",
       base::BindRepeating(&SiteSettingsHandler::HandleSetOriginPermissions,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resetCategoryPermissionForPattern",
       base::BindRepeating(
           &SiteSettingsHandler::HandleResetCategoryPermissionForPattern,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setCategoryPermissionForPattern",
       base::BindRepeating(
           &SiteSettingsHandler::HandleSetCategoryPermissionForPattern,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "resetChooserExceptionForSite",
       base::BindRepeating(
           &SiteSettingsHandler::HandleResetChooserExceptionForSite,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isOriginValid",
       base::BindRepeating(&SiteSettingsHandler::HandleIsOriginValid,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "isPatternValidForType",
       base::BindRepeating(&SiteSettingsHandler::HandleIsPatternValidForType,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "updateIncognitoStatus",
       base::BindRepeating(&SiteSettingsHandler::HandleUpdateIncognitoStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "fetchZoomLevels",
       base::BindRepeating(&SiteSettingsHandler::HandleFetchZoomLevels,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "removeZoomLevel",
       base::BindRepeating(&SiteSettingsHandler::HandleRemoveZoomLevel,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "setBlockAutoplayEnabled",
       base::BindRepeating(&SiteSettingsHandler::HandleSetBlockAutoplayEnabled,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "fetchBlockAutoplayStatus",
       base::BindRepeating(&SiteSettingsHandler::HandleFetchBlockAutoplayStatus,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "clearEtldPlus1DataAndCookies",
       base::BindRepeating(
           &SiteSettingsHandler::HandleClearEtldPlus1DataAndCookies,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "recordAction",
       base::BindRepeating(&SiteSettingsHandler::HandleRecordAction,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc
index 4313cfe..afec1507 100644
--- a/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -169,7 +169,7 @@
     {ContentSettingsType::REQUEST_DESKTOP_SITE, nullptr},
 };
 
-static_assert(base::size(kContentSettingsTypeGroupNames) ==
+static_assert(std::size(kContentSettingsTypeGroupNames) ==
                   // ContentSettingsType starts at -1, so add 1 here.
                   static_cast<int32_t>(ContentSettingsType::NUM_TYPES) + 1,
               "kContentSettingsTypeGroupNames should have "
@@ -192,7 +192,7 @@
     {SiteSettingSource::kPolicy, "policy"},
     {SiteSettingSource::kPreference, "preference"},
 };
-static_assert(base::size(kSiteSettingSourceStringMapping) ==
+static_assert(std::size(kSiteSettingSourceStringMapping) ==
                   static_cast<int>(SiteSettingSource::kNumSources),
               "kSiteSettingSourceStringMapping should have "
               "SiteSettingSource::kNumSources elements");
@@ -214,7 +214,7 @@
     {PolicyIndicatorType::kParent, "parent"},
     {PolicyIndicatorType::kChildRestriction, "childRestriction"},
 };
-static_assert(base::size(kPolicyIndicatorTypeStringMapping) ==
+static_assert(std::size(kPolicyIndicatorTypeStringMapping) ==
                   static_cast<int>(PolicyIndicatorType::kNumIndicators),
               "kPolicyIndicatorStringMapping should have "
               "PolicyIndicatorType::kNumIndicators elements");
@@ -381,7 +381,7 @@
 }  // namespace
 
 bool HasRegisteredGroupName(ContentSettingsType type) {
-  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
+  for (size_t i = 0; i < std::size(kContentSettingsTypeGroupNames); ++i) {
     if (type == kContentSettingsTypeGroupNames[i].type &&
         kContentSettingsTypeGroupNames[i].name) {
       return true;
@@ -391,7 +391,7 @@
 }
 
 ContentSettingsType ContentSettingsTypeFromGroupName(base::StringPiece name) {
-  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
+  for (size_t i = 0; i < std::size(kContentSettingsTypeGroupNames); ++i) {
     if (name == kContentSettingsTypeGroupNames[i].name)
       return kContentSettingsTypeGroupNames[i].type;
   }
@@ -401,7 +401,7 @@
 }
 
 base::StringPiece ContentSettingsTypeToGroupName(ContentSettingsType type) {
-  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
+  for (size_t i = 0; i < std::size(kContentSettingsTypeGroupNames); ++i) {
     if (type == kContentSettingsTypeGroupNames[i].type) {
       const char* name = kContentSettingsTypeGroupNames[i].name;
       if (name)
diff --git a/chrome/browser/ui/webui/settings/system_handler.cc b/chrome/browser/ui/webui/settings/system_handler.cc
index d322315..54de4467 100644
--- a/chrome/browser/ui/webui/settings/system_handler.cc
+++ b/chrome/browser/ui/webui/settings/system_handler.cc
@@ -29,7 +29,7 @@
 }
 
 void SystemHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "showProxySettings",
       base::BindRepeating(&SystemHandler::HandleShowProxySettings,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
index ce824995..1164f6c 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos.cc
@@ -240,12 +240,12 @@
       "getAccounts",
       base::BindRepeating(&InlineLoginHandlerChromeOS::GetAccountsInSession,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAccountsNotAvailableInArc",
       base::BindRepeating(
           &InlineLoginHandlerChromeOS::GetAccountsNotAvailableInArc,
           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "makeAvailableInArc",
       base::BindRepeating(
           &InlineLoginHandlerChromeOS::MakeAvailableInArcAndCloseDialog,
@@ -254,7 +254,7 @@
       "skipWelcomePage",
       base::BindRepeating(&InlineLoginHandlerChromeOS::HandleSkipWelcomePage,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openGuestWindow",
       base::BindRepeating(
           &InlineLoginHandlerChromeOS::OpenGuestWindowAndCloseDialog,
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
index 0975bf2..34ff5bf 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -445,7 +445,7 @@
       "getAvailableAccounts",
       base::BindRepeating(&ProfilePickerHandler::HandleGetAvailableAccounts,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "openAshAccountSettingsPage",
       base::BindRepeating(
           &ProfilePickerHandler::HandleOpenAshAccountSettingsPage,
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 08d3bbb..ff8f843 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
@@ -92,58 +92,58 @@
 void SyncInternalsMessageHandler::RegisterMessages() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestDataAndRegisterForUpdates,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestDataAndRegisterForUpdates,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestListOfTypes,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestListOfTypes,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestIncludeSpecificsInitialState,
       base::BindRepeating(&SyncInternalsMessageHandler::
                               HandleRequestIncludeSpecificsInitialState,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kSetIncludeSpecifics,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleSetIncludeSpecifics,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kWriteUserEvent,
       base::BindRepeating(&SyncInternalsMessageHandler::HandleWriteUserEvent,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestStart,
       base::BindRepeating(&SyncInternalsMessageHandler::HandleRequestStart,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestStopKeepData,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestStopKeepData,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kRequestStopClearData,
       base::BindRepeating(
           &SyncInternalsMessageHandler::HandleRequestStopClearData,
           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kTriggerRefresh,
       base::BindRepeating(&SyncInternalsMessageHandler::HandleTriggerRefresh,
                           base::Unretained(this)));
 
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       syncer::sync_ui_util::kGetAllNodes,
       base::BindRepeating(&SyncInternalsMessageHandler::HandleGetAllNodes,
                           base::Unretained(this)));
diff --git a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc
index 5dcd8e2..3f58c6fdd 100644
--- a/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc
+++ b/chrome/browser/ui/webui/translate_internals/chrome_translate_internals_handler.cc
@@ -52,7 +52,7 @@
 void ChromeTranslateInternalsHandler::RegisterMessageCallback(
     const std::string& message,
     MessageCallback callback) {
-  web_ui()->RegisterMessageCallback(message, std::move(callback));
+  web_ui()->RegisterDeprecatedMessageCallback2(message, std::move(callback));
 }
 
 void ChromeTranslateInternalsHandler::RegisterDeprecatedMessageCallback(
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
index b75d8450..8b9fec4 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -13,7 +13,6 @@
 #include "base/build_time.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
@@ -395,8 +394,8 @@
       UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED,
       UpgradeDetector::UPGRADE_ANNOYANCE_LOW,
       UpgradeDetector::UPGRADE_ANNOYANCE_VERY_LOW};
-  static_assert(base::size(kIndexToLevel) == kNumStages, "mismatch");
-  DCHECK_LT(index, base::size(kIndexToLevel));
+  static_assert(std::size(kIndexToLevel) == kNumStages, "mismatch");
+  DCHECK_LT(index, std::size(kIndexToLevel));
   return kIndexToLevel[index];
 }
 
diff --git a/chrome/browser/vr/chrome_xr_integration_client.cc b/chrome/browser/vr/chrome_xr_integration_client.cc
index 74ee91e..ef1aade2 100644
--- a/chrome/browser/vr/chrome_xr_integration_client.cc
+++ b/chrome/browser/vr/chrome_xr_integration_client.cc
@@ -48,7 +48,7 @@
                                bool in_use) override {
     DVLOG(3) << __func__ << ": web_contents=" << web_contents
              << ", in_use=" << in_use << ", num_runtimes_with_camera_in_use_="
-             << num_runtimes_with_camera_in_use_ << ", ui_=" << ui_;
+             << num_runtimes_with_camera_in_use_ << ", ui_=" << ui_.get();
     // If `in_use` is true, we need to have a non-null `web_contents` to be able
     // to register the media stream:
     DCHECK(!in_use || web_contents);
diff --git a/chrome/browser/vr/elements/controller.cc b/chrome/browser/vr/elements/controller.cc
index 3c1cbfc..8268f537 100644
--- a/chrome/browser/vr/elements/controller.cc
+++ b/chrome/browser/vr/elements/controller.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/vr/elements/controller.h"
 
-#include "base/cxx17_backports.h"
 #include "base/numerics/math_constants.h"
 #include "base/trace_event/trace_event.h"
 #include "chrome/browser/vr/ui_element_renderer.h"
@@ -278,9 +277,9 @@
   opacity_handle_ = glGetUniformLocation(program_handle_, "u_Opacity");
 
   auto body_alpha_curve =
-      CreateAlphaCurve(kBodyAlphaStops, base::size(kBodyAlphaStops));
+      CreateAlphaCurve(kBodyAlphaStops, std::size(kBodyAlphaStops));
   auto top_alpha_curve =
-      CreateAlphaCurve(kTopAlphaStops, base::size(kTopAlphaStops));
+      CreateAlphaCurve(kTopAlphaStops, std::size(kTopAlphaStops));
 
   gfx::Transform transform;
   transform.Translate3d(0.0, 0.0, (kControllerLength - kControllerWidth) / 2);
diff --git a/chrome/browser/vr/elements/draw_phase.cc b/chrome/browser/vr/elements/draw_phase.cc
index f8a71fe..a580701 100644
--- a/chrome/browser/vr/elements/draw_phase.cc
+++ b/chrome/browser/vr/elements/draw_phase.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/vr/elements/draw_phase.h"
 
-#include "base/cxx17_backports.h"
-
 namespace vr {
 
 namespace {
@@ -16,7 +14,7 @@
 };
 
 static_assert(
-    kNumDrawPhases + 1 == base::size(g_draw_phase_strings),
+    kNumDrawPhases + 1 == std::size(g_draw_phase_strings),
     "Mismatch between the DrawPhase enum and the corresponding strings");
 
 }  // namespace
diff --git a/chrome/browser/vr/elements/environment/stars.cc b/chrome/browser/vr/elements/environment/stars.cc
index 23db423..4de5733 100644
--- a/chrome/browser/vr/elements/environment/stars.cc
+++ b/chrome/browser/vr/elements/environment/stars.cc
@@ -121,7 +121,7 @@
   glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
 
-  glDrawElements(GL_TRIANGLES, base::size(g_indices), GL_UNSIGNED_SHORT, 0);
+  glDrawElements(GL_TRIANGLES, std::size(g_indices), GL_UNSIGNED_SHORT, 0);
 
   glDisableVertexAttribArray(position_handle_);
   glDisableVertexAttribArray(opacity_handle_);
@@ -185,13 +185,12 @@
   index_buffer_ = buffers[1];
 
   glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
-  glBufferData(GL_ARRAY_BUFFER, base::size(g_vertices) * sizeof(float),
+  glBufferData(GL_ARRAY_BUFFER, std::size(g_vertices) * sizeof(float),
                g_vertices, GL_STATIC_DRAW);
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
-  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-               base::size(g_indices) * sizeof(GLushort), g_indices,
-               GL_STATIC_DRAW);
+  glBufferData(GL_ELEMENT_ARRAY_BUFFER, std::size(g_indices) * sizeof(GLushort),
+               g_indices, GL_STATIC_DRAW);
 }
 
 }  // namespace vr
diff --git a/chrome/browser/vr/elements/scrollable_element_unittest.cc b/chrome/browser/vr/elements/scrollable_element_unittest.cc
index 2382f57..5db1278 100644
--- a/chrome/browser/vr/elements/scrollable_element_unittest.cc
+++ b/chrome/browser/vr/elements/scrollable_element_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/vr/elements/scrollable_element.h"
 
-#include "base/cxx17_backports.h"
 #include "chrome/browser/vr/input_event.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/test/geometry_util.h"
@@ -41,7 +40,7 @@
       {1000.0f, 1000.0f, -0.5f}, {-1000.0f, -1000.0f, 0.5f},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(i);
     element->OnScrollUpdate(
         CreateScrollUpdate(test_cases[i].delta_x, test_cases[i].delta_y), {});
@@ -67,7 +66,7 @@
     float expected;
   } test_cases[] = {{-1000.0f, -1000.0f, 0.5f}, {1000.0f, 1000.0f, -0.5f}};
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(i);
     element->OnScrollUpdate(
         CreateScrollUpdate(test_cases[i].delta_x, test_cases[i].delta_y), {});
@@ -94,7 +93,7 @@
       {1000.0f, 1000.0f, -0.5f}, {-1000.0f, -1000.0f, 0.5f},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(i);
     element->OnScrollUpdate(
         CreateScrollUpdate(test_cases[i].delta_x, test_cases[i].delta_y), {});
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc
index 9106c7e..c15b94e2 100644
--- a/chrome/browser/vr/elements/ui_element_name.cc
+++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/vr/elements/ui_element_name.h"
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 
 namespace vr {
 
@@ -155,7 +154,7 @@
 };
 
 static_assert(
-    kNumUiElementNames == base::size(g_ui_element_name_strings),
+    kNumUiElementNames == std::size(g_ui_element_name_strings),
     "Mismatch between the kUiElementName enum and the corresponding array "
     "of strings.");
 
diff --git a/chrome/browser/vr/elements/ui_element_type.cc b/chrome/browser/vr/elements/ui_element_type.cc
index 49c78f6..85e558ca 100644
--- a/chrome/browser/vr/elements/ui_element_type.cc
+++ b/chrome/browser/vr/elements/ui_element_type.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/vr/elements/ui_element_type.h"
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 
 namespace vr {
 
@@ -50,7 +49,7 @@
 };
 
 static_assert(
-    kNumUiElementTypes == base::size(g_ui_element_type_strings),
+    kNumUiElementTypes == std::size(g_ui_element_type_strings),
     "Mismatch between the kUiElementType enum and the corresponding array "
     "of strings.");
 
diff --git a/chrome/browser/vr/elements/ui_element_unittest.cc b/chrome/browser/vr/elements/ui_element_unittest.cc
index 3f48846..fb1ca62 100644
--- a/chrome/browser/vr/elements/ui_element_unittest.cc
+++ b/chrome/browser/vr/elements/ui_element_unittest.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "cc/animation/keyframe_model.h"
 #include "chrome/browser/vr/databinding/binding.h"
 #include "chrome/browser/vr/test/animation_utils.h"
@@ -343,7 +342,7 @@
       {gfx::PointF(-0.1f, -0.1f), false, false, false},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(i);
     EXPECT_EQ(test_cases[i].expected_rect,
               rect.LocalHitTest(test_cases[i].location));
@@ -379,7 +378,7 @@
       {{kAlmostOne, 0.5f}, true},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(i);
     EXPECT_EQ(test_cases[i].expected,
               rect.LocalHitTest(test_cases[i].location));
diff --git a/chrome/browser/vr/renderers/base_quad_renderer.cc b/chrome/browser/vr/renderers/base_quad_renderer.cc
index 5fbcdfc..f8d6879 100644
--- a/chrome/browser/vr/renderers/base_quad_renderer.cc
+++ b/chrome/browser/vr/renderers/base_quad_renderer.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/vr/renderers/base_quad_renderer.h"
 
-#include "base/cxx17_backports.h"
 #include "device/vr/vr_gl_util.h"
 #include "ui/gfx/geometry/transform.h"
 
@@ -52,17 +51,17 @@
   index_buffer_ = buffers[1];
 
   glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
-  glBufferData(GL_ARRAY_BUFFER, base::size(kQuadVertices) * sizeof(float),
+  glBufferData(GL_ARRAY_BUFFER, std::size(kQuadVertices) * sizeof(float),
                kQuadVertices, GL_STATIC_DRAW);
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
   glBufferData(GL_ELEMENT_ARRAY_BUFFER,
-               base::size(kQuadIndices) * sizeof(GLushort), kQuadIndices,
+               std::size(kQuadIndices) * sizeof(GLushort), kQuadIndices,
                GL_STATIC_DRAW);
 }
 
 int BaseQuadRenderer::NumQuadIndices() {
-  return base::size(kQuadIndices);
+  return std::size(kQuadIndices);
 }
 
 }  // namespace vr
diff --git a/chrome/browser/vr/renderers/textured_quad_renderer.cc b/chrome/browser/vr/renderers/textured_quad_renderer.cc
index dd39056..b0e5570 100644
--- a/chrome/browser/vr/renderers/textured_quad_renderer.cc
+++ b/chrome/browser/vr/renderers/textured_quad_renderer.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/vr/renderers/textured_quad_renderer.h"
 
-#include "base/cxx17_backports.h"
 #include "device/vr/vr_gl_util.h"
 #include "ui/gfx/geometry/transform.h"
 
@@ -321,7 +320,7 @@
       glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT,
                      VOID_OFFSET(kInnerRectOffset));
     } else {
-      glDrawElements(GL_TRIANGLES, base::size(kIndices), GL_UNSIGNED_SHORT, 0);
+      glDrawElements(GL_TRIANGLES, std::size(kIndices), GL_UNSIGNED_SHORT, 0);
     }
 
     quad_queue_.pop();
@@ -347,11 +346,11 @@
   index_buffer_ = buffers[1];
 
   glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
-  glBufferData(GL_ARRAY_BUFFER, base::size(kVertices) * sizeof(float),
-               kVertices, GL_STATIC_DRAW);
+  glBufferData(GL_ARRAY_BUFFER, std::size(kVertices) * sizeof(float), kVertices,
+               GL_STATIC_DRAW);
 
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
-  glBufferData(GL_ELEMENT_ARRAY_BUFFER, base::size(kIndices) * sizeof(GLushort),
+  glBufferData(GL_ELEMENT_ARRAY_BUFFER, std::size(kIndices) * sizeof(GLushort),
                kIndices, GL_STATIC_DRAW);
 }
 
@@ -372,7 +371,7 @@
 }
 
 int TexturedQuadRenderer::NumQuadIndices() {
-  return base::size(kIndices);
+  return std::size(kIndices);
 }
 
 }  // namespace vr
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 3f6f684..aed266e 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
@@ -577,6 +577,11 @@
   app->window_mode =
       GetDisplayMode(registrar().GetAppUserDisplayMode(web_app->app_id()));
 
+  const auto login_mode = registrar().GetAppRunOnOsLoginMode(web_app->app_id());
+  app->run_on_os_login =
+      apps::RunOnOsLogin(apps::ConvertMojomRunOnOsLoginModeToRunOnOsLoginMode(
+                             ConvertOsLoginModeToMojom(login_mode.value)),
+                         !login_mode.user_controllable);
   return app;
 }
 
diff --git a/chrome/browser/web_applications/isolated_app_browsertest.cc b/chrome/browser/web_applications/isolated_app_browsertest.cc
index 148ce9d..470fd4a 100644
--- a/chrome/browser/web_applications/isolated_app_browsertest.cc
+++ b/chrome/browser/web_applications/isolated_app_browsertest.cc
@@ -67,7 +67,7 @@
 std::string GetTestApplicationServerKey() {
   std::string application_server_key(
       kApplicationServerKey,
-      kApplicationServerKey + base::size(kApplicationServerKey));
+      kApplicationServerKey + std::size(kApplicationServerKey));
 
   return application_server_key;
 }
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index 58a4baa..0cccb73 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -990,9 +990,8 @@
 
   // Load a page which contains the same manifest content but at a new manifest
   // URL.
-  url::Replacements<char> replacements;
-  std::string query = "manifest=/banners/manifest_one_icon.json";
-  replacements.SetQuery(query.c_str(), url::Component(0, query.length()));
+  GURL::Replacements replacements;
+  replacements.SetQueryStr("manifest=/banners/manifest_one_icon.json");
   GURL app_url_with_new_manifest = GetAppURL().ReplaceComponents(replacements);
   EXPECT_EQ(GetResultAfterPageLoad(app_url_with_new_manifest),
             ManifestUpdateResult::kAppUpdated);
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut.cc b/chrome/browser/web_applications/os_integration/web_app_shortcut.cc
index 51bbc31..129e7981 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut.cc
@@ -57,7 +57,7 @@
 #if BUILDFLAG(IS_WIN)
   return IconUtil::kNumIconDimensions;
 #else
-  return base::size(kDesiredIconSizesForShortcut);
+  return std::size(kDesiredIconSizesForShortcut);
 #endif
 }
 
diff --git a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
index 2050d01..5295ca5 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut_mac.mm
@@ -952,7 +952,7 @@
 
   // Write the PkgInfo file.
   constexpr char kPkgInfoData[] = "APPL????";
-  constexpr size_t kPkgInfoDataSize = base::size(kPkgInfoData) - 1;
+  constexpr size_t kPkgInfoDataSize = std::size(kPkgInfoData) - 1;
   if (base::WriteFile(destination_contents_path.Append("PkgInfo"), kPkgInfoData,
                       kPkgInfoDataSize) != kPkgInfoDataSize) {
     RecordCreateShortcut(CreateShortcutResult::kFailToWritePkgInfoFile);
diff --git a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc
index 456e29d2..add9fdfc 100644
--- a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc
+++ b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc
@@ -122,7 +122,7 @@
 }
 
 base::span<const int> GetIconSizes() {
-  return base::span<const int>(kIconSizes, base::size(kIconSizes));
+  return base::span<const int>(kIconSizes, std::size(kIconSizes));
 }
 
 bool ContainsOneIconOfEachSize(
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 d39541e..4c13242f 100644
--- a/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc
+++ b/chrome/browser/web_applications/web_app_audio_focus_browsertest.cc
@@ -135,10 +135,8 @@
 
   // Navigate inside the PWA and make sure we keep the same group id.
   {
-    std::string new_query_string = "t=1";
-    url::Component new_query(0, new_query_string.length());
-    url::Replacements<char> replacements;
-    replacements.SetQuery(new_query_string.c_str(), new_query);
+    GURL::Replacements replacements;
+    replacements.SetQueryStr("t=1");
     GURL new_url =
         web_contents->GetLastCommittedURL().ReplaceComponents(replacements);
     ASSERT_TRUE(NavigateInRenderer(web_contents, new_url));
diff --git a/chrome/browser/web_applications/web_app_icon_generator_unittest.cc b/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
index f29d4a11..bca4745 100644
--- a/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
+++ b/chrome/browser/web_applications/web_app_icon_generator_unittest.cc
@@ -32,7 +32,7 @@
       icon_size::k128,
   };
   return std::set<int>(kIconSizesToGenerate,
-                       kIconSizesToGenerate + base::size(kIconSizesToGenerate));
+                       kIconSizesToGenerate + std::size(kIconSizesToGenerate));
 }
 
 void ValidateAllIconsWithURLsArePresent(
diff --git a/chrome/browser/win/conflicts/enumerate_shell_extensions_unittest.cc b/chrome/browser/win/conflicts/enumerate_shell_extensions_unittest.cc
index 3a31603..4879b3c 100644
--- a/chrome/browser/win/conflicts/enumerate_shell_extensions_unittest.cc
+++ b/chrome/browser/win/conflicts/enumerate_shell_extensions_unittest.cc
@@ -133,7 +133,7 @@
                           base::Unretained(&shell_extension_paths)));
 
   ASSERT_EQ(3u, shell_extension_paths.size());
-  for (size_t i = 0; i < base::size(kTestCases); i++) {
+  for (size_t i = 0; i < std::size(kTestCases); i++) {
     // The inefficiency is fine as long as the number of test cases stays small.
     EXPECT_TRUE(base::Contains(shell_extension_paths,
                                base::FilePath(kTestCases[i].path)));
@@ -192,7 +192,7 @@
                           base::Unretained(&shell_extension_paths)));
 
   ASSERT_EQ(5u, shell_extension_paths.size());
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     // The inefficiency is fine as long as the number of test cases stays small.
     EXPECT_TRUE(base::Contains(shell_extension_paths,
                                base::FilePath(kTestCases[i].path)));
diff --git a/chrome/browser/win/conflicts/module_blocklist_cache_util.cc b/chrome/browser/win/conflicts/module_blocklist_cache_util.cc
index cb92ae17..f9b7b09a 100644
--- a/chrome/browser/win/conflicts/module_blocklist_cache_util.cc
+++ b/chrome/browser/win/conflicts/module_blocklist_cache_util.cc
@@ -14,7 +14,6 @@
 
 #include "base/check.h"
 #include "base/containers/cxx20_erase.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -127,7 +126,7 @@
 
   base::MD5Digest read_md5_digest;
   if (!SafeRead(&file, reinterpret_cast<char*>(&read_md5_digest.a),
-                base::size(read_md5_digest.a))) {
+                std::size(read_md5_digest.a))) {
     return ReadResult::kFailReadMD5;
   }
 
@@ -268,10 +267,10 @@
         return module_list_filter.IsAllowlisted(
             base::StringPiece(
                 reinterpret_cast<const char*>(&module.basename_hash[0]),
-                base::size(module.basename_hash)),
+                std::size(module.basename_hash)),
             base::StringPiece(
                 reinterpret_cast<const char*>(&module.code_id_hash[0]),
-                base::size(module.code_id_hash)));
+                std::size(module.code_id_hash)));
       });
 }
 
diff --git a/chrome/browser/win/conflicts/module_blocklist_cache_util_unittest.cc b/chrome/browser/win/conflicts/module_blocklist_cache_util_unittest.cc
index 3336ab0..eaf8372 100644
--- a/chrome/browser/win/conflicts/module_blocklist_cache_util_unittest.cc
+++ b/chrome/browser/win/conflicts/module_blocklist_cache_util_unittest.cc
@@ -193,10 +193,10 @@
     allowlisted_modules_.emplace(
         base::StringPiece(
             reinterpret_cast<const char*>(&module.basename_hash[0]),
-            base::size(module.basename_hash)),
+            std::size(module.basename_hash)),
         base::StringPiece(
             reinterpret_cast<const char*>(&module.code_id_hash[0]),
-            base::size(module.basename_hash)));
+            std::size(module.basename_hash)));
   }
 
   // ModuleListFilter:
diff --git a/chrome/browser/win/conflicts/module_info_util_unittest.cc b/chrome/browser/win/conflicts/module_info_util_unittest.cc
index c1c5051f..8fa14e1 100644
--- a/chrome/browser/win/conflicts/module_info_util_unittest.cc
+++ b/chrome/browser/win/conflicts/module_info_util_unittest.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/base_paths.h"
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
@@ -115,7 +114,7 @@
       std::make_pair(u"c:\\foo\\bar", u"%x%"),
   };
 
-  for (size_t i = 0; i < base::size(kCollapsePathList); ++i) {
+  for (size_t i = 0; i < std::size(kCollapsePathList); ++i) {
     std::u16string test_case = kCollapsePathList[i].test_case;
     CollapseMatchingPrefixInPath(string_mapping, &test_case);
     EXPECT_EQ(kCollapsePathList[i].expected_result, test_case);
diff --git a/chrome/browser/win/conflicts/module_inspector_unittest.cc b/chrome/browser/win/conflicts/module_inspector_unittest.cc
index f5e61a6..ade712d 100644
--- a/chrome/browser/win/conflicts/module_inspector_unittest.cc
+++ b/chrome/browser/win/conflicts/module_inspector_unittest.cc
@@ -34,6 +34,11 @@
   void IsPinnedToTaskbar(IsPinnedToTaskbarCallback callback) override {}
   void UnpinShortcuts(const std::vector<base::FilePath>& shortcuts,
                       UnpinShortcutsCallback result_callback) override {}
+  void CreateOrUpdateShortcutLink(
+      const base::FilePath& shortcut_path,
+      const base::win::ShortcutProperties& properties,
+      base::win::ShortcutOperation operation,
+      CreateOrUpdateShortcutLinkCallback callback) override {}
 
   void CallExecuteSelectFile(ui::SelectFileDialog::Type type,
                              uint32_t owner,
diff --git a/chrome/browser/win/conflicts/third_party_metrics_recorder.cc b/chrome/browser/win/conflicts/third_party_metrics_recorder.cc
index 5b1aaf5..3d0258dd 100644
--- a/chrome/browser/win/conflicts/third_party_metrics_recorder.cc
+++ b/chrome/browser/win/conflicts/third_party_metrics_recorder.cc
@@ -130,7 +130,7 @@
       {"unsigned-modules-5", UnsignedModulesKey::Tag::kArray},
   };
 
-  if (current_key_index_ >= base::size(unsigned_modules_keys))
+  if (current_key_index_ >= std::size(unsigned_modules_keys))
     return;
 
   std::string module = base::WideToUTF8(module_basename);
@@ -147,7 +147,7 @@
   if (module_length > length_remaining) {
     current_value_.clear();
 
-    if (++current_key_index_ >= base::size(unsigned_modules_keys))
+    if (++current_key_index_ >= std::size(unsigned_modules_keys))
       return;
   }
 
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc
index 6bd3706..ac33ca55 100644
--- a/chrome/browser/win/jumplist.cc
+++ b/chrome/browser/win/jumplist.cc
@@ -12,7 +12,6 @@
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/path_service.h"
@@ -106,7 +105,7 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
   shell_link->GetCommandLine()->CopySwitchesFrom(command_line, kSwitchNames,
-                                                 base::size(kSwitchNames));
+                                                 std::size(kSwitchNames));
   if (!cmd_line_profile_dir.empty()) {
     shell_link->GetCommandLine()->AppendSwitchPath(switches::kProfileDirectory,
                                                    cmd_line_profile_dir);
diff --git a/chrome/browser/win/uninstallation_via_os_settings.cc b/chrome/browser/win/uninstallation_via_os_settings.cc
index 5de899a..4d0b295 100644
--- a/chrome/browser/win/uninstallation_via_os_settings.cc
+++ b/chrome/browser/win/uninstallation_via_os_settings.cc
@@ -8,7 +8,6 @@
 
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/win/registry.h"
 #include "base/win/windows_types.h"
@@ -58,9 +57,9 @@
   uninstall_reg_entry_key.WriteValue(L"ApplicationVersion", L"1.0");
 
   static constexpr wchar_t kDateFormat[] = L"yyyyyMMdd";
-  wchar_t date_str[base::size(kDateFormat)] = {};
+  wchar_t date_str[std::size(kDateFormat)] = {};
   int len = ::GetDateFormatW(LOCALE_INVARIANT, 0, nullptr, kDateFormat,
-                             date_str, base::size(date_str));
+                             date_str, std::size(date_str));
   if (len)
     uninstall_reg_entry_key.WriteValue(L"InstallDate", date_str);
 
diff --git a/chrome/browser/window_placement/DEPS b/chrome/browser/window_placement/DEPS
index a8ce4911..55832c74 100644
--- a/chrome/browser/window_placement/DEPS
+++ b/chrome/browser/window_placement/DEPS
@@ -5,4 +5,7 @@
   "window_placement_permission_context_browsertest\.cc": [
     "+ash/shell.h",
   ],
+  "window_placement_printing_interactive_uitest\.cc": [
+    "+ash/shell.h",
+  ],
 }
diff --git a/chrome/browser/window_placement/window_placement_printing_interactive_uitest.cc b/chrome/browser/window_placement/window_placement_printing_interactive_uitest.cc
new file mode 100644
index 0000000..8efceba
--- /dev/null
+++ b/chrome/browser/window_placement/window_placement_printing_interactive_uitest.cc
@@ -0,0 +1,135 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "build/chromeos_buildflags.h"
+#include "chrome/browser/printing/print_preview_dialog_controller.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/permissions/permission_request_manager.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "third_party/blink/public/common/features.h"
+#include "ui/display/screen_base.h"
+#include "ui/display/test/scoped_screen_override.h"
+#include "ui/display/test/test_screen.h"
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/shell.h"
+#include "ui/display/test/display_manager_test_api.h"  // nogncheck
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+class WindowPlacementTest : public InProcessBrowserTest {
+ public:
+  void SetUpOnMainThread() override {
+    // Window placement features are only available on secure contexts.
+    https_test_server_ = std::make_unique<net::EmbeddedTestServer>(
+        net::EmbeddedTestServer::TYPE_HTTPS);
+    https_test_server_->ServeFilesFromSourceDirectory(GetChromeTestDataDir());
+    ASSERT_TRUE(https_test_server_->Start());
+  }
+
+ protected:
+  std::unique_ptr<net::EmbeddedTestServer> https_test_server_;
+  base::test::ScopedFeatureList scoped_feature_list_{
+      blink::features::kWindowPlacement};
+};
+
+// TODO(crbug.com/1042990): Windows crashes static casting to ScreenWin.
+#if BUILDFLAG(IS_WIN)
+#define MAYBE_NoCrashOnEventsDuringHandlerPrint \
+  DISABLED_NoCrashOnEventsDuringHandlerPrint
+#else
+#define MAYBE_NoCrashOnEventsDuringHandlerPrint \
+  NoCrashOnEventsDuringHandlerPrint
+#endif
+// Test that screen change events occurring while an event handler is running
+// a nested event loop (i.e. via window.print()) do not cause a crash.
+// Regression test for crbug.com/1273841
+IN_PROC_BROWSER_TEST_F(WindowPlacementTest,
+                       MAYBE_NoCrashOnEventsDuringHandlerPrint) {
+  // Update the display configuration to mock display changes.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager())
+      .UpdateDisplay("0+0-803x600");
+#else
+  display::ScreenBase screen;
+  screen.display_list().AddDisplay({1, gfx::Rect(0, 0, 803, 600)},
+                                   display::DisplayList::Type::PRIMARY);
+  display::test::ScopedScreenOverride screen_override(&screen);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+  ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
+
+  // Navigate in a new tab to observe the test screen instance as needed.
+  const GURL url(https_test_server_->GetURL("/simple.html"));
+  ui_test_utils::NavigateToURLWithDisposition(
+      browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
+          ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
+
+  // Auto-accept the Window Placement permission request.
+  auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
+  permissions::PermissionRequestManager* permission_request_manager_tab =
+      permissions::PermissionRequestManager::FromWebContents(tab);
+  permission_request_manager_tab->set_auto_response_for_test(
+      permissions::PermissionRequestManager::ACCEPT_ALL);
+
+  // Add a currentscreenchange event handler that will freeze JS via print().
+  auto* script = R"(
+      function freezeJS(e) {
+        self.print();
+        screenDetails.removeEventListener('currentscreenchange', freezeJS);
+      }
+
+      let screenDetails;
+      self.getScreenDetails().then(s => {
+        screenDetails = s;
+        screenDetails.addEventListener('currentscreenchange', freezeJS);
+      });
+  )";
+  content::WebContentsAddedObserver web_contents_added_observer;
+  ASSERT_TRUE(EvalJs(tab, script).error.empty());
+
+  // Alter the display to trigger the currentscreenchange event and print().
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager())
+      .UpdateDisplay("0+0-807x600");
+#else
+  screen.display_list().UpdateDisplay({1, gfx::Rect(0, 0, 807, 600)},
+                                      display::DisplayList::Type::PRIMARY);
+  EXPECT_EQ(screen.display_list().displays().size(), 1u);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+  ASSERT_EQ(1, display::Screen::GetScreen()->GetNumDisplays());
+
+  content::WebContents* print_preview =
+      web_contents_added_observer.GetWebContents();
+  EXPECT_EQ(print_preview, printing::PrintPreviewDialogController::GetInstance()
+                               ->GetPrintPreviewForContents(tab));
+  content::AwaitDocumentOnLoadCompleted(print_preview);
+
+  // Add a second display while the print preview dialog is showing.
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  display::test::DisplayManagerTestApi(ash::Shell::Get()->display_manager())
+      .UpdateDisplay("0+0-807x600,1000+0-804x600");
+#else
+  screen.display_list().AddDisplay({2, gfx::Rect(1000, 0, 804, 600)},
+                                   display::DisplayList::Type::NOT_PRIMARY);
+  EXPECT_EQ(screen.display_list().displays().size(), 2u);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+  ASSERT_EQ(2, display::Screen::GetScreen()->GetNumDisplays());
+
+  // Cancel print to unfreeze the tab's JS and check that no crash occurred.
+  content::WebContentsDestroyedWatcher destroyed_watcher(print_preview);
+  // Note: This could be a browser_test if cancelling the print preview dialog
+  // was more broadly possible without simulating a key press.
+  // PrintViewManager::PrintPreviewDone() worked on Linux, but not Chrome OS.
+  EXPECT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_ESCAPE, false,
+                                              false, false, false));
+  destroyed_watcher.Wait();
+  ASSERT_FALSE(tab->IsCrashed());
+  EXPECT_EQ(true, EvalJs(tab, "true"));
+}
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index a114758..34dcea4 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1645768781-bb464cc52b278b12cc2abb848b19cebc75d215ed.profdata
+chrome-linux-main-1645854382-0ad3013dee8c48689470f401c9ae4eac73aca36b.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 515bee2..6d73f5c 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1645790211-0110073c69833eb15f293788b3addf72d7d467eb.profdata
+chrome-mac-arm-main-1645854382-c347d76ee094fc59bc0abf2e9235027639a6c205.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 365cbfe2..78a4eb79a 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1645747137-9ec32e48b5cc7eb5891c059f03441638585af5b1.profdata
+chrome-mac-main-1645854382-ca5bdf8165ed04431a205d087b8a1c9fc4069a38.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 696ee02..1522d330 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1645779392-17dbc3a8d1365a6bf7bcaa2c3f5c9d21d5b5469e.profdata
+chrome-win32-main-1645865513-417b67d5ec4b9eb841746463edfd3d55a91ca328.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 092928f..2c4d22b0 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1645790211-6309a201572799e1dea980224c96c604e4019e1a.profdata
+chrome-win64-main-1645854382-f9030c4d7de25f4c564afa1c0c034e0aa9c71ad6.profdata
diff --git a/chrome/child/delay_load_failure_hook.cc b/chrome/child/delay_load_failure_hook.cc
index 2eb757c..e0e622df 100644
--- a/chrome/child/delay_load_failure_hook.cc
+++ b/chrome/child/delay_load_failure_hook.cc
@@ -8,7 +8,6 @@
 #include <delayimp.h>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/strings/string_util.h"
 
@@ -20,7 +19,7 @@
 extern "C" FARPROC WINAPI DelayLoadFailureHook(unsigned reason,
                                                DelayLoadInfo* dll_info) {
   char dll_name[MAX_PATH];
-  base::strlcpy(dll_name, dll_info->szDll, base::size(dll_name));
+  base::strlcpy(dll_name, dll_info->szDll, std::size(dll_name));
   // It's not an error if "bthprops.cpl" fails to be loaded, there's a custom
   // exception handler in 'device/bluetooth/bluetooth_init_win.cc" that will
   // intercept the exception triggered by the delay load runtime. Returning 0
diff --git a/chrome/chrome_cleaner/chrome_utils/extensions_util.cc b/chrome/chrome_cleaner/chrome_utils/extensions_util.cc
index 229dff2..565d585 100644
--- a/chrome/chrome_cleaner/chrome_utils/extensions_util.cc
+++ b/chrome/chrome_cleaner/chrome_utils/extensions_util.cc
@@ -74,7 +74,7 @@
 void GetForcelistPoliciesForAccessMask(
     REGSAM access_mask,
     std::vector<ExtensionPolicyRegistryEntry>* policies) {
-  for (size_t i = 0; i < base::size(extension_forcelist_keys); ++i) {
+  for (size_t i = 0; i < std::size(extension_forcelist_keys); ++i) {
     base::win::RegistryValueIterator forcelist_it(
         extension_forcelist_keys[i].hkey, extension_forcelist_keys[i].path,
         access_mask);
@@ -142,7 +142,7 @@
     JsonParserAPI* json_parser,
     std::vector<ExtensionPolicyRegistryEntry>* policies,
     scoped_refptr<ParseTasksRemainingCounter> counter) {
-  for (size_t i = 0; i < base::size(extension_settings_keys); ++i) {
+  for (size_t i = 0; i < std::size(extension_settings_keys); ++i) {
     RegKeyPath key(extension_settings_keys[i].hkey,
                    extension_settings_keys[i].path, access_mask);
     std::wstring extension_settings;
diff --git a/chrome/chrome_cleaner/chrome_utils/extensions_util_unittest.cc b/chrome/chrome_cleaner/chrome_utils/extensions_util_unittest.cc
index 57420cf..9bd9fcf 100644
--- a/chrome/chrome_cleaner/chrome_utils/extensions_util_unittest.cc
+++ b/chrome/chrome_cleaner/chrome_utils/extensions_util_unittest.cc
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/base_paths_win.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
@@ -108,7 +107,7 @@
 
   const std::wstring expected_extension_ids[] = {kTestExtensionId1,
                                                  kTestExtensionId2};
-  ASSERT_EQ(base::size(expected_extension_ids), policies.size());
+  ASSERT_EQ(std::size(expected_extension_ids), policies.size());
   const std::wstring found_extension_ids[] = {policies[0].extension_id,
                                               policies[1].extension_id};
   EXPECT_THAT(expected_extension_ids,
@@ -212,7 +211,7 @@
 
   const std::wstring expected_extension_ids[] = {kTestExtensionId6,
                                                  kTestExtensionId7};
-  ASSERT_EQ(base::size(expected_extension_ids), policies.size());
+  ASSERT_EQ(std::size(expected_extension_ids), policies.size());
   const std::wstring found_extension_ids[] = {policies[0].extension_id,
                                               policies[1].extension_id};
   EXPECT_THAT(expected_extension_ids,
diff --git a/chrome/chrome_cleaner/components/reset_shortcuts_component.cc b/chrome/chrome_cleaner/components/reset_shortcuts_component.cc
index 19e74ac..2282df0 100644
--- a/chrome/chrome_cleaner/components/reset_shortcuts_component.cc
+++ b/chrome/chrome_cleaner/components/reset_shortcuts_component.cc
@@ -4,9 +4,8 @@
 
 #include "chrome/chrome_cleaner/components/reset_shortcuts_component.h"
 
-#include <windows.h>
-
 #include <stdint.h>
+#include <windows.h>
 
 #include <memory>
 #include <set>
@@ -17,7 +16,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -100,7 +98,7 @@
     };
     base::CommandLine desired_args(base::CommandLine::NO_PROGRAM);
     desired_args.CopySwitchesFrom(current_args, kept_switches,
-                                  base::size(kept_switches));
+                                  std::size(kept_switches));
     updated_properties.set_arguments(desired_args.GetArgumentsString());
     bool success = base::win::CreateOrUpdateShortcutLink(
         shortcut_path, updated_properties,
diff --git a/chrome/chrome_cleaner/components/system_report_component.cc b/chrome/chrome_cleaner/components/system_report_component.cc
index 3eaafb44..cb24eaec 100644
--- a/chrome/chrome_cleaner/components/system_report_component.cc
+++ b/chrome/chrome_cleaner/components/system_report_component.cc
@@ -20,7 +20,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -333,15 +332,15 @@
 
 void ReportRegistry(REGSAM access_mask) {
   // Report on startup keys/values.
-  ReportRegistryKeys(startup_registry_keys, base::size(startup_registry_keys),
+  ReportRegistryKeys(startup_registry_keys, std::size(startup_registry_keys),
                      access_mask, kHasFileInformation);
-  ReportRegistryValues(system_path_values, base::size(system_path_values),
+  ReportRegistryValues(system_path_values, std::size(system_path_values),
                        access_mask, kHasFileInformation);
-  ReportRegistryValues(system_values, base::size(system_values), access_mask,
+  ReportRegistryValues(system_values, std::size(system_values), access_mask,
                        kNoFileInformation);
 
   // Report on extension policy keys.
-  ReportRegistryKeys(extension_policy_keys, base::size(extension_policy_keys),
+  ReportRegistryKeys(extension_policy_keys, std::size(extension_policy_keys),
                      access_mask, kNoFileInformation);
   ReportAppInitDllsTargets(access_mask);
   ReportNameServer(access_mask);
@@ -369,7 +368,7 @@
       base::DIR_LOCAL_APP_DATA,    base::DIR_COMMON_APP_DATA,
   };
   std::set<base::FilePath> path_processed;
-  for (size_t path = 0; path < base::size(install_paths); ++path) {
+  for (size_t path = 0; path < std::size(install_paths); ++path) {
     base::FilePath install_path;
     bool success = base::PathService::Get(install_paths[path], &install_path);
     if (!success) {
@@ -438,13 +437,13 @@
                               base::CompareCase::INSENSITIVE_ASCII)) {
     // Remove the prefix "\??\" in front of the path.
     file_path = base::FilePath(
-        file_path.value().substr(base::size(kAbsolutePrefix) - 1));
+        file_path.value().substr(std::size(kAbsolutePrefix) - 1));
   } else if (base::StartsWith(file_path.value(), kSystemRootPrefix,
                               base::CompareCase::INSENSITIVE_ASCII)) {
     // Remove the prefix "\systemroot\" in front of the path. The path
     // will be resolved from the system folder.
     file_path = base::FilePath(
-        file_path.value().substr(base::size(kSystemRootPrefix) - 1));
+        file_path.value().substr(std::size(kSystemRootPrefix) - 1));
   }
 
   // For relative path, resolve them from %systemroot%.
diff --git a/chrome/chrome_cleaner/components/system_restore_point_component.cc b/chrome/chrome_cleaner/components/system_restore_point_component.cc
index c6c0f66..7422ba9 100644
--- a/chrome/chrome_cleaner/components/system_restore_point_component.cc
+++ b/chrome/chrome_cleaner/components/system_restore_point_component.cc
@@ -7,7 +7,6 @@
 #include <stdint.h>
 #include <windows.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/win/registry.h"
@@ -99,7 +98,7 @@
   restore_point_spec.dwRestorePtType = APPLICATION_INSTALL;
   restore_point_spec.llSequenceNumber = 0;
   wcsncpy(restore_point_spec.szDescription, product_fullname_.c_str(),
-          base::size(restore_point_spec.szDescription));
+          std::size(restore_point_spec.szDescription));
 
   if (set_restore_point_info_fn_(&restore_point_spec, &state_manager_status)) {
     sequence_number_ = state_manager_status.llSequenceNumber;
diff --git a/chrome/chrome_cleaner/crash/crashpad_crash_client.cc b/chrome/chrome_cleaner/crash/crashpad_crash_client.cc
index 016a9d5..0627dd8 100644
--- a/chrome/chrome_cleaner/crash/crashpad_crash_client.cc
+++ b/chrome/chrome_cleaner/crash/crashpad_crash_client.cc
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
@@ -57,8 +56,8 @@
   // characters long. Leave space for a NULL terminator character.
   static char buffer[11] = {};
 
-  _snprintf(buffer, base::size(buffer), "%u", value);
-  buffer[base::size(buffer) - 1] = '\0';
+  _snprintf(buffer, std::size(buffer), "%u", value);
+  buffer[std::size(buffer) - 1] = '\0';
   return buffer;
 }
 
@@ -73,8 +72,8 @@
   // terminator character.
   static char buffer[21] = {};
 
-  _snprintf(buffer, base::size(buffer), "%Iu", value);
-  buffer[base::size(buffer) - 1] = '\0';
+  _snprintf(buffer, std::size(buffer), "%Iu", value);
+  buffer[std::size(buffer) - 1] = '\0';
   return buffer;
 }
 
diff --git a/chrome/chrome_cleaner/engines/controllers/elevating_facade.cc b/chrome/chrome_cleaner/engines/controllers/elevating_facade.cc
index 27ce77c..843b94e3 100644
--- a/chrome/chrome_cleaner/engines/controllers/elevating_facade.cc
+++ b/chrome/chrome_cleaner/engines/controllers/elevating_facade.cc
@@ -12,7 +12,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
 #include "base/strings/string_number_conversions.h"
@@ -46,16 +45,16 @@
 
   // Ask for just enough of the class name to determine if it begins with
   // |kChromeWindowClassPrefix|.
-  wchar_t window_class_prefix[base::size(kChromeWindowClassPrefix)];
+  wchar_t window_class_prefix[std::size(kChromeWindowClassPrefix)];
   int class_name_length = ::GetClassName(window, window_class_prefix,
-                                         base::size(window_class_prefix));
+                                         std::size(window_class_prefix));
   if (class_name_length == 0)
     return false;
 
   return base::EqualsCaseInsensitiveASCII(
       base::WStringPiece(window_class_prefix, class_name_length),
       base::WStringPiece(kChromeWindowClassPrefix,
-                         base::size(kChromeWindowClassPrefix) - 1));
+                         std::size(kChromeWindowClassPrefix) - 1));
 }
 
 // Returns a handle to the foreground window if it is a Chrome window, otherwise
diff --git a/chrome/chrome_cleaner/http/error_utils.cc b/chrome/chrome_cleaner/http/error_utils.cc
index d10eaf8..a9d5c9f 100644
--- a/chrome/chrome_cleaner/http/error_utils.cc
+++ b/chrome/chrome_cleaner/http/error_utils.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/win/atl.h"
 #include "base/win/shlwapi.h"
@@ -20,7 +19,7 @@
   const DWORD kFlags =
       FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
   char error_text[4096] = {'\0'};
-  ::FormatMessageA(kFlags, 0, hr.hr_, 0, error_text, base::size(error_text),
+  ::FormatMessageA(kFlags, 0, hr.hr_, 0, error_text, std::size(error_text),
                    NULL);
   std::string error(error_text);
   base::TrimWhitespaceASCII(error, base::TRIM_ALL, &error);
@@ -35,7 +34,7 @@
   const DWORD kFlags =
       FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
   char error_text[4096] = {'\0'};
-  ::FormatMessageA(kFlags, 0, we.we_, 0, error_text, base::size(error_text),
+  ::FormatMessageA(kFlags, 0, we.we_, 0, error_text, std::size(error_text),
                    NULL);
   std::string error(error_text);
   base::TrimWhitespaceASCII(error, base::TRIM_ALL, &error);
diff --git a/chrome/chrome_cleaner/http/internet_helpers_unittest.cc b/chrome/chrome_cleaner/http/internet_helpers_unittest.cc
index b8a9880..3dcd3862 100644
--- a/chrome/chrome_cleaner/http/internet_helpers_unittest.cc
+++ b/chrome/chrome_cleaner/http/internet_helpers_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/chrome_cleaner/http/internet_unittest_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -43,7 +42,7 @@
       {L"text/html; boundary=WebKit-ada-df-dsf-adsfadsfs", L"text/html", L"",
        false, L"WebKit-ada-df-dsf-adsfadsfs"},
   };
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     std::wstring mime_type;
     std::wstring charset;
     bool had_charset = false;
@@ -71,7 +70,7 @@
       {L"https://example.com:9999/", L"https", L"example.com", 9999, L"/"},
       {L"http://example.com/a/b/c", L"http", L"example.com", 80, L"/a/b/c"},
   };
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     std::wstring scheme, host, path;
     uint16_t port = 0;
     EXPECT_TRUE(DecomposeUrl(tests[i].url, &scheme, &host, &port, &path))
@@ -90,7 +89,7 @@
       L"/foo/bar", L"example.com:80",    L"http://",
       L"http:",    L"http:/example.com", L"http:example.com"};
 
-  for (size_t i = 0; i < base::size(invalid_urls); ++i) {
+  for (size_t i = 0; i < std::size(invalid_urls); ++i) {
     std::wstring scheme, host, path;
     uint16_t port = 0;
     EXPECT_FALSE(DecomposeUrl(invalid_urls[i], &scheme, &host, &port, &path))
diff --git a/chrome/chrome_cleaner/logging/safe_browsing_reporter.cc b/chrome/chrome_cleaner/logging/safe_browsing_reporter.cc
index 4cfd720..6d5cd5c3 100644
--- a/chrome/chrome_cleaner/logging/safe_browsing_reporter.cc
+++ b/chrome/chrome_cleaner/logging/safe_browsing_reporter.cc
@@ -15,7 +15,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
@@ -57,7 +56,7 @@
   std::string response_data;
   while (true) {
     char buffer[8192] = {};
-    uint32_t count = static_cast<uint32_t>(base::size(buffer));
+    uint32_t count = static_cast<uint32_t>(std::size(buffer));
     if (!http_response->ReadData(buffer, &count)) {
       LOG(ERROR) << "ReadData failed";
       break;
diff --git a/chrome/chrome_cleaner/os/disk_util.cc b/chrome/chrome_cleaner/os/disk_util.cc
index 22c0afd..e0d47e83 100644
--- a/chrome/chrome_cleaner/os/disk_util.cc
+++ b/chrome/chrome_cleaner/os/disk_util.cc
@@ -619,7 +619,7 @@
 
   for (int i = 0; i < num_service_providers; ++i) {
     wchar_t path[MAX_PATH];
-    int path_length = base::size(path);
+    int path_length = std::size(path);
     if (0 == lsp_api.GetProviderPath(&service_providers[i].ProviderId, path,
                                      &path_length, &error)) {
       std::pair<LSPPathToGUIDs::iterator, bool> inserted =
@@ -645,7 +645,7 @@
       L"%SystemRoot%\\System32\\rundll32.exe";
   wchar_t rundll32[MAX_PATH] = {};
   DWORD size =
-      ExpandEnvironmentStrings(kRunDll32Path, rundll32, base::size(rundll32));
+      ExpandEnvironmentStrings(kRunDll32Path, rundll32, std::size(rundll32));
   if (!size || size >= MAX_PATH)
     return false;
 
@@ -824,7 +824,7 @@
 
   static const char kIdentifier[] = "[ZoneTransfer]\r\nZoneId=0\r\n";
   // Don't include trailing null in data written.
-  static const DWORD kIdentifierSize = base::size(kIdentifier) - 1;
+  static const DWORD kIdentifierSize = std::size(kIdentifier) - 1;
   DWORD written = 0;
   BOOL result =
       WriteFile(file, kIdentifier, kIdentifierSize, &written, nullptr);
diff --git a/chrome/chrome_cleaner/os/disk_util_unittest.cc b/chrome/chrome_cleaner/os/disk_util_unittest.cc
index 3a2c028..30a4953 100644
--- a/chrome/chrome_cleaner/os/disk_util_unittest.cc
+++ b/chrome/chrome_cleaner/os/disk_util_unittest.cc
@@ -671,7 +671,7 @@
       {10000,
        "5B92F844F0ED521B75688F4B6FF58E127711709613589EB6EC88FDFBBDC7DC63"}};
 
-  for (size_t offset = 0; offset < base::size(digests); ++offset) {
+  for (size_t offset = 0; offset < std::size(digests); ++offset) {
     DigestInfo* info = &digests[offset];
     DCHECK(info);
 
diff --git a/chrome/chrome_cleaner/os/registry_util_unittest.cc b/chrome/chrome_cleaner/os/registry_util_unittest.cc
index 687c744c..87c02dc 100644
--- a/chrome/chrome_cleaner/os/registry_util_unittest.cc
+++ b/chrome/chrome_cleaner/os/registry_util_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/test_reg_util_win.h"
 #include "chrome/chrome_cleaner/os/system_util.h"
@@ -576,7 +575,7 @@
 }
 
 TEST(RegistryUtilTests, GetRegistryValueAsStringRegularString) {
-  std::wstring input_value(kUnicodeValue, base::size(kUnicodeValue) - 1);
+  std::wstring input_value(kUnicodeValue, std::size(kUnicodeValue) - 1);
   std::wstring output_value;
 
   GetRegistryValueAsString(input_value.c_str(),
@@ -609,7 +608,7 @@
   std::wstring output_value;
 
   GetRegistryValueAsString(reinterpret_cast<const wchar_t*>(kBytesValue),
-                           base::size(kBytesValue), REG_BINARY, &output_value);
+                           std::size(kBytesValue), REG_BINARY, &output_value);
 
   EXPECT_EQ(kConvertedBytesValue, output_value);
 }
diff --git a/chrome/chrome_cleaner/os/system_util_cleaner.cc b/chrome/chrome_cleaner/os/system_util_cleaner.cc
index 47ecf65..6133011 100644
--- a/chrome/chrome_cleaner/os/system_util_cleaner.cc
+++ b/chrome/chrome_cleaner/os/system_util_cleaner.cc
@@ -17,7 +17,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/process/process_info.h"
@@ -434,8 +433,8 @@
                                       SECURITY_DESCRIPTOR_REVISION))
     return false;
 
-  DCHECK_EQ(kSidCount, base::size(sids));
-  DCHECK_EQ(kSidCount, base::size(sid_types));
+  DCHECK_EQ(kSidCount, std::size(sids));
+  DCHECK_EQ(kSidCount, std::size(sid_types));
   for (size_t i = 0; i < kSidCount; ++i) {
     DWORD sid_bytes = sizeof(sids[i]);
     if (!::CreateWellKnownSid(sid_types[i], nullptr, sids[i], &sid_bytes))
@@ -446,8 +445,8 @@
   // the access permissions for your application. COM_RIGHTS_EXECUTE and
   // COM_RIGHTS_EXECUTE_LOCAL are the minimum access rights required.
   EXPLICIT_ACCESS explicit_access[kSidCount] = {};
-  DCHECK_EQ(kSidCount, base::size(sids));
-  DCHECK_EQ(kSidCount, base::size(explicit_access));
+  DCHECK_EQ(kSidCount, std::size(sids));
+  DCHECK_EQ(kSidCount, std::size(explicit_access));
   for (size_t i = 0; i < kSidCount; ++i) {
     explicit_access[i].grfAccessPermissions =
         COM_RIGHTS_EXECUTE | COM_RIGHTS_EXECUTE_LOCAL;
@@ -463,7 +462,7 @@
   // Create an access control list (ACL) using this ACE list, if this succeeds
   // make sure to ::LocalFree(acl).
   ACL* acl = nullptr;
-  DWORD acl_result = ::SetEntriesInAcl(base::size(explicit_access),
+  DWORD acl_result = ::SetEntriesInAcl(std::size(explicit_access),
                                        explicit_access, nullptr, &acl);
   if (acl_result != ERROR_SUCCESS || acl == nullptr)
     return false;
@@ -529,7 +528,7 @@
   ::BuildTrusteeWithSidW(&explicit_access[0].Trustee, admin_sid->GetPSID());
 
   PACL dacl_ptr = nullptr;
-  if (::SetEntriesInAcl(base::size(explicit_access), explicit_access,
+  if (::SetEntriesInAcl(std::size(explicit_access), explicit_access,
                         /*OldAcl=*/nullptr, &dacl_ptr) != ERROR_SUCCESS) {
     LOG(ERROR) << "Failed to create DACL for quarantine folder.";
     return false;
diff --git a/chrome/chrome_cleaner/pup_data/pup_data.cc b/chrome/chrome_cleaner/pup_data/pup_data.cc
index ed05108..3b114d3 100644
--- a/chrome/chrome_cleaner/pup_data/pup_data.cc
+++ b/chrome/chrome_cleaner/pup_data/pup_data.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/strings/string_piece.h"
 #include "chrome/chrome_cleaner/proto/shared_pup_enums.pb.h"
@@ -30,10 +29,10 @@
 // static
 const wchar_t PUPData::kCommaDelimiter[] = L",";
 const size_t PUPData::kCommaDelimiterLength =
-    base::size(PUPData::kCommaDelimiter) - 1;
+    std::size(PUPData::kCommaDelimiter) - 1;
 const wchar_t PUPData::kCommonDelimiters[] = L" ,\0";
 const size_t PUPData::kCommonDelimitersLength =
-    base::size(PUPData::kCommonDelimiters) - 1;
+    std::size(PUPData::kCommonDelimiters) - 1;
 
 // The escape character used for registry key name and value is an unused
 // unicode character (see: http://en.wikipedia.org/wiki/Private_Use_Areas).
diff --git a/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc b/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
index 7132ba5..915425bc 100644
--- a/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
+++ b/chrome/chrome_cleaner/scanner/matcher_util_unittest.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/path_service.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
@@ -102,15 +101,15 @@
   // Hash: BD283E41A3672B6BDAA574F8BD7176F8BCA95BD81383CDE32AA6D78B1DB0E371.
   EXPECT_TRUE(IsKnownFileByDigest(file_path1, signature_matcher.get(),
                                   kKnownContentDigests,
-                                  base::size(kKnownContentDigests)));
+                                  std::size(kKnownContentDigests)));
   // Hash: not present.
   EXPECT_FALSE(IsKnownFileByDigest(file_path2, signature_matcher.get(),
                                    kKnownContentDigests,
-                                   base::size(kKnownContentDigests)));
+                                   std::size(kKnownContentDigests)));
   // The file doesn't exist.
   EXPECT_FALSE(IsKnownFileByDigest(file_path3, signature_matcher.get(),
                                    kKnownContentDigests,
-                                   base::size(kKnownContentDigests)));
+                                   std::size(kKnownContentDigests)));
 }
 
 TEST(MatcherUtilTest, IsKnownFileByDigestInfo) {
@@ -131,11 +130,11 @@
   // Search BD283E41A3672B6BDAA574F8BD7176F8BCA95BD81383CDE32AA6D78B1DB0E371.
   EXPECT_TRUE(IsKnownFileByDigestInfo(file_path1, signature_matcher.get(),
                                       kFileContentDigestInfos,
-                                      base::size(kFileContentDigestInfos)));
+                                      std::size(kFileContentDigestInfos)));
   // Search 82E0B92772BC0DA59AAB0B9231AA006FB37B4F99EC3E853C5A62786A1C7215BD.
   EXPECT_TRUE(IsKnownFileByDigestInfo(file_path2, signature_matcher.get(),
                                       kFileContentDigestInfos,
-                                      base::size(kFileContentDigestInfos)));
+                                      std::size(kFileContentDigestInfos)));
 
   // Replace the content of file_path2 with a content of the same size, it
   // must no longer match.
@@ -143,16 +142,16 @@
   CreateFileWithContent(file_path2, kFileContent4, sizeof(kFileContent4));
   EXPECT_FALSE(IsKnownFileByDigestInfo(file_path2, signature_matcher.get(),
                                        kFileContentDigestInfos,
-                                       base::size(kFileContentDigestInfos)));
+                                       std::size(kFileContentDigestInfos)));
 
   // The digest of |file_path3| is not in the array.
   EXPECT_FALSE(IsKnownFileByDigestInfo(file_path3, signature_matcher.get(),
                                        kFileContentDigestInfos,
-                                       base::size(kFileContentDigestInfos)));
+                                       std::size(kFileContentDigestInfos)));
   // The |file_path4| doesn't exist.
   EXPECT_FALSE(IsKnownFileByDigestInfo(file_path4, signature_matcher.get(),
                                        kFileContentDigestInfos,
-                                       base::size(kFileContentDigestInfos)));
+                                       std::size(kFileContentDigestInfos)));
 }
 
 TEST(MatcherUtilTest, IsKnownFileByOriginalFilename) {
@@ -169,14 +168,14 @@
       normalized_temp_dir_path.Append(kFileName1));
   EXPECT_FALSE(IsKnownFileByOriginalFilename(
       nonexistent_file_path, &signature_matcher, kKnownOriginalFilenames,
-      base::size(kKnownOriginalFilenames)));
+      std::size(kKnownOriginalFilenames)));
 
   // An existing file without version information should not be recognized.
   base::FilePath file_path2(normalized_temp_dir_path.Append(kFileName2));
   CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
   EXPECT_FALSE(IsKnownFileByOriginalFilename(
       file_path2, &signature_matcher, kKnownOriginalFilenames,
-      base::size(kKnownOriginalFilenames)));
+      std::size(kKnownOriginalFilenames)));
 
   // A file with version information but not in the array should not be
   // recognized.
@@ -189,7 +188,7 @@
   CreateFileWithContent(file_path3, kFileContent, sizeof(kFileContent));
   EXPECT_FALSE(IsKnownFileByOriginalFilename(
       file_path3, &signature_matcher, kKnownOriginalFilenames,
-      base::size(kKnownOriginalFilenames)));
+      std::size(kKnownOriginalFilenames)));
 
   // A file with version information present in the array should be recognized.
   base::FilePath file_path4(normalized_temp_dir_path.Append(kFileName4));
@@ -201,7 +200,7 @@
   CreateFileWithContent(file_path4, kFileContent, sizeof(kFileContent));
   EXPECT_TRUE(IsKnownFileByOriginalFilename(
       file_path4, &signature_matcher, kKnownOriginalFilenames,
-      base::size(kKnownOriginalFilenames)));
+      std::size(kKnownOriginalFilenames)));
 }
 
 TEST(MatcherUtilTest, IsKnownFileByCompanyName) {
@@ -218,14 +217,14 @@
       normalized_temp_dir_path.Append(kFileName1));
   EXPECT_FALSE(IsKnownFileByCompanyName(nonexistent_file_path,
                                         &signature_matcher, kKnownCompanyNames,
-                                        base::size(kKnownCompanyNames)));
+                                        std::size(kKnownCompanyNames)));
 
   // An existing file without version information should not be recognized.
   base::FilePath file_path2(normalized_temp_dir_path.Append(kFileName2));
   CreateFileWithContent(file_path2, kFileContent, sizeof(kFileContent));
   EXPECT_FALSE(IsKnownFileByCompanyName(file_path2, &signature_matcher,
                                         kKnownCompanyNames,
-                                        base::size(kKnownCompanyNames)));
+                                        std::size(kKnownCompanyNames)));
 
   // A file with version information but not in the array should not be
   // recognized.
@@ -238,7 +237,7 @@
   CreateFileWithContent(file_path3, kFileContent, sizeof(kFileContent));
   EXPECT_FALSE(IsKnownFileByCompanyName(file_path3, &signature_matcher,
                                         kKnownCompanyNames,
-                                        base::size(kKnownCompanyNames)));
+                                        std::size(kKnownCompanyNames)));
 
   // A file with version information present in the array should be recognized.
   base::FilePath file_path4(normalized_temp_dir_path.Append(kFileName4));
@@ -250,7 +249,7 @@
   CreateFileWithContent(file_path4, kFileContent, sizeof(kFileContent));
   EXPECT_TRUE(IsKnownFileByCompanyName(file_path4, &signature_matcher,
                                        kKnownCompanyNames,
-                                       base::size(kKnownCompanyNames)));
+                                       std::size(kKnownCompanyNames)));
 }
 
 }  // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/test/reboot_deletion_helper.cc b/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
index e0e9c1e2..9a4ff7f 100644
--- a/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
+++ b/chrome/chrome_cleaner/test/reboot_deletion_helper.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/win/registry.h"
@@ -290,7 +289,7 @@
 
   // The pending moves format needs a null entry at the end which consists of
   // two MULTISZ empty string.
-  std::wstring last_entry(kDoubleNullEntry, base::size(kDoubleNullEntry) - 1);
+  std::wstring last_entry(kDoubleNullEntry, std::size(kDoubleNullEntry) - 1);
   buffer = buffer + last_entry;
 
   // Write back the serialized values into the registry key.
diff --git a/chrome/chrome_elf/chrome_elf_test_stubs.cc b/chrome/chrome_elf/chrome_elf_test_stubs.cc
index f8b3d95..9ae7a78 100644
--- a/chrome/chrome_elf/chrome_elf_test_stubs.cc
+++ b/chrome/chrome_elf/chrome_elf_test_stubs.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/path_service.h"
@@ -69,11 +68,11 @@
 
   // Each entry shares the module path for convenience.
   static constexpr char kModulePath[] = "C:\\foo\\bar\\module.dll";
-  static constexpr uint32_t kModulePathLength = base::size(kModulePath) - 1;
+  static constexpr uint32_t kModulePathLength = std::size(kModulePath) - 1;
 
   if (log_remaining) {
     *log_remaining = third_party_dlls::GetLogEntrySize(kModulePathLength) *
-                     base::size(kTestLogEntries);
+                     std::size(kTestLogEntries);
   }
 
   uint8_t* tracker = buffer;
diff --git a/chrome/chrome_elf/nt_registry/nt_registry_unittest.cc b/chrome/chrome_elf/nt_registry/nt_registry_unittest.cc
index d46cad9b..5bfe4a7f 100644
--- a/chrome/chrome_elf/nt_registry/nt_registry_unittest.cc
+++ b/chrome/chrome_elf/nt_registry/nt_registry_unittest.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/test/test_reg_util_win.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -629,7 +628,7 @@
     ASSERT_TRUE(nt::QueryRegSubkey(key_handle, i, &subkey_name));
 
     bool found = false;
-    for (size_t index = 0; index < base::size(check_names); index++) {
+    for (size_t index = 0; index < std::size(check_names); index++) {
       if (0 == subkey_name.compare(check_names[index])) {
         found = true;
         break;
diff --git a/chrome/chrome_elf/third_party_dlls/logs_unittest.cc b/chrome/chrome_elf/third_party_dlls/logs_unittest.cc
index 8d7f17e..6e91c2d 100644
--- a/chrome/chrome_elf/third_party_dlls/logs_unittest.cc
+++ b/chrome/chrome_elf/third_party_dlls/logs_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
 #include "chrome/chrome_elf/sha1/sha1.h"
@@ -39,21 +38,21 @@
 };
 
 // Be sure to test the padding/alignment issues well here.
-const std::string kTestPaths[] = {
+const char* const kTestPaths[] = {
     "1", "123", "1234", "12345", "123456", "1234567",
 };
 
 static_assert(
-    base::size(kTestLogs) == base::size(kTestPaths),
+    std::size(kTestLogs) == std::size(kTestPaths),
     "Some tests currently expect these two arrays to be the same size.");
 
 // Ensure |buffer_size| passed in is the actual bytes written by DrainLog().
 void VerifyBuffer(uint8_t* buffer, uint32_t buffer_size) {
   uint32_t total_logs = 0;
   size_t index = 0;
-  size_t array_size = base::size(kTestLogs);
+  size_t array_size = std::size(kTestLogs);
 
-  // Verify against kTestLogs/kTestPaths.  Expect 2 * base::size(kTestLogs)
+  // Verify against kTestLogs/kTestPaths.  Expect 2 * std::size(kTestLogs)
   // entries: first half are "blocked", second half are "allowed".
   LogEntry* entry = nullptr;
   uint8_t* tracker = buffer;
@@ -64,7 +63,7 @@
     EXPECT_EQ(entry->time_date_stamp, kTestLogs[index].time_date_stamp);
 
     if (entry->path_len)
-      EXPECT_STREQ(entry->path, kTestPaths[index].c_str());
+      EXPECT_STREQ(entry->path, kTestPaths[index]);
 
     ++total_logs;
     tracker += GetLogEntrySize(entry->path_len);
@@ -125,7 +124,7 @@
   // Init.
   ASSERT_EQ(InitLogs(), ThirdPartyStatus::kSuccess);
 
-  for (size_t i = 0; i < base::size(kTestLogs); ++i) {
+  for (size_t i = 0; i < std::size(kTestLogs); ++i) {
     // Add some blocked entries.
     LogLoadAttempt(LogType::kBlocked, kTestLogs[i].image_size,
                    kTestLogs[i].time_date_stamp, std::string());
@@ -161,7 +160,7 @@
 
   // Set up the required arguments for the test thread.
   NotificationHandlerArguments handler_data;
-  handler_data.logs_expected = base::size(kTestLogs);
+  handler_data.logs_expected = std::size(kTestLogs);
   handler_data.notification_event = std::make_unique<base::WaitableEvent>(
       base::WaitableEvent::ResetPolicy::AUTOMATIC,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -194,7 +193,7 @@
   // Init.
   ASSERT_EQ(InitLogs(), ThirdPartyStatus::kSuccess);
 
-  for (size_t i = 0; i < base::size(kTestLogs); ++i) {
+  for (size_t i = 0; i < std::size(kTestLogs); ++i) {
     // Add some blocked entries.
     LogLoadAttempt(LogType::kBlocked, kTestLogs[i].image_size,
                    kTestLogs[i].time_date_stamp, kTestPaths[i]);
@@ -215,11 +214,11 @@
   EXPECT_EQ(remaining_log, uint32_t{0});
 
   // Validate that all of the logs have been drained.
-  EXPECT_EQ(GetLogCount(&buffer[0], bytes_written), base::size(kTestLogs) * 2);
+  EXPECT_EQ(GetLogCount(&buffer[0], bytes_written), std::size(kTestLogs) * 2);
 
   // Now the real test.  Add the same log entries again, and expect that the
   // blocked logs will NOT be re-added and drained this time.
-  for (size_t i = 0; i < base::size(kTestLogs); ++i) {
+  for (size_t i = 0; i < std::size(kTestLogs); ++i) {
     // Add some blocked entries.
     LogLoadAttempt(LogType::kBlocked, kTestLogs[i].image_size,
                    kTestLogs[i].time_date_stamp, kTestPaths[i]);
@@ -240,7 +239,7 @@
   EXPECT_EQ(remaining_log, uint32_t{0});
 
   // Validate that only half of the logs have been drained.
-  EXPECT_EQ(GetLogCount(&buffer[0], bytes_written), base::size(kTestLogs));
+  EXPECT_EQ(GetLogCount(&buffer[0], bytes_written), std::size(kTestLogs));
 
   DeinitLogs();
 }
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
index a25adac..70720b70 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
@@ -34,7 +34,7 @@
        {/*manufacturer=*/"HP", /*pwa_origin=*/"*://www.google.com/*"}},
       {/*extension_id=*/"alnedpmllcfpgldkagbfbjkloonjlfjb",
        {/*manufacturer=*/"HP",
-        /*pwa_origin=*/"*://hpcs-appschr.hpcloud.hp.com/*"}}};
+        /*pwa_origin=*/"https://hpcs-appschr.hpcloud.hp.com/*"}}};
 
   return kExtensionIdToExtensionInfoMap;
 }
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
index 9f33ffc..4722008f 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
@@ -28,7 +28,7 @@
   const auto extension_info =
       chromeos::GetChromeOSExtensionInfoForId(hp_extension_id);
   EXPECT_EQ("HP", extension_info.manufacturer);
-  EXPECT_EQ("*://hpcs-appschr.hpcloud.hp.com/*", extension_info.pwa_origin);
+  EXPECT_EQ("https://hpcs-appschr.hpcloud.hp.com/*", extension_info.pwa_origin);
 }
 
 TEST(ChromeOSSystemExtensionInfo, PwaOriginOverride) {
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index f6850e85..3a954d5 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -6,7 +6,6 @@
 
 #include "base/base_switches.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -100,7 +99,7 @@
     return false;
   size_t end = flag.find("=");
   size_t len = (end == std::string::npos) ? flag.length() - 2 : end - 2;
-  for (size_t i = 0; i < base::size(kIgnoreSwitches); ++i) {
+  for (size_t i = 0; i < std::size(kIgnoreSwitches); ++i) {
     if (flag.compare(2, len, kIgnoreSwitches[i]) == 0)
       return true;
   }
@@ -135,7 +134,7 @@
   };
 
   auto it = extensions.begin();
-  for (size_t i = 0; i < base::size(extension_ids); ++i) {
+  for (size_t i = 0; i < std::size(extension_ids); ++i) {
     if (it == extensions.end()) {
       extension_ids[i].Clear();
     } else {
diff --git a/chrome/common/extensions/api/common_extension_api_unittest.cc b/chrome/common/extensions/api/common_extension_api_unittest.cc
index 699dc43e..4a6d573 100644
--- a/chrome/common/extensions/api/common_extension_api_unittest.cc
+++ b/chrome/common/extensions/api/common_extension_api_unittest.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/common/extension_api.h"
-
 #include <stddef.h>
 
 #include <memory>
@@ -11,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/raw_ptr.h"
@@ -27,6 +24,7 @@
 #include "chrome/common/extensions/extension_features_unittest.h"
 #include "extensions/common/api/extension_action/action_info.h"
 #include "extensions/common/extension.h"
+#include "extensions/common/extension_api.h"
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/features/feature_session_type.h"
 #include "extensions/common/features/simple_feature.h"
@@ -100,7 +98,7 @@
     { &empty_instance, false }
   };
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     EXPECT_EQ(test_data[i].expect_populated,
               test_data[i].api->GetSchema("bookmarks.create") != nullptr);
   }
@@ -118,7 +116,7 @@
                    {"foo:bar", "foo", "bar"},
                    {"foo:bar.baz", "foo", "bar.baz"}};
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     std::string feature_type;
     std::string feature_name;
     ExtensionAPI::SplitDependencyName(
@@ -225,7 +223,7 @@
   FeatureProvider api_feature_provider;
   AddUnittestAPIFeatures(&api_feature_provider);
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     TestExtensionAPI api;
     api.RegisterDependencyProvider("api", &api_feature_provider);
     for (auto* key : kTestFeatures)
@@ -363,7 +361,7 @@
   FeatureProvider api_feature_provider;
   AddUnittestAPIFeatures(&api_feature_provider);
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     TestExtensionAPI api;
     api.RegisterDependencyProvider("api", &api_feature_provider);
     for (auto* key : kTestFeatures)
@@ -804,7 +802,7 @@
 
   std::unique_ptr<ExtensionAPI> api(
       ExtensionAPI::CreateWithDefaultConfiguration());
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     std::string child_name;
     std::string api_name = api->GetAPINameFromFullName(test_data[i].input,
                                                        &child_name);
@@ -828,7 +826,7 @@
     // TODO(aa): More stuff to test over time.
   } test_data[] = {{browser_action}, {browser_action_set_title}};
 
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     const SimpleFeature* feature = test_data[i].feature;
     ASSERT_TRUE(feature) << i;
 
@@ -982,7 +980,7 @@
       ExtensionAPI::CreateWithDefaultConfiguration());
   scoped_refptr<const Extension> extension = ExtensionBuilder("Test").Build();
 
-  for (size_t i = 0; i < base::size(kTests); ++i) {
+  for (size_t i = 0; i < std::size(kTests); ++i) {
     EXPECT_EQ(
         kTests[i].expect_success,
         extension_api
diff --git a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler_manifest_unittest.cc b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler_manifest_unittest.cc
index a116f5e..395b26ce 100644
--- a/chrome/common/extensions/api/file_browser_handlers/file_browser_handler_manifest_unittest.cc
+++ b/chrome/common/extensions/api/file_browser_handlers/file_browser_handler_manifest_unittest.cc
@@ -5,7 +5,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "chrome/common/extensions/api/file_browser_handlers/file_browser_handler.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
@@ -96,7 +95,7 @@
       Testcase("filebrowser_invalid_file_filters_url.json",
                extensions::ErrorUtils::FormatErrorMessage(
                    errors::kInvalidURLPatternError, "http:*.html"))};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
   RunTestcase(Testcase("filebrowser_missing_permission.json",
                        errors::kInvalidFileBrowserHandlerMissingPermission),
               EXPECT_TYPE_WARNING);
diff --git a/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc b/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc
index 355b75b6..b123fb75 100644
--- a/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc
+++ b/chrome/common/extensions/api/speech/tts_engine_manifest_handler_unittest.cc
@@ -56,7 +56,7 @@
       Testcase("tts_engine_invalid_buffer_size_4.json",
                errors::kInvalidTtsRequiresSampleRateAndBufferSize),
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 
   LoadAndExpectSuccess("tts_engine_valid_voices.json");
   LoadAndExpectSuccess("tts_engine_valid_sample_rate_buffer_size.json");
diff --git a/chrome/common/extensions/command_unittest.cc b/chrome/common/extensions/command_unittest.cc
index ce3b6b2..3ab9907e 100644
--- a/chrome/common/extensions/command_unittest.cc
+++ b/chrome/common/extensions/command_unittest.cc
@@ -198,7 +198,7 @@
   all_platforms.push_back("mac");
   all_platforms.push_back("windows");
 
-  for (size_t i = 0; i < base::size(kTests); ++i)
+  for (size_t i = 0; i < std::size(kTests); ++i)
     CheckParse(kTests[i], i, false, all_platforms);
 }
 
@@ -300,7 +300,7 @@
 
   std::vector<std::string> chromeos;
   chromeos.push_back("chromeos");
-  for (size_t i = 0; i < base::size(kChromeOsTests); ++i)
+  for (size_t i = 0; i < std::size(kChromeOsTests); ++i)
     CheckParse(kChromeOsTests[i], i, true, chromeos);
 
   ConstCommandsTestData kNonChromeOsSearchTests[] = {
@@ -312,7 +312,7 @@
   non_chromeos.push_back("mac");
   non_chromeos.push_back("linux");
 
-  for (size_t i = 0; i < base::size(kNonChromeOsSearchTests); ++i)
+  for (size_t i = 0; i < std::size(kNonChromeOsSearchTests); ++i)
     CheckParse(kNonChromeOsSearchTests[i], i, true, non_chromeos);
 }
 
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc
index 1433d3a6..d6f16ec 100644
--- a/chrome/common/extensions/extension_unittest.cc
+++ b/chrome/common/extensions/extension_unittest.cc
@@ -4,7 +4,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
 #include "base/path_service.h"
@@ -274,9 +273,9 @@
   scoped_refptr<Extension> extension = LoadManifestStrict("empty_manifest",
       "empty.json");
   EXPECT_TRUE(extension.get());
-  for (size_t i = 0; i < base::size(valid_path_test_cases); ++i)
+  for (size_t i = 0; i < std::size(valid_path_test_cases); ++i)
     EXPECT_TRUE(!extension->GetResource(valid_path_test_cases[i]).empty());
-  for (size_t i = 0; i < base::size(invalid_path_test_cases); ++i)
+  for (size_t i = 0; i < std::size(invalid_path_test_cases); ++i)
     EXPECT_TRUE(extension->GetResource(invalid_path_test_cases[i]).empty());
 }
 
diff --git a/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc b/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc
index a3ee370..15d64ec 100644
--- a/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc
+++ b/chrome/common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
@@ -43,7 +42,7 @@
                "Error at key 'content_scripts'. Parsing array failed at index "
                "0: Error at key 'matches': Parsing array failed at index 0: "
                "expected string, got integer")};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 
   LoadAndExpectSuccess("ports_in_content_scripts.json");
 }
diff --git a/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc b/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc
index 61346a3..655d219 100644
--- a/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc
+++ b/chrome/common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/extension.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -17,7 +16,7 @@
     Testcase("exclude_matches.json"),
     Testcase("exclude_matches_empty.json")
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_SUCCESS);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_SUCCESS);
 
   Testcase testcases2[] = {
       Testcase("exclude_matches_not_list.json",
@@ -26,7 +25,7 @@
       Testcase("exclude_matches_invalid_host.json",
                "Invalid value for 'content_scripts[0].exclude_matches[0]': "
                "Invalid host wildcard.")};
-  RunTestcases(testcases2, base::size(testcases2), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases2, std::size(testcases2), EXPECT_TYPE_ERROR);
 }
 
 }  // namespace extensions
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_about_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_about_unittest.cc
index 792c0df..50443cb 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_about_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_about_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_url_handlers.h"
@@ -26,5 +25,5 @@
       // Forbid absolute URLs.
       Testcase("shared_module_about_absolute.json",
                errors::kInvalidAboutPageExpectRelativePath)};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_contentsecuritypolicy_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_contentsecuritypolicy_unittest.cc
index 65b96c19..dd91a98 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_contentsecuritypolicy_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_contentsecuritypolicy_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/manifest_constants.h"
@@ -31,5 +30,5 @@
                ErrorUtils::FormatErrorMessage(
                    errors::kInvalidCSPMissingSecureSrc,
                    keys::kContentSecurityPolicy, "object-src"))};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_WARNING);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_WARNING);
 }
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_homepage_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_homepage_unittest.cc
index 312e60d..27f81e2 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_homepage_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_homepage_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/extension.h"
@@ -27,7 +26,7 @@
     Testcase("homepage_bad_schema.json",
              errors::kInvalidHomepageURL)
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(HomepageURLManifestTest, GetHomepageURL) {
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
index c641d18d3..8fae489 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_initvalue_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
@@ -105,7 +104,7 @@
       Testcase("init_invalid_short_name_type.json", errors::kInvalidShortName),
   };
 
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(InitValueManifestTest, InitFromValueValid) {
@@ -167,7 +166,7 @@
     Testcase("init_valid_permissions_unknown.json")
   };
 
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_SUCCESS);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_SUCCESS);
 }
 
 TEST_F(InitValueManifestTest, InitFromValueValidNameInRTL) {
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
index b072c8ce..d995661 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
@@ -65,7 +64,7 @@
                  errors::kInvalidLaunchValue,
                  keys::kLaunchHeight))
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(AppLaunchManifestTest, AppLaunchURL) {
@@ -103,7 +102,7 @@
                  errors::kInvalidLaunchValue,
                  keys::kLaunchWebURL))
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 
   scoped_refptr<Extension> extension =
       LoadAndExpectSuccess("launch_local_path.json");
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_options_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_options_unittest.cc
index 531097f..1caef23 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_options_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_options_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/error_utils.h"
@@ -89,7 +88,7 @@
       Testcase(
           "packaged_app_absolute_options.json",
           extensions::manifest_errors::kInvalidOptionsPageExpectUrlInPackage)};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 // Tests for the options_ui.page manifest field.
@@ -110,7 +109,7 @@
 
   Testcase testcases[] = {Testcase("options_ui_page_bad_url.json",
                                    "'page': expected page, got null")};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_WARNING);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_WARNING);
 }
 
 // Runs TestOptionsUIChromeStyleAndOpenInTab with and without the
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
index 4c71e75..73758c68 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_platformapp_unittest.cc
@@ -5,7 +5,6 @@
 #include <memory>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_file_value_serializer.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/error_utils.h"
@@ -46,7 +45,7 @@
                    errors::kInvalidManifestVersionUnsupported, "either 2 or 3",
                    "apps")),
   };
-  RunTestcases(error_testcases, base::size(error_testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(error_testcases, std::size(error_testcases), EXPECT_TYPE_ERROR);
 
   Testcase warning_testcases[] = {
       Testcase(
@@ -66,7 +65,7 @@
                "apps, "
                "but this is a packaged app."),
   };
-  RunTestcases(warning_testcases, base::size(warning_testcases),
+  RunTestcases(warning_testcases, std::size(warning_testcases),
                EXPECT_TYPE_WARNING);
 }
 
@@ -83,7 +82,7 @@
         "'app.content_security_policy' is not allowed for specified extension "
             "ID.")
   };
-  RunTestcases(warning_testcases, base::size(warning_testcases),
+  RunTestcases(warning_testcases, std::size(warning_testcases),
                EXPECT_TYPE_WARNING);
 
   // Allowlisted ones can (this is the ID corresponding to the base 64 encoded
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
index 9360e8f0..fa3d30a 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/manifest_constants.h"
@@ -35,7 +34,7 @@
           "Error at key 'requirements.3D.features'. Manifest key is required."),
   };
 
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(RequirementsManifestTest, RequirementsValid) {
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_update_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_update_unittest.cc
index 2020fbe..061af5e 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_update_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_update_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_url_handlers.h"
@@ -27,7 +26,7 @@
                Extension::NO_FLAGS),
       Testcase("update_url_valid_4.json", ManifestLocation::kInternal,
                Extension::NO_FLAGS)};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_SUCCESS);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_SUCCESS);
 
   // Test some invalid update urls
   Testcase testcases2[] = {
@@ -37,5 +36,5 @@
                ManifestLocation::kInternal, Extension::NO_FLAGS),
       Testcase("update_url_invalid_3.json", errors::kInvalidUpdateURL,
                ManifestLocation::kInternal, Extension::NO_FLAGS)};
-  RunTestcases(testcases2, base::size(testcases2), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases2, std::size(testcases2), EXPECT_TYPE_ERROR);
 }
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_web_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_web_unittest.cc
index 8ff9390..a106559 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_web_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_web_unittest.cc
@@ -2,11 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
-
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/manifest_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -40,7 +38,7 @@
                ErrorUtils::FormatErrorMessage(
                    errors::kInvalidWebURL, base::NumberToString(1),
                    errors::kCannotClaimAllHostsInExtent))};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 
   LoadAndExpectSuccess("web_urls_has_port.json");
 
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 1247e74e..c42251c 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
@@ -689,7 +688,7 @@
       {"sockets3", true},           // tcp:a.com:80 -> tcp:*:*
   };
 
-  for (size_t i = 0; i < base::size(kTests); ++i) {
+  for (size_t i = 0; i < std::size(kTests); ++i) {
     scoped_refptr<Extension> old_extension(
         LoadManifest("allow_silent_upgrade",
                      std::string(kTests[i].base_name) + "_old.json"));
@@ -1673,7 +1672,7 @@
        false},
   };
   const PermissionMessageProvider* provider = PermissionMessageProvider::Get();
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     URLPatternSet explicit_hosts1;
     URLPatternSet explicit_hosts2;
     const auto& test_case = test_cases[i];
diff --git a/chrome/common/importer/firefox_importer_utils_unittest.cc b/chrome/common/importer/firefox_importer_utils_unittest.cc
index 80ba0c42..7a74488 100644
--- a/chrome/common/importer/firefox_importer_utils_unittest.cc
+++ b/chrome/common/importer/firefox_importer_utils_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/strings/utf_string_conversions.h"
@@ -101,7 +100,7 @@
 }  // anonymous namespace
 
 TEST(FirefoxImporterUtilsTest, GetPrefsJsValue) {
-  for (size_t i = 0; i < base::size(GetPrefsJsValueCases); ++i) {
+  for (size_t i = 0; i < std::size(GetPrefsJsValueCases); ++i) {
     EXPECT_EQ(
       GetPrefsJsValueCases[i].pref_value,
       GetPrefsJsValue(GetPrefsJsValueCases[i].prefs_content,
@@ -114,7 +113,7 @@
   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   const base::FilePath app_ini_file(
       temp_dir.GetPath().AppendASCII("application.ini"));
-  for (size_t i = 0; i < base::size(GetFirefoxImporterNameCases); ++i) {
+  for (size_t i = 0; i < std::size(GetFirefoxImporterNameCases); ++i) {
     base::WriteFile(app_ini_file,
                     GetFirefoxImporterNameCases[i].app_ini_content.c_str(),
                     GetFirefoxImporterNameCases[i].app_ini_content.size());
diff --git a/chrome/common/media/cdm_host_file_path.cc b/chrome/common/media/cdm_host_file_path.cc
index fe95403..279708d 100644
--- a/chrome/common/media/cdm_host_file_path.cc
+++ b/chrome/common/media/cdm_host_file_path.cc
@@ -5,7 +5,6 @@
 #include "chrome/common/media/cdm_host_file_path.h"
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -58,11 +57,11 @@
     NOTREACHED();
   base::FilePath version_dir(chrome_exe_dir.AppendASCII(CHROME_VERSION_STRING));
 
-  cdm_host_file_paths->reserve(base::size(kUnversionedFiles) +
-                               base::size(kVersionedFiles));
+  cdm_host_file_paths->reserve(std::size(kUnversionedFiles) +
+                               std::size(kVersionedFiles));
 
   // Signature files are always in the version directory.
-  for (size_t i = 0; i < base::size(kUnversionedFiles); ++i) {
+  for (size_t i = 0; i < std::size(kUnversionedFiles); ++i) {
     base::FilePath file_path = chrome_exe_dir.Append(kUnversionedFiles[i]);
     base::FilePath sig_path =
         GetSigFilePath(version_dir.Append(kUnversionedFiles[i]));
@@ -71,7 +70,7 @@
     cdm_host_file_paths->emplace_back(file_path, sig_path);
   }
 
-  for (size_t i = 0; i < base::size(kVersionedFiles); ++i) {
+  for (size_t i = 0; i < std::size(kVersionedFiles); ++i) {
     base::FilePath file_path = version_dir.Append(kVersionedFiles[i]);
     DVLOG(2) << __func__ << ": versioned file " << i << " at "
              << file_path.value();
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 3fede71..e8ae72e2 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -4,7 +4,8 @@
 
 #include "chrome/common/pref_names.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
+
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -262,7 +263,7 @@
 };
 
 const size_t kWebKitScriptsForFontFamilyMapsLength =
-    base::size(kWebKitScriptsForFontFamilyMaps);
+    std::size(kWebKitScriptsForFontFamilyMaps);
 
 // Strings for WebKit font family preferences. If these change, the pref prefix
 // in pref_names_util.cc and the pref format in font_settings_api.cc must also
@@ -3399,4 +3400,9 @@
 const char kOriginAgentClusterDefaultEnabled[] =
     "origin_agent_cluster_default_enabled";
 
+// An integer count of how many SCT Auditing hashdance reports have ever been
+// sent by this client, across all profiles.
+const char kSCTAuditingHashdanceReportCount[] =
+    "sct_auditing.hashdance_report_count";
+
 }  // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 32df3c4b..629b4ad 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -1199,6 +1199,8 @@
 extern const char kOriginAgentClusterDefaultEnabled[];
 
 extern const char kForceMajorVersionToMinorPositionInUserAgent[];
+
+extern const char kSCTAuditingHashdanceReportCount[];
 }  // namespace prefs
 
 #endif  // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/common/safe_browsing/archive_analyzer_results.cc b/chrome/common/safe_browsing/archive_analyzer_results.cc
index abd2ae9..e32115a 100644
--- a/chrome/common/safe_browsing/archive_analyzer_results.cc
+++ b/chrome/common/safe_browsing/archive_analyzer_results.cc
@@ -7,7 +7,6 @@
 
 #include "chrome/common/safe_browsing/archive_analyzer_results.h"
 
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/i18n/streaming_utf8_validator.h"
 #include "base/logging.h"
@@ -65,8 +64,8 @@
   }
 
   uint8_t digest[crypto::kSHA256Length];
-  hasher->Finish(digest, base::size(digest));
-  archived_binary->mutable_digests()->set_sha256(digest, base::size(digest));
+  hasher->Finish(digest, std::size(digest));
+  archived_binary->mutable_digests()->set_sha256(digest, std::size(digest));
 }
 
 void AnalyzeContainedBinary(
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index c4e90bf..bdb6091 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/common/webui_url_constants.h"
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -713,7 +712,7 @@
     kCfmNetworkSettingsHost,
 #endif  // BUILDFLAG(PLATFORM_CFM)
 };
-const size_t kNumberOfChromeHostURLs = base::size(kChromeHostURLs);
+const size_t kNumberOfChromeHostURLs = std::size(kChromeHostURLs);
 
 // Add chrome://internals/* subpages here to be included in chrome://chrome-urls
 // (about:about).
@@ -726,7 +725,7 @@
 #endif
 };
 const size_t kNumberOfChromeInternalsPathURLs =
-    base::size(kChromeInternalsPathURLs);
+    std::size(kChromeInternalsPathURLs);
 
 const char* const kChromeDebugURLs[] = {
     blink::kChromeUIBadCastCrashURL,
@@ -755,6 +754,6 @@
 #endif
     kChromeUIQuitURL,
     kChromeUIRestartURL};
-const size_t kNumberOfChromeDebugURLs = base::size(kChromeDebugURLs);
+const size_t kNumberOfChromeDebugURLs = std::size(kChromeDebugURLs);
 
 }  // namespace chrome
diff --git a/chrome/credential_provider/extension/app_inventory_manager.cc b/chrome/credential_provider/extension/app_inventory_manager.cc
index 4e214de..5ab8ee9 100644
--- a/chrome/credential_provider/extension/app_inventory_manager.cc
+++ b/chrome/credential_provider/extension/app_inventory_manager.cc
@@ -228,7 +228,7 @@
         std::make_unique<base::Value>(base::Value::Type::DICTIONARY);
 
     wchar_t display_name[256];
-    ULONG display_length = base::size(display_name);
+    ULONG display_length = std::size(display_name);
     HRESULT hr =
         GetMachineRegString(regPath, std::wstring(kAppDisplayNameRegistryKey),
                             display_name, &display_length);
@@ -237,7 +237,7 @@
                                  base::WideToUTF8(display_name));
 
       wchar_t display_version[256];
-      ULONG version_length = base::size(display_version);
+      ULONG version_length = std::size(display_version);
       hr = GetMachineRegString(regPath,
                                std::wstring(kAppDisplayVersionRegistryKey),
                                display_version, &version_length);
@@ -247,7 +247,7 @@
       }
 
       wchar_t publisher[256];
-      ULONG publisher_length = base::size(publisher);
+      ULONG publisher_length = std::size(publisher);
       hr = GetMachineRegString(regPath, std::wstring(kAppPublisherRegistryKey),
                                publisher, &publisher_length);
       if (hr == S_OK) {
diff --git a/chrome/credential_provider/extension/task_manager.cc b/chrome/credential_provider/extension/task_manager.cc
index 5c347744..980ec06e0 100644
--- a/chrome/credential_provider/extension/task_manager.cc
+++ b/chrome/credential_provider/extension/task_manager.cc
@@ -53,7 +53,7 @@
 base::TimeDelta GetTimeDeltaSinceLastPeriodicSync(
     const std::wstring& task_reg_name) {
   wchar_t last_sync_millis[512];
-  ULONG last_sync_size = base::size(last_sync_millis);
+  ULONG last_sync_size = std::size(last_sync_millis);
   HRESULT hr = GetGlobalFlag(task_reg_name, last_sync_millis, &last_sync_size);
 
   if (FAILED(hr)) {
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator.cc b/chrome/credential_provider/gaiacp/associated_user_validator.cc
index ecb9d93..443ca16 100644
--- a/chrome/credential_provider/gaiacp/associated_user_validator.cc
+++ b/chrome/credential_provider/gaiacp/associated_user_validator.cc
@@ -134,7 +134,7 @@
   wchar_t domain[kWindowsDomainBufferLength];
 
   HRESULT hr = manager->FindUserBySID(
-      sid.c_str(), username, base::size(username), domain, base::size(domain));
+      sid.c_str(), username, std::size(username), domain, std::size(domain));
 
   if (FAILED(hr)) {
     LOGFN(ERROR) << "FindUserBySID sid=" << sid << " hr=" << putHR(hr);
@@ -219,7 +219,7 @@
 bool AssociatedUserValidator::IsOnlineLoginStale(
     const std::wstring& sid) const {
   wchar_t last_token_valid_millis[512];
-  ULONG last_token_valid_size = base::size(last_token_valid_millis);
+  ULONG last_token_valid_size = std::size(last_token_valid_millis);
   HRESULT hr = GetUserProperty(sid, base::UTF8ToWide(kKeyLastTokenValid),
                                last_token_valid_millis, &last_token_valid_size);
 
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
index b14e3b2b..02ba92b 100644
--- a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
+++ b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
@@ -2,12 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/credential_provider/gaiacp/stdafx.h"
-
 #include <memory>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/guid.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -20,6 +17,7 @@
 #include "chrome/credential_provider/gaiacp/gcpw_strings.h"
 #include "chrome/credential_provider/gaiacp/mdm_utils.h"
 #include "chrome/credential_provider/gaiacp/reg_utils.h"
+#include "chrome/credential_provider/gaiacp/stdafx.h"
 #include "chrome/credential_provider/test/gcp_fakes.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -143,7 +141,7 @@
             SetUserProperty((BSTR)sid_no_token_handle, kUserTokenHandle, L""));
 
   wchar_t token_handle[256];
-  DWORD length = base::size(token_handle);
+  DWORD length = std::size(token_handle);
   EXPECT_NE(S_OK, GetUserProperty((BSTR)sid_no_token_handle, kUserTokenHandle,
                                   token_handle, &length));
 
@@ -171,7 +169,7 @@
 
   // Expect user with no token handle to still not have a token handle set in
   // the registry.
-  length = base::size(token_handle);
+  length = std::size(token_handle);
   EXPECT_NE(S_OK, GetUserProperty((BSTR)sid_no_token_handle, kUserTokenHandle,
                                   token_handle, &length));
 }
diff --git a/chrome/credential_provider/gaiacp/device_policies_manager.cc b/chrome/credential_provider/gaiacp/device_policies_manager.cc
index 075ecb6..e60feec 100644
--- a/chrome/credential_provider/gaiacp/device_policies_manager.cc
+++ b/chrome/credential_provider/gaiacp/device_policies_manager.cc
@@ -176,8 +176,8 @@
 
     // Check if this account with this sid exists on device.
     HRESULT hr = OSUserManager::Get()->FindUserBySidWithFallback(
-        sid.c_str(), found_username, base::size(found_username), found_domain,
-        base::size(found_domain));
+        sid.c_str(), found_username, std::size(found_username), found_domain,
+        std::size(found_domain));
     if (hr != S_OK) {
       if (hr != HRESULT_FROM_WIN32(ERROR_NONE_MAPPED)) {
         LOGFN(ERROR) << "FindUserBySidWithRegistryFallback hr=" << putHR(hr);
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
index e895266..a8a4ebf 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -16,7 +16,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
@@ -771,7 +770,7 @@
   DCHECK(final_username);
   DCHECK(sid);
   wchar_t new_username[kWindowsUsernameBufferLength];
-  errno_t err = wcscpy_s(new_username, base::size(new_username), base_username);
+  errno_t err = wcscpy_s(new_username, std::size(new_username), base_username);
   if (err != 0) {
     LOGFN(ERROR) << "wcscpy_s errno=" << err;
     return E_FAIL;
@@ -801,7 +800,7 @@
       LOGFN(VERBOSE) << "Username '" << new_username
                      << "' already exists. Trying '" << next_username << "'";
 
-      err = wcscpy_s(new_username, base::size(new_username),
+      err = wcscpy_s(new_username, std::size(new_username),
                      next_username.c_str());
       if (err != 0) {
         LOGFN(ERROR) << "wcscpy_s errno=" << err;
@@ -889,13 +888,13 @@
   // step fails, assume that a new user needs to be created.
   wchar_t gaia_username[kWindowsUsernameBufferLength];
   HRESULT hr = policy->RetrievePrivateData(kLsaKeyGaiaUsername, gaia_username,
-                                           base::size(gaia_username));
+                                           std::size(gaia_username));
 
   if (SUCCEEDED(hr)) {
     LOGFN(VERBOSE) << "Expecting gaia user '" << gaia_username << "' to exist.";
     wchar_t password[32];
     hr = policy->RetrievePrivateData(kLsaKeyGaiaPassword, password,
-                                     base::size(password));
+                                     std::size(password));
     if (SUCCEEDED(hr)) {
       std::wstring local_domain = OSUserManager::GetLocalDomain();
       base::win::ScopedHandle token;
@@ -917,7 +916,7 @@
   if (sid == nullptr) {
     // No valid existing user found, reset to default name and start generating
     // from there.
-    errno_t err = wcscpy_s(gaia_username, base::size(gaia_username),
+    errno_t err = wcscpy_s(gaia_username, std::size(gaia_username),
                            kDefaultGaiaAccountName);
     if (err != 0) {
       LOGFN(ERROR) << "wcscpy_s errno=" << err;
@@ -926,7 +925,7 @@
 
     // Generate a random password for the new gaia account.
     wchar_t password[32];
-    hr = manager->GenerateRandomPassword(password, base::size(password));
+    hr = manager->GenerateRandomPassword(password, std::size(password));
     if (FAILED(hr)) {
       LOGFN(ERROR) << "GenerateRandomPassword hr=" << putHR(hr);
       return hr;
@@ -993,7 +992,7 @@
     wchar_t password[32];
 
     HRESULT hr = policy->RetrievePrivateData(kLsaKeyGaiaPassword, password,
-                                             base::size(password));
+                                             std::size(password));
     if (FAILED(hr))
       LOGFN(ERROR) << "policy.RetrievePrivateData hr=" << putHR(hr);
 
@@ -1006,7 +1005,7 @@
 
     wchar_t gaia_username[kWindowsUsernameBufferLength];
     hr = policy->RetrievePrivateData(kLsaKeyGaiaUsername, gaia_username,
-                                     base::size(gaia_username));
+                                     std::size(gaia_username));
 
     if (SUCCEEDED(hr)) {
       hr = policy->RemovePrivateData(kLsaKeyGaiaUsername);
@@ -1821,7 +1820,7 @@
 
   wchar_t gaia_username[kWindowsUsernameBufferLength];
   HRESULT hr = policy->RetrievePrivateData(kLsaKeyGaiaUsername, gaia_username,
-                                           base::size(gaia_username));
+                                           std::size(gaia_username));
 
   if (FAILED(hr)) {
     LOGFN(ERROR) << "Retrieve gaia username hr=" << putHR(hr);
@@ -1829,7 +1828,7 @@
   }
   wchar_t password[32];
   hr = policy->RetrievePrivateData(kLsaKeyGaiaPassword, password,
-                                   base::size(password));
+                                   std::size(password));
   if (FAILED(hr)) {
     LOGFN(ERROR) << "Retrieve password for gaia user '" << gaia_username
                  << "' hr=" << putHR(hr);
@@ -2350,8 +2349,8 @@
   bool is_consumer_account = false;
   std::wstring gaia_id;
   HRESULT hr = MakeUsernameForAccount(
-      result, &gaia_id, found_username, base::size(found_username),
-      found_domain, base::size(found_domain), found_sid, base::size(found_sid),
+      result, &gaia_id, found_username, std::size(found_username), found_domain,
+      std::size(found_domain), found_sid, std::size(found_sid),
       &is_consumer_account, error_text);
   if (FAILED(hr)) {
     LOGFN(ERROR) << "MakeUsernameForAccount hr=" << putHR(hr);
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
index d7831de..5686576b 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
@@ -251,7 +251,7 @@
 
   // Verify that the registry entry for the user was created.
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   wchar_t* sidstr = nullptr;
   ::ConvertSidToStringSid(sid, &sidstr);
   ::LocalFree(sid);
@@ -1213,7 +1213,7 @@
       OLE2W(first_sid)));
 
   wchar_t latest_token_valid_millis[512];
-  ULONG latest_token_valid_size = base::size(latest_token_valid_millis);
+  ULONG latest_token_valid_size = std::size(latest_token_valid_millis);
   ASSERT_EQ(S_OK, GetUserProperty(
                       OLE2W(first_sid), base::UTF8ToWide(kKeyLastTokenValid),
                       latest_token_valid_millis, &latest_token_valid_size));
@@ -1436,7 +1436,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -1470,7 +1470,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -1536,7 +1536,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -1624,7 +1624,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -1680,7 +1680,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -1753,7 +1753,7 @@
 
   // Verify that the registry entry for the user was created.
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   std::wstring sid_str(ad_sid, SysStringLen(ad_sid));
   ::SysFreeString(ad_sid);
 
@@ -1770,7 +1770,7 @@
 
   // Verify that the registry entry for the domain name was created.
   wchar_t domain_reg[256];
-  ULONG domain_reg_length = base::size(domain_reg);
+  ULONG domain_reg_length = std::size(domain_reg);
   ASSERT_TRUE(
       SUCCEEDED(GetUserProperty(sid_str.c_str(), base::UTF8ToWide(kKeyDomain),
                                 domain_reg, &domain_reg_length)));
@@ -1779,7 +1779,7 @@
 
   // Verify that the registry entry for the username was created.
   wchar_t username_reg[256];
-  ULONG username_reg_length = base::size(username_reg);
+  ULONG username_reg_length = std::size(username_reg);
   ASSERT_TRUE(
       SUCCEEDED(GetUserProperty(sid_str.c_str(), base::UTF8ToWide(kKeyUsername),
                                 username_reg, &username_reg_length)));
@@ -1859,7 +1859,7 @@
 
   ASSERT_EQ(S_OK, StartLogonProcessAndWait());
 
-  ASSERT_TRUE(base::size(test->GetFinalEmail()) == 0);
+  ASSERT_TRUE(std::size(test->GetFinalEmail()) == 0);
 
   // Make sure no user was created and the login attempt failed.
   PSID sid = nullptr;
@@ -2146,7 +2146,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2220,7 +2220,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2292,7 +2292,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2363,7 +2363,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2437,7 +2437,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2567,7 +2567,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -2635,7 +2635,7 @@
   std::wstring sid_str(local_sid, SysStringLen(local_sid));
 
   wchar_t gaia_id[256];
-  ULONG length = base::size(gaia_id);
+  ULONG length = std::size(gaia_id);
   HRESULT gaia_id_hr =
       GetUserProperty(sid_str.c_str(), kUserId, gaia_id, &length);
   ASSERT_EQ(S_OK, gaia_id_hr);
@@ -3503,7 +3503,7 @@
     ASSERT_EQ(0UL, device_upload_failures);
 
     wchar_t resource_id[512];
-    ULONG resource_id_size = base::size(resource_id);
+    ULONG resource_id_size = std::size(resource_id);
     hr = GetUserProperty(sid.Copy(), kRegUserDeviceResourceId, resource_id,
                          &resource_id_size);
     ASSERT_TRUE(SUCCEEDED(hr));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
index 96788be..0b8c7a0 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -9,7 +9,6 @@
 #include <string>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_reader.h"
 #include "base/memory/raw_ptr.h"
@@ -46,7 +45,7 @@
      CPFG_CREDENTIAL_PROVIDER_LABEL},
 };
 
-static_assert(base::size(g_field_desc) == FIELD_COUNT,
+static_assert(std::size(g_field_desc) == FIELD_COUNT,
               "g_field_desc does not match FIELDID enum");
 
 namespace {
@@ -75,7 +74,7 @@
   // effect is that the user will need to enter their email address manually
   // instead of it being pre-filled.
   wchar_t email[64];
-  ULONG email_length = base::size(email);
+  ULONG email_length = std::size(email);
   hr = GetUserProperty(sid.c_str(), kUserEmail, email, &email_length);
   if (FAILED(hr))
     email[0] = 0;
@@ -433,8 +432,7 @@
     wchar_t domain[kWindowsDomainBufferLength];
 
     hr = OSUserManager::Get()->FindUserBySidWithFallback(
-        sid.c_str(), username, base::size(username), domain,
-        base::size(domain));
+        sid.c_str(), username, std::size(username), domain, std::size(domain));
     if (FAILED(hr)) {
       LOGFN(ERROR) << "Can't get sid or username hr=" << putHR(hr);
       continue;
@@ -443,7 +441,7 @@
     // Get the user's gaia id from registry stored against the sid if it
     // exists.
     wchar_t user_id[64];
-    ULONG user_id_length = base::size(user_id);
+    ULONG user_id_length = std::size(user_id);
     hr = GetUserProperty(sid.c_str(), kUserId, user_id, &user_id_length);
     if (FAILED(hr))
       user_id[0] = L'\0';
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
index c399acb..9b5658b 100644
--- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -855,7 +855,7 @@
     auto guid_string = base::win::WStringFromGUID(CLSID_GaiaCredentialProvider);
 
     wchar_t guid_in_registry[64];
-    ULONG length = base::size(guid_in_registry);
+    ULONG length = std::size(guid_in_registry);
     EXPECT_EQ(S_OK, GetMachineRegString(kLogonUiUserTileRegKey, sid,
                                         guid_in_registry, &length));
     EXPECT_EQ(guid_string, std::wstring(guid_in_registry));
diff --git a/chrome/credential_provider/gaiacp/gcp_utils.cc b/chrome/credential_provider/gaiacp/gcp_utils.cc
index a7a1a900..76a6cbf 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils.cc
@@ -229,7 +229,7 @@
   } else {
     wchar_t dm_token_lsa_data[1024];
     HRESULT hr = policy->RetrievePrivateData(
-        store_key.c_str(), dm_token_lsa_data, base::size(dm_token_lsa_data));
+        store_key.c_str(), dm_token_lsa_data, std::size(dm_token_lsa_data));
     if (FAILED(hr)) {
       LOGFN(ERROR) << "ScopedLsaPolicy::RetrievePrivateData hr=" << putHR(hr);
       return hr;
@@ -436,7 +436,7 @@
 
   for (bool is_done = false; !is_done;) {
     char buffer[80];
-    DWORD length = base::size(buffer) - 1;
+    DWORD length = std::size(buffer) - 1;
     HRESULT hr = S_OK;
 
     const DWORD kThreeMinutesInMs = 3 * 60 * 1000;
@@ -678,9 +678,9 @@
 HRESULT GetPathToDllFromHandle(HINSTANCE dll_handle,
                                base::FilePath* path_to_dll) {
   wchar_t path[MAX_PATH];
-  DWORD length = base::size(path);
+  DWORD length = std::size(path);
   length = ::GetModuleFileName(dll_handle, path, length);
-  if (length == 0 || length >= base::size(path)) {
+  if (length == 0 || length >= std::size(path)) {
     HRESULT hr = HRESULT_FROM_WIN32(::GetLastError());
     LOGFN(ERROR) << "GetModuleFileNameW hr=" << putHR(hr);
     return hr;
@@ -709,10 +709,10 @@
     return hr;
 
   wchar_t short_path[MAX_PATH];
-  DWORD short_length = base::size(short_path);
+  DWORD short_length = std::size(short_path);
   short_length =
       ::GetShortPathName(path_to_dll.value().c_str(), short_path, short_length);
-  if (short_length >= base::size(short_path)) {
+  if (short_length >= std::size(short_path)) {
     hr = HRESULT_FROM_WIN32(::GetLastError());
     LOGFN(ERROR) << "GetShortPathNameW hr=" << putHR(hr);
     return hr;
@@ -771,7 +771,7 @@
         PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi);
     if (status >= 0) {
       BYTE well_known_sid[SECURITY_MAX_SID_SIZE];
-      DWORD size_local_users_group_sid = base::size(well_known_sid);
+      DWORD size_local_users_group_sid = std::size(well_known_sid);
       if (CreateWellKnownSid(::WinAccountAdministratorSid, ppadi->DomainSid,
                              well_known_sid, &size_local_users_group_sid)) {
         return LookupLocalizedNameBySid(well_known_sid,
@@ -829,7 +829,7 @@
 HRESULT LookupLocalizedNameForWellKnownSid(WELL_KNOWN_SID_TYPE sid_type,
                                            std::wstring* localized_name) {
   BYTE well_known_sid[SECURITY_MAX_SID_SIZE];
-  DWORD size_local_users_group_sid = base::size(well_known_sid);
+  DWORD size_local_users_group_sid = std::size(well_known_sid);
 
   // Get the sid for the well known local users group.
   if (!::CreateWellKnownSid(sid_type, nullptr, well_known_sid,
@@ -1040,7 +1040,7 @@
 
 std::wstring GetWindowsVersion() {
   wchar_t release_id[32];
-  ULONG length = base::size(release_id);
+  ULONG length = std::size(release_id);
   HRESULT hr =
       GetMachineRegString(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
                           L"ReleaseId", release_id, &length);
@@ -1159,7 +1159,7 @@
   DWORD major;
   DWORD minor;
   wchar_t build[32];
-  ULONG length = base::size(build);
+  ULONG length = std::size(build);
 
   HRESULT hr1 = GetMachineRegDWORD(kOsRegistryPath, kOsMajorName, &major);
   HRESULT hr2 = GetMachineRegDWORD(kOsRegistryPath, kOsMinorName, &minor);
@@ -1218,7 +1218,7 @@
                                            base::CommandLine* command_line) {
   // Registry specified endpoint.
   wchar_t endpoint_url_setting[256];
-  ULONG endpoint_url_length = base::size(endpoint_url_setting);
+  ULONG endpoint_url_length = std::size(endpoint_url_setting);
   HRESULT hr = GetGlobalFlag(override_registry_key, endpoint_url_setting,
                              &endpoint_url_length);
   if (SUCCEEDED(hr) && endpoint_url_setting[0]) {
@@ -1254,7 +1254,7 @@
   base::FilePath gls_path = GetSystemChromePath();
 
   wchar_t custom_gls_path_value[MAX_PATH];
-  ULONG path_len = base::size(custom_gls_path_value);
+  ULONG path_len = std::size(custom_gls_path_value);
   HRESULT hr = GetGlobalFlag(kRegGlsPath, custom_gls_path_value, &path_len);
   if (SUCCEEDED(hr)) {
     base::FilePath custom_gls_path(custom_gls_path_value);
@@ -1354,7 +1354,7 @@
 base::TimeDelta GetTimeDeltaSinceLastFetch(const std::wstring& sid,
                                            const std::wstring& flag) {
   wchar_t last_fetch_millis[512];
-  ULONG last_fetch_size = base::size(last_fetch_millis);
+  ULONG last_fetch_size = std::size(last_fetch_millis);
   HRESULT hr = GetUserProperty(sid, flag, last_fetch_millis, &last_fetch_size);
 
   if (FAILED(hr)) {
diff --git a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
index e66447fb..1b5c195d 100644
--- a/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
+++ b/chrome/credential_provider/gaiacp/gcp_utils_unittests.cc
@@ -4,7 +4,6 @@
 
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/process/launch.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -33,7 +32,7 @@
   // Generate a few passwords and make sure length i correct.
   for (int i = 0; i < 100; ++i) {
     ASSERT_EQ(S_OK,
-              manager->GenerateRandomPassword(password, base::size(password)));
+              manager->GenerateRandomPassword(password, std::size(password)));
     ASSERT_LT(24u, wcslen(password));
   }
 }
@@ -85,7 +84,7 @@
     const base::win::ScopedHandle::Handle& writing) {
   char input_buffer[8];
   char output_buffer[8];
-  strcpy_s(input_buffer, base::size(input_buffer), "hello");
+  strcpy_s(input_buffer, std::size(input_buffer), "hello");
   const DWORD kExpectedDataLength = strlen(input_buffer) + 1;
 
   // Make sure what is written can be read.
@@ -95,7 +94,7 @@
   EXPECT_EQ(kExpectedDataLength, written);
 
   DWORD read;
-  EXPECT_TRUE(ReadFile(reading, output_buffer, base::size(output_buffer), &read,
+  EXPECT_TRUE(ReadFile(reading, output_buffer, std::size(output_buffer), &read,
                        nullptr));
   EXPECT_EQ(kExpectedDataLength, read);
   return strcmp(input_buffer, output_buffer) == 0;
@@ -405,7 +404,7 @@
   // Write to stdin of the child process.
   const int kBufferSize = 16;
   char input_buffer[kBufferSize];
-  strcpy_s(input_buffer, base::size(input_buffer), "hello");
+  strcpy_s(input_buffer, std::size(input_buffer), "hello");
   const DWORD kExpectedDataLength = strlen(input_buffer) + 1;
   DWORD written;
   ASSERT_TRUE(::WriteFile(parent_handles.hstdin_write.Get(), input_buffer,
@@ -438,8 +437,8 @@
   // Get short path name of this binary and build the expect command line.
   wchar_t path[MAX_PATH];
   wchar_t short_path[MAX_PATH];
-  ASSERT_LT(0u, GetModuleFileName(nullptr, path, base::size(path)));
-  ASSERT_LT(0u, GetShortPathName(path, short_path, base::size(short_path)));
+  ASSERT_LT(0u, GetModuleFileName(nullptr, path, std::size(path)));
+  ASSERT_LT(0u, GetShortPathName(path, short_path, std::size(short_path)));
 
   std::wstring expected_arg =
       base::StringPrintf(L"\"%ls\",%ls", short_path, L"entrypoint");
diff --git a/chrome/credential_provider/gaiacp/gem_device_details_manager.cc b/chrome/credential_provider/gaiacp/gem_device_details_manager.cc
index a1fbe00..7c17b8ce 100644
--- a/chrome/credential_provider/gaiacp/gem_device_details_manager.cc
+++ b/chrome/credential_provider/gaiacp/gem_device_details_manager.cc
@@ -167,8 +167,8 @@
   wchar_t found_domain[kWindowsDomainBufferLength] = {};
 
   status = OSUserManager::Get()->FindUserBySidWithFallback(
-      context.user_sid.c_str(), found_username, base::size(found_username),
-      found_domain, base::size(found_domain));
+      context.user_sid.c_str(), found_username, std::size(found_username),
+      found_domain, std::size(found_domain));
   if (FAILED(status)) {
     LOGFN(ERROR) << "Could not get username and domain from sid "
                  << context.user_sid;
diff --git a/chrome/credential_provider/gaiacp/os_process_manager.cc b/chrome/credential_provider/gaiacp/os_process_manager.cc
index b5bdab1..a40a10720 100644
--- a/chrome/credential_provider/gaiacp/os_process_manager.cc
+++ b/chrome/credential_provider/gaiacp/os_process_manager.cc
@@ -5,29 +5,26 @@
 #include "chrome/credential_provider/gaiacp/os_process_manager.h"
 
 #include <Windows.h>
-#include <Winternl.h>
 
 #include <MDMRegistration.h>
 #include <Shellapi.h>  // For CommandLineToArgvW()
 #include <Shlobj.h>
+#include <Winternl.h>
 #include <aclapi.h>
-#include <dpapi.h>
-#include <sddl.h>
-#include <security.h>
-#include <userenv.h>
-#include <wincred.h>
-
 #include <atlconv.h>
-
+#include <dpapi.h>
 #include <malloc.h>
 #include <memory.h>
+#include <sddl.h>
+#include <security.h>
 #include <stdlib.h>
+#include <userenv.h>
+#include <wincred.h>
 
 #include <iomanip>
 #include <memory>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/process/launch.h"
 #include "base/scoped_native_library.h"
@@ -58,7 +55,7 @@
   char buffer[256];
   DWORD returned_length;
   if (!::GetTokenInformation(token.Get(), TokenLogonSid, &buffer,
-                             base::size(buffer), &returned_length)) {
+                             std::size(buffer), &returned_length)) {
     HRESULT hr = HRESULT_FROM_WIN32(::GetLastError());
     LOGFN(ERROR) << "GetTokenInformation hr=" << putHR(hr);
     return hr;
@@ -196,9 +193,9 @@
   UNICODE_STRING name;
   wchar_t name_buffer[64];
   if (session_id == 0) {
-    _snwprintf_s(name_buffer, base::size(name_buffer), L"\\BaseNamedObjects");
+    _snwprintf_s(name_buffer, std::size(name_buffer), L"\\BaseNamedObjects");
   } else {
-    _snwprintf_s(name_buffer, base::size(name_buffer),
+    _snwprintf_s(name_buffer, std::size(name_buffer),
                  L"\\Sessions\\%d\\BaseNamedObjects", session_id);
   }
   InitWindowsStringWithString(name_buffer, &name);
diff --git a/chrome/credential_provider/gaiacp/os_user_manager.cc b/chrome/credential_provider/gaiacp/os_user_manager.cc
index aded98d..d4238b2 100644
--- a/chrome/credential_provider/gaiacp/os_user_manager.cc
+++ b/chrome/credential_provider/gaiacp/os_user_manager.cc
@@ -6,22 +6,18 @@
 
 #include <windows.h>
 
-#include <lm.h>
-
-#include <sddl.h>      // For ConvertSidToStringSid()
-#include <userenv.h>   // For GetUserProfileDirectory()
-#include <wincrypt.h>  // For CryptXXX()
-
 #include <atlconv.h>
-
+#include <lm.h>
 #include <malloc.h>
 #include <memory.h>
+#include <sddl.h>  // For ConvertSidToStringSid()
 #include <stdlib.h>
+#include <userenv.h>   // For GetUserProfileDirectory()
+#include <wincrypt.h>  // For CryptXXX()
 
 #include <iomanip>
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/scoped_native_library.h"
@@ -82,7 +78,7 @@
 std::wstring OSUserManager::GetLocalDomain() {
   // If the domain is the current computer, then there is no domain controller.
   wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1];
-  DWORD length = base::size(computer_name);
+  DWORD length = std::size(computer_name);
   if (!::GetComputerNameW(computer_name, &length))
     return std::wstring();
 
@@ -145,8 +141,7 @@
         return hr;
       }
 
-      wchar_t c =
-          kValidPasswordChars[r % (base::size(kValidPasswordChars) - 1)];
+      wchar_t c = kValidPasswordChars[r % (std::size(kValidPasswordChars) - 1)];
       *p++ = c;
       ++cur_length;
       --remaining_length;
@@ -541,9 +536,9 @@
   DCHECK(sid);
 
   char sid_buffer[256];
-  DWORD sid_length = base::size(sid_buffer);
+  DWORD sid_length = std::size(sid_buffer);
   wchar_t user_domain_buffer[kWindowsDomainBufferLength];
-  DWORD domain_length = base::size(user_domain_buffer);
+  DWORD domain_length = std::size(user_domain_buffer);
   SID_NAME_USE use;
   std::wstring username_with_domain = std::wstring(domain) + L"\\" + username;
 
@@ -556,7 +551,7 @@
 
     wchar_t sid_buffer_temp[256];
     if (FAILED(GetSidFromDomainAccountInfo(domain, username, sid_buffer_temp,
-                                           base::size(sid_buffer_temp)))) {
+                                           std::size(sid_buffer_temp)))) {
       LOGFN(ERROR) << "GetSidFromDomainAccountInfo failed";
 
       return hr;
@@ -596,7 +591,7 @@
   HRESULT hr = S_OK;
   DWORD name_length = username ? username_size : 0;
   wchar_t local_domain_buffer[kWindowsDomainBufferLength];
-  DWORD domain_length = base::size(local_domain_buffer);
+  DWORD domain_length = std::size(local_domain_buffer);
   SID_NAME_USE use;
   if (!::LookupAccountSid(nullptr, psid, username, &name_length,
                           local_domain_buffer, &domain_length, &use)) {
@@ -651,7 +646,7 @@
   wchar_t domain[kWindowsDomainBufferLength];
 
   HRESULT hr = FindUserBySidWithFallback(
-      sid.c_str(), username, base::size(username), domain, base::size(domain));
+      sid.c_str(), username, std::size(username), domain, std::size(domain));
 
   if (FAILED(hr)) {
     LOGFN(ERROR) << "IsUserDomainJoined sid=" << sid << " hr=" << putHR(hr);
@@ -683,7 +678,7 @@
 
   if (SUCCEEDED(hr)) {
     // Get the gaia user's profile directory so that it can be deleted.
-    DWORD length = base::size(profiledir) - 1;
+    DWORD length = std::size(profiledir) - 1;
     if (!::GetUserProfileDirectory(token.Get(), profiledir, &length)) {
       hr = HRESULT_FROM_WIN32(::GetLastError());
       if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
diff --git a/chrome/credential_provider/gaiacp/password_recovery_manager.cc b/chrome/credential_provider/gaiacp/password_recovery_manager.cc
index 4b680004..04526a4 100644
--- a/chrome/credential_provider/gaiacp/password_recovery_manager.cc
+++ b/chrome/credential_provider/gaiacp/password_recovery_manager.cc
@@ -538,7 +538,7 @@
   std::wstring store_key = GetUserPasswordLsaStoreKey(sid);
   wchar_t password_lsa_data[1024];
   HRESULT hr = policy->RetrievePrivateData(store_key.c_str(), password_lsa_data,
-                                           base::size(password_lsa_data));
+                                           std::size(password_lsa_data));
 
   if (FAILED(hr))
     LOGFN(ERROR) << "RetrievePrivateData hr=" << putHR(hr);
diff --git a/chrome/credential_provider/gaiacp/reg_utils.cc b/chrome/credential_provider/gaiacp/reg_utils.cc
index b3bd6d6..e7fe5d4 100644
--- a/chrome/credential_provider/gaiacp/reg_utils.cc
+++ b/chrome/credential_provider/gaiacp/reg_utils.cc
@@ -7,7 +7,6 @@
 #include <atlbase.h>
 
 #include "base/base64.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
@@ -283,7 +282,7 @@
 std::wstring GetGlobalFlagOrDefault(const std::wstring& reg_key,
                                     const std::wstring& default_value) {
   wchar_t reg_value_buffer[256];
-  ULONG length = base::size(reg_value_buffer);
+  ULONG length = std::size(reg_value_buffer);
   HRESULT hr = GetGlobalFlag(reg_key, reg_value_buffer, &length);
   if (FAILED(hr))
     return default_value;
@@ -354,7 +353,7 @@
                         const std::wstring& name,
                         DWORD* value) {
   wchar_t key_name[128];
-  swprintf_s(key_name, base::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
+  swprintf_s(key_name, std::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
              sid.c_str());
   return GetMachineRegDWORD(key_name, name, value);
 }
@@ -364,7 +363,7 @@
                         wchar_t* value,
                         ULONG* length) {
   wchar_t key_name[128];
-  swprintf_s(key_name, base::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
+  swprintf_s(key_name, std::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
              sid.c_str());
   return GetMachineRegString(key_name, name, value, length);
 }
@@ -373,7 +372,7 @@
                         const std::wstring& name,
                         DWORD value) {
   wchar_t key_name[128];
-  swprintf_s(key_name, base::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
+  swprintf_s(key_name, std::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
              sid.c_str());
   return SetMachineRegDWORD(key_name, name, value);
 }
@@ -382,7 +381,7 @@
                         const std::wstring& name,
                         const std::wstring& value) {
   wchar_t key_name[128];
-  swprintf_s(key_name, base::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
+  swprintf_s(key_name, std::size(key_name), L"%s\\%s", kGcpUsersRootKeyName,
              sid.c_str());
   return SetMachineRegString(key_name, name, value);
 }
@@ -406,14 +405,14 @@
   for (; iter.Valid(); ++iter) {
     const wchar_t* sid = iter.Name();
     wchar_t gaia_id[256];
-    ULONG length = base::size(gaia_id);
+    ULONG length = std::size(gaia_id);
     HRESULT gaia_id_hr = GetUserProperty(sid, kUserId, gaia_id, &length);
     wchar_t token_handle[256];
-    length = base::size(token_handle);
+    length = std::size(token_handle);
     HRESULT token_handle_hr =
         GetUserProperty(sid, kUserTokenHandle, token_handle, &length);
     wchar_t email_address[256];
-    length = base::size(email_address);
+    length = std::size(email_address);
     HRESULT email_address_hr =
         GetUserProperty(sid, kUserEmail, email_address, &length);
     sid_to_handle_info->emplace(
@@ -435,7 +434,7 @@
   for (; iter.Valid(); ++iter) {
     const wchar_t* user_sid = iter.Name();
     wchar_t result[256];
-    ULONG result_length = base::size(result);
+    ULONG result_length = std::size(result);
     HRESULT hr = GetUserProperty(user_sid, key, result, &result_length);
     if (SUCCEEDED(hr) && value == result) {
       // Make sure there are not 2 users with the same SID.
@@ -488,7 +487,7 @@
 
     if (wcscmp(sid, user_sid) == 0) {
       wchar_t user_id[256];
-      ULONG user_length = base::size(user_id);
+      ULONG user_length = std::size(user_id);
       HRESULT hr = GetUserProperty(user_sid, kUserId, user_id, &user_length);
       if (SUCCEEDED(hr)) {
         *id = user_id;
@@ -501,7 +500,7 @@
 
 std::string GetUserEmailFromSid(const std::wstring& sid) {
   wchar_t email_id[512];
-  ULONG email_id_size = base::size(email_id);
+  ULONG email_id_size = std::size(email_id);
   HRESULT hr = GetUserProperty(sid, kUserEmail, email_id, &email_id_size);
 
   std::wstring email_id_str;
@@ -558,7 +557,7 @@
   // chrome/browser/policy/browser_dm_token_storage_win.cc:InitClientId.
   DCHECK(machine_guid);
   wchar_t machine_guid_buffer[64];
-  ULONG guid_length = base::size(machine_guid_buffer);
+  ULONG guid_length = std::size(machine_guid_buffer);
   HRESULT hr = GetMachineRegString(kMicrosoftCryptographyRegKey,
                                    kMicrosoftCryptographyMachineGuidRegKey,
                                    machine_guid_buffer, &guid_length);
@@ -579,7 +578,7 @@
 
 std::wstring GetUserDeviceResourceId(const std::wstring& sid) {
   wchar_t known_resource_id[512];
-  ULONG known_resource_id_size = base::size(known_resource_id);
+  ULONG known_resource_id_size = std::size(known_resource_id);
   HRESULT hr = GetUserProperty(sid, kRegUserDeviceResourceId, known_resource_id,
                                &known_resource_id_size);
 
diff --git a/chrome/credential_provider/gaiacp/scoped_user_profile.cc b/chrome/credential_provider/gaiacp/scoped_user_profile.cc
index cabf88df..40ef965 100644
--- a/chrome/credential_provider/gaiacp/scoped_user_profile.cc
+++ b/chrome/credential_provider/gaiacp/scoped_user_profile.cc
@@ -5,7 +5,6 @@
 #include "chrome/credential_provider/gaiacp/scoped_user_profile.h"
 
 #include <Windows.h>
-
 #include <aclapi.h>
 #include <atlcomcli.h>
 #include <atlconv.h>
@@ -20,7 +19,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -167,7 +165,7 @@
       SECURITY_CREATOR_SID_AUTHORITY;
   SID_IDENTIFIER_AUTHORITY administrators_sid_id = SECURITY_NT_AUTHORITY;
   BYTE real_owner_sid[SECURITY_MAX_SID_SIZE];
-  DWORD size_owner_sid = base::size(real_owner_sid);
+  DWORD size_owner_sid = std::size(real_owner_sid);
 
   HRESULT hr = S_OK;
 
@@ -212,7 +210,7 @@
           reinterpret_cast<wchar_t*>(creator_owner_sid)}});
 
     PACL acl = nullptr;
-    DWORD err = ::SetEntriesInAcl(base::size(ea), ea.data(), nullptr, &acl);
+    DWORD err = ::SetEntriesInAcl(std::size(ea), ea.data(), nullptr, &acl);
     if (ERROR_SUCCESS != errno) {
       hr = HRESULT_FROM_WIN32(err);
       LOGFN(ERROR) << "Failed set sids in acl hr=" << putHR(hr);
@@ -317,7 +315,7 @@
     if (!needs_to_save_original) {
       // Update the reg string for the image if it is not up to date.
       wchar_t old_picture_path[MAX_PATH];
-      ULONG path_size = base::size(old_picture_path);
+      ULONG path_size = std::size(old_picture_path);
       hr = GetAccountPictureRegString(sid, image_size, old_picture_path,
                                       &path_size);
       if (FAILED(hr) || target_picture_path.value() != old_picture_path) {
@@ -535,7 +533,7 @@
   // but administrators and SYSTEM can.
   {
     wchar_t key_name[128];
-    swprintf_s(key_name, base::size(key_name), L"%s\\%s\\%s", sid.c_str(),
+    swprintf_s(key_name, std::size(key_name), L"%s\\%s\\%s", sid.c_str(),
                kRegHkcuAccountsPath, id.c_str());
     LOGFN(VERBOSE) << "HKU\\" << key_name;
 
@@ -597,7 +595,7 @@
     std::wstring picture_url = GetDictString(properties, kKeyPicture);
     if (!picture_url.empty() && !sid.empty()) {
       wchar_t old_picture_url[512];
-      ULONG url_size = base::size(old_picture_url);
+      ULONG url_size = std::size(old_picture_url);
       hr = GetUserProperty(sid, kUserPictureUrl, old_picture_url, &url_size);
 
       UpdateProfilePicturesForWindows8AndNewer(
@@ -622,7 +620,7 @@
 
   for (int i = 0; i < kWaitForProfileCreationRetryCount; ++i) {
     ::Sleep(1000);
-    DWORD length = base::size(profile_dir);
+    DWORD length = std::size(profile_dir);
     if (::GetUserProfileDirectoryW(token_.Get(), profile_dir, &length)) {
       LOGFN(VERBOSE) << "GetUserProfileDirectoryW " << i << " " << profile_dir;
       created = true;
@@ -643,7 +641,7 @@
   // but administrators and SYSTEM can.
   base::win::RegKey key;
   wchar_t key_name[128];
-  swprintf_s(key_name, base::size(key_name), L"%s\\%s", sid.c_str(),
+  swprintf_s(key_name, std::size(key_name), L"%s\\%s", sid.c_str(),
              kRegHkcuAccountsPath);
   LOGFN(VERBOSE) << "HKU\\" << key_name;
 
diff --git a/chrome/credential_provider/setup/setup.cc b/chrome/credential_provider/setup/setup.cc
index 8253d7f..05367a57 100644
--- a/chrome/credential_provider/setup/setup.cc
+++ b/chrome/credential_provider/setup/setup.cc
@@ -53,7 +53,7 @@
 bool IsPerUserInstallFromGoogleUpdate() {
   wchar_t value[2];
   DWORD length = ::GetEnvironmentVariable(L"GoogleUpdateIsMachine", value,
-                                          base::size(value));
+                                          std::size(value));
 
   return length == 1 && value[0] == L'0';
 }
@@ -147,10 +147,10 @@
 
   wchar_t time_string[64];
   if (::GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, nullptr, nullptr,
-                        time_string, base::size(time_string)) == 0) {
+                        time_string, std::size(time_string)) == 0) {
     HRESULT last_error_hr = HRESULT_FROM_WIN32(::GetLastError());
     LOGFN(ERROR) << "GetTimeFormatEx(start) hr=" << putHR(last_error_hr);
-    wcscpy_s(time_string, base::size(time_string), L"Unknown");
+    wcscpy_s(time_string, std::size(time_string), L"Unknown");
   }
 
   LOGFN(INFO) << "Start: " << time_string;
@@ -218,10 +218,10 @@
   // process.
   if (!(is_uninstall && path.empty())) {
     if (::GetTimeFormatEx(LOCALE_NAME_USER_DEFAULT, 0, nullptr, nullptr,
-                          time_string, base::size(time_string)) == 0) {
+                          time_string, std::size(time_string)) == 0) {
       HRESULT last_error_hr = HRESULT_FROM_WIN32(::GetLastError());
       LOGFN(ERROR) << "GetTimeFormatEx(end) hr=" << putHR(last_error_hr);
-      wcscpy_s(time_string, base::size(time_string), L"Unknown");
+      wcscpy_s(time_string, std::size(time_string), L"Unknown");
     }
 
     LOGFN(INFO) << (SUCCEEDED(hr) ? "Setup completed successfully"
diff --git a/chrome/credential_provider/setup/setup_utils.cc b/chrome/credential_provider/setup/setup_utils.cc
index aed071b8..1e87a8cb 100644
--- a/chrome/credential_provider/setup/setup_utils.cc
+++ b/chrome/credential_provider/setup/setup_utils.cc
@@ -125,9 +125,9 @@
 
 std::wstring StandaloneInstallerConfigurator::GetCurrentDate() {
   static const wchar_t kDateFormat[] = L"yyyyMMdd";
-  wchar_t date_str[base::size(kDateFormat)] = {0};
+  wchar_t date_str[std::size(kDateFormat)] = {0};
   int len = GetDateFormatW(LOCALE_INVARIANT, 0, nullptr, kDateFormat, date_str,
-                           base::size(date_str));
+                           std::size(date_str));
   if (len) {
     --len;  // Subtract terminating \0.
   } else {
diff --git a/chrome/credential_provider/test/gcp_gls_output_unittest.cc b/chrome/credential_provider/test/gcp_gls_output_unittest.cc
index dd97e41..b9d919b 100644
--- a/chrome/credential_provider/test/gcp_gls_output_unittest.cc
+++ b/chrome/credential_provider/test/gcp_gls_output_unittest.cc
@@ -190,7 +190,7 @@
   std::string output_from_process;
   char buffer[1024];
   for (bool is_done = false; !is_done;) {
-    DWORD length = base::size(buffer) - 1;
+    DWORD length = std::size(buffer) - 1;
 
     DWORD ret = ::WaitForSingleObject(read_handle.Get(), kTimeout);
     if (ret == WAIT_OBJECT_0) {
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc
index 0ea7558..425b2e21 100644
--- a/chrome/credential_provider/test/gcp_setup_unittests.cc
+++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -181,9 +181,9 @@
  private:
   std::wstring GetCurrentDateForTesting() {
     static const wchar_t kDateFormat[] = L"yyyyMMdd";
-    wchar_t date_str[base::size(kDateFormat)] = {0};
+    wchar_t date_str[std::size(kDateFormat)] = {0};
     int len = GetDateFormatW(LOCALE_INVARIANT, 0, nullptr, kDateFormat,
-                             date_str, base::size(date_str));
+                             date_str, std::size(date_str));
     if (len) {
       --len;  // Subtract terminating \0.
     } else {
diff --git a/chrome/elevation_service/service_main.cc b/chrome/elevation_service/service_main.cc
index 4296b7a8..599cabb8 100644
--- a/chrome/elevation_service/service_main.cc
+++ b/chrome/elevation_service/service_main.cc
@@ -18,7 +18,6 @@
 #include <type_traits>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/win/scoped_com_initializer.h"
@@ -92,17 +91,16 @@
 
   // The pointer in this array is unowned. Do not release it.
   IClassFactory* class_factories[] = {class_factory.Get()};
-  static_assert(
-      std::extent<decltype(cookies_)>() == base::size(class_factories),
-      "Arrays cookies_ and class_factories must be the same size.");
+  static_assert(std::extent<decltype(cookies_)>() == std::size(class_factories),
+                "Arrays cookies_ and class_factories must be the same size.");
 
   IID class_ids[] = {install_static::GetElevatorClsid()};
-  DCHECK_EQ(base::size(cookies_), base::size(class_ids));
-  static_assert(std::extent<decltype(cookies_)>() == base::size(class_ids),
+  DCHECK_EQ(std::size(cookies_), std::size(class_ids));
+  static_assert(std::extent<decltype(cookies_)>() == std::size(class_ids),
                 "Arrays cookies_ and class_ids must be the same size.");
 
   hr = module.RegisterCOMObject(nullptr, class_ids, class_factories, cookies_,
-                                base::size(cookies_));
+                                std::size(cookies_));
   if (FAILED(hr)) {
     LOG(ERROR) << "RegisterCOMObject failed; hr: " << hr;
     return hr;
@@ -114,7 +112,7 @@
 void ServiceMain::UnregisterClassObject() {
   auto& module = Microsoft::WRL::Module<Microsoft::WRL::OutOfProc>::GetModule();
   const HRESULT hr =
-      module.UnregisterCOMObject(nullptr, cookies_, base::size(cookies_));
+      module.UnregisterCOMObject(nullptr, cookies_, std::size(cookies_));
   if (FAILED(hr))
     LOG(ERROR) << "UnregisterCOMObject failed; hr: " << hr;
 }
diff --git a/chrome/install_static/install_util_unittest.cc b/chrome/install_static/install_util_unittest.cc
index 504e42a..bde9ce0 100644
--- a/chrome/install_static/install_util_unittest.cc
+++ b/chrome/install_static/install_util_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <tuple>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/test/test_reg_util_win.h"
 #include "base/win/win_util.h"
@@ -362,7 +361,7 @@
       L"Chromium",
   };
 #endif
-  static_assert(base::size(kInstallDirs) == NUM_INSTALL_MODES,
+  static_assert(std::size(kInstallDirs) == NUM_INSTALL_MODES,
                 "kInstallDirs out of date.");
   EXPECT_THAT(GetChromeInstallSubDirectory(),
               StrCaseEq(kInstallDirs[std::get<0>(GetParam())]));
@@ -385,7 +384,7 @@
       L"Software\\Chromium",
   };
 #endif
-  static_assert(base::size(kRegistryPaths) == NUM_INSTALL_MODES,
+  static_assert(std::size(kRegistryPaths) == NUM_INSTALL_MODES,
                 "kRegistryPaths out of date.");
   EXPECT_THAT(GetRegistryPath(),
               StrCaseEq(kRegistryPaths[std::get<0>(GetParam())]));
@@ -411,7 +410,7 @@
       L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Chromium",
   };
 #endif
-  static_assert(base::size(kUninstallRegistryPaths) == NUM_INSTALL_MODES,
+  static_assert(std::size(kUninstallRegistryPaths) == NUM_INSTALL_MODES,
                 "kUninstallRegistryPaths out of date.");
   EXPECT_THAT(GetUninstallRegistryPath(),
               StrCaseEq(kUninstallRegistryPaths[std::get<0>(GetParam())]));
@@ -430,7 +429,7 @@
       L"{401C381F-E0DE-4B85-8BD8-3F3F14FBDA57}",  // Google Chrome Dev.
       L"{4EA16AC7-FD5A-47C3-875B-DBF4A2008C20}",  // Google Chrome SxS (Canary).
   };
-  static_assert(base::size(kAppGuids) == NUM_INSTALL_MODES,
+  static_assert(std::size(kAppGuids) == NUM_INSTALL_MODES,
                 "kAppGuids out of date.");
   EXPECT_THAT(GetAppGuid(), StrCaseEq(kAppGuids[std::get<0>(GetParam())]));
 #else
@@ -453,7 +452,7 @@
       L"Chromium",
   };
 #endif
-  static_assert(base::size(kBaseAppIds) == NUM_INSTALL_MODES,
+  static_assert(std::size(kBaseAppIds) == NUM_INSTALL_MODES,
                 "kBaseAppIds out of date.");
   EXPECT_THAT(GetBaseAppId(), StrCaseEq(kBaseAppIds[std::get<0>(GetParam())]));
 }
@@ -505,7 +504,7 @@
       L"{635EFA6F-08D6-4EC9-BD14-8A0FDE975159}"  // Chromium.
   };
 #endif
-  static_assert(base::size(kToastActivatorClsids) == NUM_INSTALL_MODES,
+  static_assert(std::size(kToastActivatorClsids) == NUM_INSTALL_MODES,
                 "kToastActivatorClsids out of date.");
 
   EXPECT_EQ(GetToastActivatorClsid(),
@@ -560,7 +559,7 @@
       L"{D133B120-6DB4-4D6B-8BFE-83BF8CA1B1B0}",  // Chromium.
   };
 #endif
-  static_assert(base::size(kElevatorClsids) == NUM_INSTALL_MODES,
+  static_assert(std::size(kElevatorClsids) == NUM_INSTALL_MODES,
                 "kElevatorClsids needs to be updated for any new modes.");
 
   EXPECT_EQ(GetElevatorClsid(), kElevatorClsids[std::get<0>(GetParam())]);
@@ -626,7 +625,7 @@
       L"{B88C45B9-8825-4629-B83E-77CC67D9CEED}",  // Chromium.
   };
 #endif
-  static_assert(base::size(kElevatorIids) == NUM_INSTALL_MODES,
+  static_assert(std::size(kElevatorIids) == NUM_INSTALL_MODES,
                 "kElevatorIids needs to be updated for any new modes.");
 
   EXPECT_EQ(GetElevatorIid(), kElevatorIids[std::get<0>(GetParam())]);
diff --git a/chrome/installer/gcapi/gcapi.cc b/chrome/installer/gcapi/gcapi.cc
index e2f500b8..2267362 100644
--- a/chrome/installer/gcapi/gcapi.cc
+++ b/chrome/installer/gcapi/gcapi.cc
@@ -334,7 +334,7 @@
   SetWindowPosParams* params = reinterpret_cast<SetWindowPosParams*>(lparam);
 
   if (!params->shunted_hwnds.count(hwnd) &&
-      ::GetClassName(hwnd, window_class, base::size(window_class)) &&
+      ::GetClassName(hwnd, window_class, std::size(window_class)) &&
       base::StartsWith(window_class, kChromeWindowClassPrefix,
                        base::CompareCase::INSENSITIVE_ASCII) &&
       ::SetWindowPos(hwnd, params->window_insert_after, params->x, params->y,
diff --git a/chrome/installer/setup/install_unittest.cc b/chrome/installer/setup/install_unittest.cc
index ec46f37e..fbf54c9 100644
--- a/chrome/installer/setup/install_unittest.cc
+++ b/chrome/installer/setup/install_unittest.cc
@@ -11,7 +11,6 @@
 #include <tuple>
 
 #include "base/base_paths.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -87,8 +86,8 @@
   // Creates a dummy test file at |path|.
   void CreateTestFile(const base::FilePath& path) {
     static constexpr char kBlah[] = "blah";
-    ASSERT_EQ(static_cast<int>(base::size(kBlah) - 1),
-              base::WriteFile(path, &kBlah[0], base::size(kBlah) - 1));
+    ASSERT_EQ(static_cast<int>(std::size(kBlah) - 1),
+              base::WriteFile(path, &kBlah[0], std::size(kBlah) - 1));
   }
 
   // Creates the VisualElements directory and a light asset, if testing such.
@@ -288,7 +287,7 @@
     };
 
     std::string initial_prefs("{\"distribution\":{");
-    for (size_t i = 0; i < base::size(desired_prefs); ++i) {
+    for (size_t i = 0; i < std::size(desired_prefs); ++i) {
       initial_prefs += (i == 0 ? "\"" : ",\"");
       initial_prefs += desired_prefs[i].pref_name;
       initial_prefs += "\":";
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index cbc7018f..8984011 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -19,7 +19,6 @@
 
 #include "base/at_exit.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/file_version_info.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -225,7 +224,7 @@
   constexpr DWORD kWaitForStartTimeoutMs = 30 * 1000;
   const HANDLE handles[] = {start_event.Get(), writer.Handle()};
   auto wait_result =
-      ::WaitForMultipleObjects(base::size(handles), &handles[0],
+      ::WaitForMultipleObjects(std::size(handles), &handles[0],
                                /*bWaitAll=*/FALSE, kWaitForStartTimeoutMs);
   if (wait_result == WAIT_OBJECT_0) {
     VLOG(1) << "Proceeding after waiting for DisplayVersion overwrite child.";
@@ -364,7 +363,7 @@
     std::wstring value_name(value_iter.Name());
     if (base::StartsWith(value_name, kMsiProductIdPrefix,
                          base::CompareCase::INSENSITIVE_ASCII)) {
-      return value_name.substr(base::size(kMsiProductIdPrefix) - 1);
+      return value_name.substr(std::size(kMsiProductIdPrefix) - 1);
     }
   }
   return std::wstring();
diff --git a/chrome/installer/setup/setup_util.cc b/chrome/installer/setup/setup_util.cc
index 9f4425a..2cdbf72 100644
--- a/chrome/installer/setup/setup_util.cc
+++ b/chrome/installer/setup/setup_util.cc
@@ -25,7 +25,6 @@
 #include "base/check.h"
 #include "base/command_line.h"
 #include "base/cpu.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -265,7 +264,7 @@
       L"%SystemRoot%\\System32\\rundll32.exe";
   wchar_t rundll32[MAX_PATH];
   DWORD size =
-      ExpandEnvironmentStrings(kRunDll32Path, rundll32, base::size(rundll32));
+      ExpandEnvironmentStrings(kRunDll32Path, rundll32, std::size(rundll32));
   if (!size || size >= MAX_PATH)
     return false;
 
@@ -359,7 +358,7 @@
       "app-host",
       "app-launcher",
   };
-  for (size_t i = 0; i < base::size(kLegacySwitches); ++i) {
+  for (size_t i = 0; i < std::size(kLegacySwitches); ++i) {
     if (cmd_line.HasSwitch(kLegacySwitches[i]))
       return true;
   }
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index b5c6a23..493d216 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -18,7 +18,6 @@
 
 #include "base/base_paths.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -513,7 +512,7 @@
   // but doesn't seem to do so when manually deleting the user-level keys it
   // created.
   std::wstring alternate_active_setup_path(active_setup_path);
-  alternate_active_setup_path.insert(base::size("Software\\") - 1,
+  alternate_active_setup_path.insert(std::size("Software\\") - 1,
                                      L"Wow6432Node\\");
 
   VLOG(1) << "Uninstall per-user Active Setup keys.";
@@ -741,7 +740,7 @@
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING
 
   HKEY roots[] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
-  for (size_t i = 0; i < base::size(roots); ++i) {
+  for (size_t i = 0; i < std::size(roots); ++i) {
     std::wstring suffix;
     if (roots[i] == HKEY_LOCAL_MACHINE)
       suffix = ShellUtil::GetCurrentInstallationSuffix(chrome_exe);
diff --git a/chrome/installer/setup/user_experiment.cc b/chrome/installer/setup/user_experiment.cc
index 439cfcb..4e47c87a 100644
--- a/chrome/installer/setup/user_experiment.cc
+++ b/chrome/installer/setup/user_experiment.cc
@@ -14,7 +14,6 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/process/launch.h"
@@ -279,7 +278,7 @@
       kExperimentRetryDelay,
   };
   setup_command.CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
-                                 kSwitchesToCopy, base::size(kSwitchesToCopy));
+                                 kSwitchesToCopy, std::size(kSwitchesToCopy));
 
   if (user_context) {
     // This is either a per-user install or a per-machine install run via
diff --git a/chrome/installer/test/alternate_version_generator.cc b/chrome/installer/test/alternate_version_generator.cc
index 39026b5..280bb294 100644
--- a/chrome/installer/test/alternate_version_generator.cc
+++ b/chrome/installer/test/alternate_version_generator.cc
@@ -36,7 +36,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -146,20 +145,19 @@
 
 std::wstring ChromeVersion::ToString() const {
   wchar_t buffer[24];
-  int string_len =
-      swprintf_s(&buffer[0], base::size(buffer), L"%hu.%hu.%hu.%hu", major(),
-                 minor(), build(), patch());
+  int string_len = swprintf_s(&buffer[0], std::size(buffer), L"%hu.%hu.%hu.%hu",
+                              major(), minor(), build(), patch());
   DCHECK_NE(-1, string_len);
-  DCHECK_GT(static_cast<int>(base::size(buffer)), string_len);
+  DCHECK_GT(static_cast<int>(std::size(buffer)), string_len);
   return std::wstring(&buffer[0], string_len);
 }
 
 std::string ChromeVersion::ToASCII() const {
   char buffer[24];
-  int string_len = sprintf_s(&buffer[0], base::size(buffer), "%hu.%hu.%hu.%hu",
+  int string_len = sprintf_s(&buffer[0], std::size(buffer), "%hu.%hu.%hu.%hu",
                              major(), minor(), build(), patch());
   DCHECK_NE(-1, string_len);
-  DCHECK_GT(static_cast<int>(base::size(buffer)), string_len);
+  DCHECK_GT(static_cast<int>(std::size(buffer)), string_len);
   return std::string(&buffer[0], string_len);
 }
 
diff --git a/chrome/installer/test/alternate_version_generator_main.cc b/chrome/installer/test/alternate_version_generator_main.cc
index 4f74cee..01762e3 100644
--- a/chrome/installer/test/alternate_version_generator_main.cc
+++ b/chrome/installer/test/alternate_version_generator_main.cc
@@ -13,7 +13,6 @@
 #include "base/at_exit.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
@@ -50,7 +49,7 @@
 
 const wchar_t* GetErrorMessage(ErrorCode error_code) {
   DCHECK_LE(0, error_code);
-  DCHECK_GT(base::size(Messages), static_cast<size_t>(error_code));
+  DCHECK_GT(std::size(Messages), static_cast<size_t>(error_code));
   return Messages[error_code];
 }
 
diff --git a/chrome/installer/util/advanced_firewall_manager_win.cc b/chrome/installer/util/advanced_firewall_manager_win.cc
index 5d999ac..41db300 100644
--- a/chrome/installer/util/advanced_firewall_manager_win.cc
+++ b/chrome/installer/util/advanced_firewall_manager_win.cc
@@ -7,7 +7,6 @@
 #include <objbase.h>
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/guid.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
@@ -50,7 +49,7 @@
   // The most-restrictive active profile takes precedence.
   const NET_FW_PROFILE_TYPE2 kProfileTypes[] = {
       NET_FW_PROFILE2_PUBLIC, NET_FW_PROFILE2_PRIVATE, NET_FW_PROFILE2_DOMAIN};
-  for (size_t i = 0; i < base::size(kProfileTypes); ++i) {
+  for (size_t i = 0; i < std::size(kProfileTypes); ++i) {
     if ((profile_types & kProfileTypes[i]) != 0) {
       VARIANT_BOOL enabled = VARIANT_TRUE;
       hr = firewall_policy_->get_FirewallEnabled(kProfileTypes[i], &enabled);
diff --git a/chrome/installer/util/app_command.cc b/chrome/installer/util/app_command.cc
index 0e777e993..f372a4a 100644
--- a/chrome/installer/util/app_command.cc
+++ b/chrome/installer/util/app_command.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/win/registry.h"
 #include "chrome/installer/util/google_update_constants.h"
@@ -55,7 +54,7 @@
 
   command_line_.swap(cmd_line);
 
-  for (size_t i = 0; i < base::size(kNameBoolVars); ++i) {
+  for (size_t i = 0; i < std::size(kNameBoolVars); ++i) {
     DWORD value = 0;  // Set default to false.
     // Note: ReadValueDW only modifies out param on success.
     key.ReadValueDW(kNameBoolVars[i].name, &value);
@@ -79,7 +78,7 @@
                                command_line_, true)
       ->set_log_message("setting AppCommand CommandLine registry value");
 
-  for (size_t i = 0; i < base::size(kNameBoolVars); ++i) {
+  for (size_t i = 0; i < std::size(kNameBoolVars); ++i) {
     const wchar_t* var_name = kNameBoolVars[i].name;
     bool var_data = this->*(kNameBoolVars[i].data);
 
diff --git a/chrome/installer/util/auto_launch_util.cc b/chrome/installer/util/auto_launch_util.cc
index ba5093d..c18919a4 100644
--- a/chrome/installer/util/auto_launch_util.cc
+++ b/chrome/installer/util/auto_launch_util.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/notreached.h"
 #include "base/path_service.h"
@@ -41,9 +40,9 @@
 
   std::string input(path.AsUTF8Unsafe());
   uint8_t hash[16];
-  crypto::SHA256HashString(input, hash, base::size(hash));
+  crypto::SHA256HashString(input, hash, std::size(hash));
   return std::wstring(kAutolaunchKeyValue) + L"_" +
-         base::ASCIIToWide(base::HexEncode(hash, base::size(hash)));
+         base::ASCIIToWide(base::HexEncode(hash, std::size(hash)));
 }
 
 }  // namespace
diff --git a/chrome/installer/util/delete_after_reboot_helper_unittest.cc b/chrome/installer/util/delete_after_reboot_helper_unittest.cc
index cc38718..08e3944 100644
--- a/chrome/installer/util/delete_after_reboot_helper_unittest.cc
+++ b/chrome/installer/util/delete_after_reboot_helper_unittest.cc
@@ -11,7 +11,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
@@ -117,7 +116,7 @@
       {L"deletes", L"foo\0\0bar\0\0bizz\0\0", 16 * sizeof(wchar_t), 3},
   };
 
-  for (size_t i = 0; i < base::size(tests); i++) {
+  for (size_t i = 0; i < std::size(tests); i++) {
     std::vector<PendingMove> string_list;
     EXPECT_TRUE(SUCCEEDED(
         MultiSZBytesToStringArray(reinterpret_cast<const char*>(tests[i].str),
@@ -137,7 +136,7 @@
       {L"malformed", reinterpret_cast<const wchar_t*>("oddnumb\0\0"), 9, 1},
   };
 
-  for (size_t i = 0; i < base::size(failures); i++) {
+  for (size_t i = 0; i < std::size(failures); i++) {
     std::vector<PendingMove> string_list;
     EXPECT_FALSE(SUCCEEDED(MultiSZBytesToStringArray(
         reinterpret_cast<const char*>(failures[i].str), failures[i].length,
@@ -174,7 +173,7 @@
   // Check that each of the deletes we expect are there in order.
   base::FilePath expected_paths[] = {temp_file_, temp_subdir_file_,
                                      temp_subdir_, temp_dir_};
-  for (size_t i = 0; i < base::size(expected_paths); ++i) {
+  for (size_t i = 0; i < std::size(expected_paths); ++i) {
     EXPECT_FALSE(iter == pending_moves.end());
     if (iter != pending_moves.end()) {
       base::FilePath short_path_name(GetShortPathName(expected_paths[i]));
@@ -228,7 +227,7 @@
   // Check that each of the deletes we expect are there in order.
   base::FilePath expected_paths[] = {temp_file_, temp_subdir_file_,
                                      temp_subdir_, temp_dir_};
-  for (size_t i = 0; i < base::size(expected_paths); ++i) {
+  for (size_t i = 0; i < std::size(expected_paths); ++i) {
     EXPECT_FALSE(iter == pending_moves.end());
     if (iter != pending_moves.end()) {
       base::FilePath short_path_name(GetShortPathName(expected_paths[i]));
diff --git a/chrome/installer/util/delete_reg_key_work_item_unittest.cc b/chrome/installer/util/delete_reg_key_work_item_unittest.cc
index 5532faa6..a0dec0e 100644
--- a/chrome/installer/util/delete_reg_key_work_item_unittest.cc
+++ b/chrome/installer/util/delete_reg_key_work_item_unittest.cc
@@ -11,7 +11,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/win/registry.h"
 #include "chrome/installer/util/registry_test_data.h"
@@ -38,7 +37,7 @@
       std::wstring(test_data_.base_path() + L"\\NoKeyHere"),
       std::wstring(test_data_.base_path() + L"\\NoKeyHere\\OrHere")};
   RegKey key;
-  for (size_t i = 0; i < base::size(key_paths); ++i) {
+  for (size_t i = 0; i < std::size(key_paths); ++i) {
     const std::wstring& key_path = key_paths[i];
     std::unique_ptr<DeleteRegKeyWorkItem> item(
         WorkItem::CreateDeleteRegKeyWorkItem(test_data_.root_key(), key_path,
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc
index 94a953d..9ada591 100644
--- a/chrome/installer/util/google_update_settings_unittest.cc
+++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/base_paths.h"
-#include "base/cxx17_backports.h"
 #include "base/path_service.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_path_override.h"
@@ -223,7 +222,7 @@
                          installer::INSTALL_FAILED};
   const wchar_t* const plain[] = {L"", L"1.1", L"1.1-dev"};
   const wchar_t* const full[] = {L"-full", L"1.1-full", L"1.1-dev-full"};
-  static_assert(base::size(full) == base::size(plain), "bad full array size");
+  static_assert(std::size(full) == std::size(plain), "bad full array size");
   const wchar_t* const* input_arrays[] = {plain, full};
   for (const installer::ArchiveType archive_type : archive_types) {
     SCOPED_TRACE(::testing::Message()
@@ -259,7 +258,7 @@
           else
             outputs = plain;
         }
-        for (size_t input_idx = 0; input_idx < base::size(plain); ++input_idx) {
+        for (size_t input_idx = 0; input_idx < std::size(plain); ++input_idx) {
           const wchar_t* input = inputs[input_idx];
           const wchar_t* output = outputs[input_idx];
           SCOPED_TRACE(::testing::Message() << "input=\"" << input << "\"");
diff --git a/chrome/installer/util/initial_preferences.cc b/chrome/installer/util/initial_preferences.cc
index e7c3c27..40f67389 100644
--- a/chrome/installer/util/initial_preferences.cc
+++ b/chrome/installer/util/initial_preferences.cc
@@ -8,7 +8,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
 #include "base/json/json_string_value_serializer.h"
@@ -140,7 +139,7 @@
   };
 
   std::string name(installer::initial_preferences::kDistroDict);
-  for (size_t i = 0; i < base::size(translate_switches); ++i) {
+  for (size_t i = 0; i < std::size(translate_switches); ++i) {
     if (cmd_line.HasSwitch(translate_switches[i].cmd_line_switch)) {
       name.assign(installer::initial_preferences::kDistroDict);
       name.append(".").append(translate_switches[i].distribution_switch);
diff --git a/chrome/installer/util/initial_preferences_unittest.cc b/chrome/installer/util/initial_preferences_unittest.cc
index e570b531..8854c0d 100644
--- a/chrome/installer/util/initial_preferences_unittest.cc
+++ b/chrome/installer/util/initial_preferences_unittest.cc
@@ -10,7 +10,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
@@ -110,7 +109,7 @@
       installer::initial_preferences::kRequireEula,
   };
 
-  for (size_t i = 0; i < base::size(expected_true); ++i) {
+  for (size_t i = 0; i < std::size(expected_true); ++i) {
     bool value = false;
     EXPECT_TRUE(prefs.GetBool(expected_true[i], &value));
     EXPECT_TRUE(value) << expected_true[i];
@@ -151,7 +150,7 @@
   };
 
   bool value = false;
-  for (size_t i = 0; i < base::size(expected_bool); ++i) {
+  for (size_t i = 0; i < std::size(expected_bool); ++i) {
     EXPECT_TRUE(prefs.GetBool(expected_bool[i].name, &value));
     EXPECT_EQ(value, expected_bool[i].expected_value) << expected_bool[i].name;
   }
@@ -162,7 +161,7 @@
       installer::initial_preferences::kMakeChromeDefaultForUser,
   };
 
-  for (size_t i = 0; i < base::size(missing_bools); ++i) {
+  for (size_t i = 0; i < std::size(missing_bools); ++i) {
     EXPECT_FALSE(prefs.GetBool(missing_bools[i], &value)) << missing_bools[i];
   }
 
@@ -264,7 +263,7 @@
 
   // Now check that prefs got merged correctly.
   bool value = false;
-  for (size_t i = 0; i < base::size(expected_bool); ++i) {
+  for (size_t i = 0; i < std::size(expected_bool); ++i) {
     EXPECT_TRUE(prefs.GetBool(expected_bool[i].name, &value));
     EXPECT_EQ(value, expected_bool[i].expected_value) << expected_bool[i].name;
   }
@@ -281,7 +280,7 @@
       {installer::initial_preferences::kDoNotLaunchChrome, true},
   };
 
-  for (size_t i = 0; i < base::size(expected_bool2); ++i) {
+  for (size_t i = 0; i < std::size(expected_bool2); ++i) {
     EXPECT_TRUE(prefs2.GetBool(expected_bool2[i].name, &value));
     EXPECT_EQ(value, expected_bool2[i].expected_value)
         << expected_bool2[i].name;
diff --git a/chrome/installer/util/install_service_work_item_unittest.cc b/chrome/installer/util/install_service_work_item_unittest.cc
index 99ec95aa..3760cca 100644
--- a/chrome/installer/util/install_service_work_item_unittest.cc
+++ b/chrome/installer/util/install_service_work_item_unittest.cc
@@ -3,19 +3,18 @@
 // found in the LICENSE file.
 
 #include "chrome/installer/util/install_service_work_item.h"
-#include "chrome/installer/util/install_service_work_item_impl.h"
 
 #include <memory>
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/strings/stringprintf.h"
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome/install_static/test/scoped_install_details.h"
+#include "chrome/installer/util/install_service_work_item_impl.h"
 #include "chrome/installer/util/work_item.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -182,7 +181,7 @@
   std::vector<wchar_t> vec =
       InstallServiceWorkItemImpl::MultiSzToVector(kZeroMultiSz);
   EXPECT_TRUE(!memcmp(vec.data(), &kZeroMultiSz, sizeof(kZeroMultiSz)));
-  EXPECT_EQ(vec.size(), base::size(kZeroMultiSz));
+  EXPECT_EQ(vec.size(), std::size(kZeroMultiSz));
 
   vec = InstallServiceWorkItemImpl::MultiSzToVector(nullptr);
   EXPECT_TRUE(vec.empty());
@@ -190,12 +189,12 @@
   constexpr wchar_t kRpcMultiSz[] = L"RPCSS\0";
   vec = InstallServiceWorkItemImpl::MultiSzToVector(kRpcMultiSz);
   EXPECT_TRUE(!memcmp(vec.data(), &kRpcMultiSz, sizeof(kRpcMultiSz)));
-  EXPECT_EQ(vec.size(), base::size(kRpcMultiSz));
+  EXPECT_EQ(vec.size(), std::size(kRpcMultiSz));
 
   constexpr wchar_t kMultiSz[] = L"RPCSS\0LSASS\0";
   vec = InstallServiceWorkItemImpl::MultiSzToVector(kMultiSz);
   EXPECT_TRUE(!memcmp(vec.data(), &kMultiSz, sizeof(kMultiSz)));
-  EXPECT_EQ(vec.size(), base::size(kMultiSz));
+  EXPECT_EQ(vec.size(), std::size(kMultiSz));
 }
 
 TEST_F(InstallServiceWorkItemTest, Do_FreshInstall) {
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc
index 6b0fa8e..262ae7898 100644
--- a/chrome/installer/util/install_util.cc
+++ b/chrome/installer/util/install_util.cc
@@ -16,7 +16,6 @@
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
@@ -494,9 +493,9 @@
 // static
 std::wstring InstallUtil::GetCurrentDate() {
   static const wchar_t kDateFormat[] = L"yyyyMMdd";
-  wchar_t date_str[base::size(kDateFormat)] = {0};
+  wchar_t date_str[std::size(kDateFormat)] = {0};
   int len = GetDateFormatW(LOCALE_INVARIANT, 0, nullptr, kDateFormat, date_str,
-                           base::size(date_str));
+                           std::size(date_str));
   if (len) {
     --len;  // Subtract terminating \0.
   } else {
diff --git a/chrome/installer/util/install_util_unittest.cc b/chrome/installer/util/install_util_unittest.cc
index 2bbe295..d1170b0 100644
--- a/chrome/installer/util/install_util_unittest.cc
+++ b/chrome/installer/util/install_util_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/base_paths.h"
 #include "base/command_line.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"
@@ -413,7 +412,7 @@
   // Tests where the expected file exists.
   static const char data[] = "data";
   ASSERT_TRUE(base::CreateDirectory(some_long_dir));
-  ASSERT_NE(-1, base::WriteFile(expect, data, base::size(data) - 1));
+  ASSERT_NE(-1, base::WriteFile(expect, data, std::size(data) - 1));
   // Paths don't match.
   EXPECT_FALSE(InstallUtil::ProgramCompare(expect).Evaluate(
       L"\"" + other.value() + L"\""));
diff --git a/chrome/installer/util/l10n_string_util.cc b/chrome/installer/util/l10n_string_util.cc
index 618ec52b..927557d 100644
--- a/chrome/installer/util/l10n_string_util.cc
+++ b/chrome/installer/util/l10n_string_util.cc
@@ -15,7 +15,6 @@
 
 #include "base/bind.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
@@ -132,12 +131,12 @@
 
 int GetBaseMessageIdForMode(int base_message_id) {
 // Generate the constants holding the mode-specific resource ID arrays.
-#define HANDLE_MODE_STRING(id, ...)                                    \
-  static constexpr int k##id##Strings[] = {__VA_ARGS__};               \
-  static_assert(                                                       \
-      base::size(k##id##Strings) == install_static::NUM_INSTALL_MODES, \
-      "resource " #id                                                  \
-      " has the wrong number of mode-specific "                        \
+#define HANDLE_MODE_STRING(id, ...)                                   \
+  static constexpr int k##id##Strings[] = {__VA_ARGS__};              \
+  static_assert(                                                      \
+      std::size(k##id##Strings) == install_static::NUM_INSTALL_MODES, \
+      "resource " #id                                                 \
+      " has the wrong number of mode-specific "                       \
       "strings.");
   DO_MODE_STRINGS
 #undef HANDLE_MODE_STRING
diff --git a/chrome/installer/util/move_tree_work_item_unittest.cc b/chrome/installer/util/move_tree_work_item_unittest.cc
index 966427e..aadd9df 100644
--- a/chrome/installer/util/move_tree_work_item_unittest.cc
+++ b/chrome/installer/util/move_tree_work_item_unittest.cc
@@ -10,7 +10,6 @@
 #include <memory>
 
 #include "base/base_paths.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/strings/string_util.h"
@@ -46,7 +45,7 @@
   std::wifstream file;
   file.open(base::WideToASCII(path.value()).c_str());
   EXPECT_TRUE(file.is_open());
-  file.getline(contents, base::size(contents));
+  file.getline(contents, std::size(contents));
   file.close();
   return std::wstring(contents);
 }
diff --git a/chrome/installer/util/self_cleaning_temp_dir_unittest.cc b/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
index 05d7e4e9..6f72446 100644
--- a/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
+++ b/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/installer/util/self_cleaning_temp_dir.h"
+
 #include <windows.h>
 #include <stdint.h>
 #include <wincrypt.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/strings/string_number_conversions.h"
-#include "chrome/installer/util/self_cleaning_temp_dir.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -25,11 +25,11 @@
   // seen the latter trivially repeat.
   EXPECT_NE(FALSE, CryptAcquireContext(&crypt_ctx, nullptr, nullptr,
                                        PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
-  EXPECT_NE(FALSE, CryptGenRandom(crypt_ctx, base::size(data), &data[0]));
+  EXPECT_NE(FALSE, CryptGenRandom(crypt_ctx, std::size(data), &data[0]));
   EXPECT_NE(FALSE, CryptReleaseContext(crypt_ctx, 0));
 
   // Hexify the value.
-  std::string result(base::HexEncode(&data[0], base::size(data)));
+  std::string result(base::HexEncode(&data[0], std::size(data)));
   EXPECT_EQ(8u, result.size());
 
   // Replace the first digit with the letter 'R' (for "random", get it?).
@@ -164,9 +164,9 @@
     EXPECT_EQ(parent_temp_dir.Append(L"Three"), temp_dir.path());
     EXPECT_TRUE(base::DirectoryExists(temp_dir.path()));
     // Drop a file somewhere.
-    EXPECT_EQ(static_cast<int>(base::size(kHiHon) - 1),
+    EXPECT_EQ(static_cast<int>(std::size(kHiHon) - 1),
               base::WriteFile(parent_temp_dir.AppendASCII(GetRandomFilename()),
-                              kHiHon, base::size(kHiHon) - 1));
+                              kHiHon, std::size(kHiHon) - 1));
   }
   EXPECT_FALSE(base::DirectoryExists(parent_temp_dir.Append(L"Three")));
   EXPECT_TRUE(base::DirectoryExists(parent_temp_dir));
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 10435dc..7aa05b6 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -25,7 +25,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -166,7 +165,7 @@
   base::MD5Sum(user_sid_ascii.c_str(), user_sid_ascii.length(), &md5_digest);
   std::string base32_md5 = base32::Base32Encode(
       base::StringPiece(reinterpret_cast<char*>(md5_digest.a),
-                        base::size(md5_digest.a)),
+                        std::size(md5_digest.a)),
       base32::Base32EncodePolicy::OMIT_PADDING);
   // The value returned by the base32 algorithm above must never change.
   DCHECK_EQ(base32_md5.length(), 26U);
@@ -1368,7 +1367,7 @@
   };
   base::CommandLine desired_args(base::CommandLine::NO_PROGRAM);
   desired_args.CopySwitchesFrom(current_args, kept_switches,
-                                base::size(kept_switches));
+                                std::size(kept_switches));
   if (desired_args.argv().size() == current_args.argv().size())
     return true;
   if (shortcuts)
@@ -2153,7 +2152,7 @@
   // to show up in Add/Remove programs for us.
   static const wchar_t* const kChromeProtocols[] = {L"http", L"https"};
   DefaultState default_state = ProbeProtocolHandlers(
-      chrome_exe, kChromeProtocols, base::size(kChromeProtocols));
+      chrome_exe, kChromeProtocols, std::size(kChromeProtocols));
   UpdateDefaultBrowserBeaconWithState(default_state);
   return default_state;
 }
@@ -2170,7 +2169,7 @@
   }
 
   const wchar_t* const protocols[] = {protocol.c_str()};
-  return ProbeProtocolHandlers(chrome_exe, protocols, base::size(protocols));
+  return ProbeProtocolHandlers(chrome_exe, protocols, std::size(protocols));
 }
 
 // static
@@ -2614,7 +2613,7 @@
 
 bool ShellUtil::GetOldUserSpecificRegistrySuffix(std::wstring* suffix) {
   wchar_t user_name[256];
-  DWORD size = base::size(user_name);
+  DWORD size = std::size(user_name);
   if (::GetUserName(user_name, &size) == 0 || size < 1) {
     NOTREACHED();
     return false;
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc
index bbd4c11..5456b5e 100644
--- a/chrome/installer/util/shell_util_unittest.cc
+++ b/chrome/installer/util/shell_util_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/base_paths.h"
 #include "base/base_paths_win.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -1096,7 +1095,7 @@
 
   static const std::set<std::wstring> FileExtensions() {
     std::set<std::wstring> file_extensions;
-    for (size_t i = 0; i < base::size(kTestFileExtensions); ++i)
+    for (size_t i = 0; i < std::size(kTestFileExtensions); ++i)
       file_extensions.insert(kTestFileExtensions[i]);
     return file_extensions;
   }
@@ -1523,7 +1522,7 @@
   ASSERT_TRUE(base::StartsWith(suffix, L".", base::CompareCase::SENSITIVE));
 
   wchar_t user_name[256];
-  DWORD size = base::size(user_name);
+  DWORD size = std::size(user_name);
   ASSERT_NE(0, ::GetUserName(user_name, &size));
   ASSERT_GE(size, 1U);
   ASSERT_STREQ(user_name, suffix.substr(1).c_str());
diff --git a/chrome/notification_helper/com_server_module.cc b/chrome/notification_helper/com_server_module.cc
index 6edf4d5..094fc9e 100644
--- a/chrome/notification_helper/com_server_module.cc
+++ b/chrome/notification_helper/com_server_module.cc
@@ -11,11 +11,10 @@
 
 #include "chrome/notification_helper/com_server_module.h"
 
-#include <type_traits>
-
 #include <wrl/module.h>
 
-#include "base/cxx17_backports.h"
+#include <type_traits>
+
 #include "base/metrics/histogram_macros.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome/notification_helper/notification_activator.h"
@@ -102,12 +101,11 @@
 
   // All pointers in this array are unowned. Do not release them.
   IClassFactory* class_factories[] = {class_factory.Get()};
-  static_assert(
-      std::extent<decltype(cookies_)>() == base::size(class_factories),
-      "Arrays cookies_ and class_factories must be the same size.");
+  static_assert(std::extent<decltype(cookies_)>() == std::size(class_factories),
+                "Arrays cookies_ and class_factories must be the same size.");
 
   IID class_ids[] = {install_static::GetToastActivatorClsid()};
-  static_assert(std::extent<decltype(cookies_)>() == base::size(class_ids),
+  static_assert(std::extent<decltype(cookies_)>() == std::size(class_ids),
                 "Arrays cookies_ and class_ids must be the same size.");
 
   hr = module.RegisterCOMObject(nullptr, class_ids, class_factories, cookies_,
diff --git a/chrome/notification_helper/trace_util.cc b/chrome/notification_helper/trace_util.cc
index 6bfcd220..dd988b7d 100644
--- a/chrome/notification_helper/trace_util.cc
+++ b/chrome/notification_helper/trace_util.cc
@@ -9,8 +9,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
-
 #if !defined(NDEBUG)
 // Sends string |format| to the debugger for display.
 //
@@ -23,7 +21,7 @@
   va_list args = {};
 
   va_start(args, format);
-  if (vswprintf(buffer, base::size(buffer), format, args) > 0) {
+  if (vswprintf(buffer, std::size(buffer), format, args) > 0) {
     OutputDebugString(buffer);
   } else {
     std::wstring error_string(L"Format error for string: ");
diff --git a/chrome/renderer/app_categorizer_unittest.cc b/chrome/renderer/app_categorizer_unittest.cc
index c4eac770..55b2d7d 100644
--- a/chrome/renderer/app_categorizer_unittest.cc
+++ b/chrome/renderer/app_categorizer_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/renderer/app_categorizer.h"
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -38,11 +37,11 @@
 }  // namespace
 
 TEST(AppCategorizerTest, IsHangoutsUrl) {
-  for (size_t i = 0; i < base::size(kChatAppURLs); ++i) {
+  for (size_t i = 0; i < std::size(kChatAppURLs); ++i) {
     EXPECT_TRUE(AppCategorizer::IsHangoutsUrl(GURL(kChatAppURLs[i])));
   }
 
-  for (size_t i = 0; i < base::size(kBadChatAppURLs); ++i) {
+  for (size_t i = 0; i < std::size(kBadChatAppURLs); ++i) {
     EXPECT_FALSE(AppCategorizer::IsHangoutsUrl(GURL(kBadChatAppURLs[i])));
   }
 }
@@ -50,12 +49,12 @@
 TEST(AppCategorizerTest, IsWhitelistedApp) {
   // Hangouts app
   {
-    EXPECT_EQ(base::size(kChatAppURLs), base::size(kChatManifestFSs));
-    for (size_t i = 0; i < base::size(kChatAppURLs); ++i) {
+    EXPECT_EQ(std::size(kChatAppURLs), std::size(kChatManifestFSs));
+    for (size_t i = 0; i < std::size(kChatAppURLs); ++i) {
       EXPECT_TRUE(AppCategorizer::IsWhitelistedApp(
           GURL(kChatManifestFSs[i]), GURL(kChatAppURLs[i])));
     }
-    for (size_t i = 0; i < base::size(kBadChatAppURLs); ++i) {
+    for (size_t i = 0; i < std::size(kBadChatAppURLs); ++i) {
       EXPECT_FALSE(AppCategorizer::IsWhitelistedApp(
           GURL("filesystem:https://irrelevant.com/"),
           GURL(kBadChatAppURLs[i])));
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index d3efb139..9b63c15eab 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -7,7 +7,6 @@
 #include <string>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
@@ -577,7 +576,7 @@
         "Go\naway!"},
     };
     TestFormFillFunctions(
-        html, unowned, url_override, field_cases, base::size(field_cases),
+        html, unowned, url_override, field_cases, std::size(field_cases),
         mojom::RendererFormDataAction::kFill, &GetValueWrapper);
     // Verify preview selection.
     WebInputElement firstname = GetInputElementById("firstname");
@@ -653,7 +652,7 @@
         ""},
     };
     TestFormFillFunctions(
-        html, unowned, url_override, field_cases, base::size(field_cases),
+        html, unowned, url_override, field_cases, std::size(field_cases),
         mojom::RendererFormDataAction::kPreview, &GetSuggestedValueWrapper);
 
     // Verify preview selection.
@@ -2731,7 +2730,7 @@
   };
 
   WebDocument document = frame->GetDocument();
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     WebFormControlElement element = GetFormControlElementById(
         WebString::FromASCII(test_cases[i].element_id));
     FormFieldData result;
diff --git a/chrome/renderer/extensions/custom_types_unittest.cc b/chrome/renderer/extensions/custom_types_unittest.cc
index fd005771..dc7f564 100644
--- a/chrome/renderer/extensions/custom_types_unittest.cc
+++ b/chrome/renderer/extensions/custom_types_unittest.cc
@@ -2,10 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/renderer/storage_area.h"
-
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/test/values_test_util.h"
 #include "components/crx_file/id_util.h"
 #include "extensions/common/extension_builder.h"
@@ -18,6 +15,7 @@
 #include "extensions/renderer/native_extension_bindings_system.h"
 #include "extensions/renderer/native_extension_bindings_system_test_base.h"
 #include "extensions/renderer/script_context.h"
+#include "extensions/renderer/storage_area.h"
 
 namespace extensions {
 
@@ -65,12 +63,12 @@
     v8::Local<v8::Function> use_api =
         FunctionFromString(context, use_api_script);
     v8::Local<v8::Value> args[] = {api_object};
-    RunFunction(use_api, context, base::size(args), args);
+    RunFunction(use_api, context, std::size(args), args);
 
     DisposeContext(context);
 
     EXPECT_FALSE(binding::IsContextValid(context));
-    RunFunctionAndExpectError(use_api, context, base::size(args), args,
+    RunFunctionAndExpectError(use_api, context, std::size(args), args,
                               "Uncaught Error: Extension context invalidated.");
   }
 
@@ -135,7 +133,7 @@
         FunctionFromString(context, kRunGetContentSetting);
     v8::Local<v8::Value> args[] = {settings};
     v8::Local<v8::Value> return_value = RunFunctionOnGlobal(
-        run_get_content_setting, context, base::size(args), args);
+        run_get_content_setting, context, std::size(args), args);
 
     ASSERT_TRUE(return_value->IsPromise());
     v8::Local<v8::Promise> promise = return_value.As<v8::Promise>();
@@ -169,7 +167,7 @@
         FunctionFromString(context, kRunSetContentSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_set_content_setting, context, base::size(args), args,
+        run_set_content_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError(
                 "contentSettings.ContentSetting.set",
@@ -207,7 +205,7 @@
         FunctionFromString(context, kRunGetContentSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_get_content_setting, context, base::size(args), args,
+        run_get_content_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError("contentSettings.ContentSetting.get",
                                         "object details, function callback",
@@ -223,7 +221,7 @@
         FunctionFromString(context, kRunSetContentSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_set_content_setting, context, base::size(args), args,
+        run_set_content_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError(
                 "contentSettings.ContentSetting.set",
@@ -263,7 +261,7 @@
         FunctionFromString(context, kRunGetChromeSetting);
     v8::Local<v8::Value> args[] = {settings};
     v8::Local<v8::Value> return_value = RunFunctionOnGlobal(
-        run_get_chrome_setting, context, base::size(args), args);
+        run_get_chrome_setting, context, std::size(args), args);
 
     ASSERT_TRUE(return_value->IsPromise());
     v8::Local<v8::Promise> promise = return_value.As<v8::Promise>();
@@ -296,7 +294,7 @@
         FunctionFromString(context, kRunSetChromeSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_set_chrome_setting, context, base::size(args), args,
+        run_set_chrome_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError(
                 "types.ChromeSetting.set",
@@ -333,7 +331,7 @@
         FunctionFromString(context, kRunGetChromeSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_get_chrome_setting, context, base::size(args), args,
+        run_get_chrome_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError("types.ChromeSetting.get",
                                         "object details, function callback",
@@ -349,7 +347,7 @@
         FunctionFromString(context, kRunSetChromeSetting);
     v8::Local<v8::Value> args[] = {settings};
     RunFunctionAndExpectError(
-        run_set_chrome_setting, context, base::size(args), args,
+        run_set_chrome_setting, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError(
                 "types.ChromeSetting.set",
diff --git a/chrome/renderer/pepper/pepper_uma_host.cc b/chrome/renderer/pepper/pepper_uma_host.cc
index 240852e..e21ec95 100644
--- a/chrome/renderer/pepper/pepper_uma_host.cc
+++ b/chrome/renderer/pepper/pepper_uma_host.cc
@@ -75,11 +75,11 @@
         host->GetPluginInstance(instance)->GetModulePath().BaseName();
   }
 
-  for (size_t i = 0; i < base::size(kPredefinedAllowedUMAOrigins); ++i)
+  for (size_t i = 0; i < std::size(kPredefinedAllowedUMAOrigins); ++i)
     allowed_origins_.insert(kPredefinedAllowedUMAOrigins[i]);
-  for (size_t i = 0; i < base::size(kAllowedHistogramPrefixes); ++i)
+  for (size_t i = 0; i < std::size(kAllowedHistogramPrefixes); ++i)
     allowed_histogram_prefixes_.insert(kAllowedHistogramPrefixes[i]);
-  for (size_t i = 0; i < base::size(kAllowedPluginBaseNames); ++i)
+  for (size_t i = 0; i < std::size(kAllowedPluginBaseNames); ++i)
     allowed_plugin_base_names_.insert(kAllowedPluginBaseNames[i]);
 }
 
diff --git a/chrome/renderer/plugins/plugin_uma.cc b/chrome/renderer/plugins/plugin_uma.cc
index f95e286..171b16b 100644
--- a/chrome/renderer/plugins/plugin_uma.cc
+++ b/chrome/renderer/plugins/plugin_uma.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 #include <cstring>
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
@@ -124,19 +123,19 @@
   std::string file_extension;
   ExtractFileExtension(src, &file_extension);
   if (CStringArrayContainsCString(kWindowsMediaPlayerExtensions,
-                                  base::size(kWindowsMediaPlayerExtensions),
+                                  std::size(kWindowsMediaPlayerExtensions),
                                   file_extension.c_str())) {
     return WINDOWS_MEDIA_PLAYER;
   }
 
   if (CStringArrayContainsCString(kQuickTimeExtensions,
-                                  base::size(kQuickTimeExtensions),
+                                  std::size(kQuickTimeExtensions),
                                   file_extension.c_str())) {
     return QUICKTIME;
   }
 
   if (CStringArrayContainsCString(kRealPlayerExtensions,
-                                  base::size(kRealPlayerExtensions),
+                                  std::size(kRealPlayerExtensions),
                                   file_extension.c_str())) {
     return REALPLAYER;
   }
diff --git a/chrome/renderer/searchbox/searchbox_unittest.cc b/chrome/renderer/searchbox/searchbox_unittest.cc
index 014b3d9..cdb18b8 100644
--- a/chrome/renderer/searchbox/searchbox_unittest.cc
+++ b/chrome/renderer/searchbox/searchbox_unittest.cc
@@ -9,7 +9,6 @@
 #include <map>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "chrome/common/search/instant_types.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -127,7 +126,7 @@
     "blahblah",
     "0xA/0x10",
   };
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     int frame_id = -1;
     InstantRestrictedID rid = -1;
     EXPECT_FALSE(ParseFrameIdAndRestrictedId(test_cases[i], &frame_id, &rid))
@@ -148,7 +147,7 @@
       {"chrome-search://favicon/size/16@2x/3/4", "size/16@2x/", 3, 4},
       {"chrome-search://favicon/iconurl/9/10", "iconurl/", 9, 10},
   };
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     std::string param_part = "(unwritten)";
     int frame_id = -1;
     InstantRestrictedID rid = -1;
@@ -174,7 +173,7 @@
       {"chrome-search://favicon/largest/http://www.google.com"},
       {"chrome-search://favicon/size/16@2x/-1/10"},
   };
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     std::string param_part = "(unwritten)";
     int frame_id = -1;
     InstantRestrictedID rid = -1;
@@ -205,7 +204,7 @@
   };
 
   MockIconURLHelper helper;
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     GURL url;
     GURL transient_url(test_cases[i].transient_url_str);
     TranslateIconRestrictedUrl(transient_url, helper, &url);
diff --git a/chrome/renderer/v8_unwinder_unittest.cc b/chrome/renderer/v8_unwinder_unittest.cc
index e9dab3c..6d4a24cb 100644
--- a/chrome/renderer/v8_unwinder_unittest.cc
+++ b/chrome/renderer/v8_unwinder_unittest.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/profiler/module_cache.h"
 #include "base/profiler/stack_sampling_profiler_test_util.h"
@@ -154,7 +153,7 @@
                 .ToLocalChecked());
     v8::Local<v8::Value> argv[] = {CreatePointerHolder(nullptr)};
     js_compile_wait_for_sample
-        ->Call(context, v8::Undefined(isolate), base::size(argv), argv)
+        ->Call(context, v8::Undefined(isolate), std::size(argv), argv)
         .ToLocalChecked();
 
     // Run waitForSample() with the real closure pointer.
@@ -164,7 +163,7 @@
             ->Get(context, ToV8String("waitForSample"))
             .ToLocalChecked());
     js_wait_for_sample
-        ->Call(context, v8::Undefined(isolate), base::size(argv), argv)
+        ->Call(context, v8::Undefined(isolate), std::size(argv), argv)
         .ToLocalChecked();
   }
 
diff --git a/chrome/services/sharing/nearby/platform/system_clock.cc b/chrome/services/sharing/nearby/platform/system_clock.cc
index e3290d9..3584c562 100644
--- a/chrome/services/sharing/nearby/platform/system_clock.cc
+++ b/chrome/services/sharing/nearby/platform/system_clock.cc
@@ -45,7 +45,7 @@
   struct timeval boottime;
   int mib[2] = {CTL_KERN, KERN_BOOTTIME};
   size_t size = sizeof(boottime);
-  int kr = sysctl(mib, base::size(mib), &boottime, &size, nullptr, 0);
+  int kr = sysctl(mib, std::size(mib), &boottime, &size, nullptr, 0);
   DCHECK_EQ(KERN_SUCCESS, kr);
   base::TimeDelta time_difference =
       base::Time::FromCFAbsoluteTime(CFAbsoluteTimeGetCurrent()) -
diff --git a/chrome/services/util_win/public/mojom/BUILD.gn b/chrome/services/util_win/public/mojom/BUILD.gn
index 53e71a4e..d56f797 100644
--- a/chrome/services/util_win/public/mojom/BUILD.gn
+++ b/chrome/services/util_win/public/mojom/BUILD.gn
@@ -40,6 +40,14 @@
           mojom = "chrome.mojom.SelectFileDialogType"
           cpp = "::ui::SelectFileDialog::Type"
         },
+        {
+          mojom = "chrome.mojom.ShortcutProperties"
+          cpp = "::base::win::ShortcutProperties"
+        },
+        {
+          mojom = "chrome.mojom.ShortcutOperation"
+          cpp = "::base::win::ShortcutOperation"
+        },
       ]
       traits_headers = [ "util_win_mojom_traits.h" ]
       traits_sources = [ "util_win_mojom_traits.cc" ]
diff --git a/chrome/services/util_win/public/mojom/util_win.mojom b/chrome/services/util_win/public/mojom/util_win.mojom
index eb80d01..821ded9 100644
--- a/chrome/services/util_win/public/mojom/util_win.mojom
+++ b/chrome/services/util_win/public/mojom/util_win.mojom
@@ -6,6 +6,7 @@
 
 import "mojo/public/mojom/base/file_path.mojom";
 import "mojo/public/mojom/base/string16.mojom";
+import "mojo/public/mojom/base/wstring.mojom";
 import "sandbox/policy/mojom/sandbox.mojom";
 
 enum SelectFileDialogType {
@@ -88,6 +89,49 @@
   AntiVirusProductState state;
 };
 
+struct ClsId {
+  array<uint8, 16> bytes;
+};
+
+struct ShortcutProperties {
+  // The target to launch from this shortcut. This is mandatory when creating
+  // a shortcut.
+  mojo_base.mojom.FilePath target;
+  // The name of the working directory when launching the shortcut.
+  mojo_base.mojom.FilePath working_dir;
+  // The arguments to be applied to |target| when launching from this shortcut.
+  mojo_base.mojom.WString arguments;
+  // The localized description of the shortcut.
+  // The length of this string must be no larger than INFOTIPSIZE.
+  mojo_base.mojom.WString description;
+  // The path to the icon (can be a dll or exe, in which case |icon_index| is
+  // the resource id).
+  mojo_base.mojom.FilePath icon;
+  int32 icon_index = -1;
+  // The app model id for the shortcut.
+  mojo_base.mojom.WString app_id;
+  // Whether this is a dual mode shortcut (Win8+).
+  bool dual_mode;
+  // The CLSID of the COM object registered with the OS via the shortcut. This
+  // is for app activation via user interaction with a toast notification in the
+  // Action Center. (Win10 version 1607, build 14393, and beyond).
+  ClsId toast_activator_clsid;
+  // Bitfield made of ShortcutProperties::IndividualProperties. Properties set
+  // in |options| will be set on the shortcut, others will be ignored.
+  uint32 options;
+};
+
+enum ShortcutOperation {
+  // Create a new shortcut (overwriting if necessary).
+  kCreateAlways,
+  // Overwrite an existing shortcut (fails if the shortcut doesn't exist).
+  // If the arguments are not specified on the new shortcut, keep the old
+  // shortcut's arguments.
+  kReplaceExisting,
+  // Update specified properties only on an existing shortcut.
+  kUpdateExisting,
+};
+
 // Utility process interface exposed to the browser process on OS_WIN. Used to
 // improve stability by executing some tasks out-of-process. This include either
 // crashy tasks, or tasks that requires certain DLLs to be loaded into the
@@ -103,6 +147,12 @@
   UnpinShortcuts(array<mojo_base.mojom.FilePath> shortcut_paths)
     => ();
 
+  // Creates or updates shortcuts.
+  CreateOrUpdateShortcutLink(mojo_base.mojom.FilePath shortcut_path,
+                                ShortcutProperties properties,
+                                ShortcutOperation operation) =>
+      (bool succeeded);
+
   // Executes a select file operation that can be executed on a utility process.
   // |owner|:
   //   The HWND that owns the file dialog.
diff --git a/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc b/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
index bc1ef7b..ca9f5d1 100644
--- a/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
+++ b/chrome/services/util_win/public/mojom/util_win_mojom_traits.cc
@@ -6,10 +6,13 @@
 
 #include <utility>
 
+#include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/win/shortcut.h"
 #include "mojo/public/cpp/base/file_path_mojom_traits.h"
 #include "mojo/public/cpp/base/string16_mojom_traits.h"
+#include "mojo/public/cpp/base/wstring_mojom_traits.h"
 
 namespace mojo {
 
@@ -86,6 +89,50 @@
 }
 
 // static
+chrome::mojom::ShortcutOperation
+EnumTraits<chrome::mojom::ShortcutOperation, ::base::win::ShortcutOperation>::
+    ToMojom(::base::win::ShortcutOperation input) {
+  switch (input) {
+    case base::win::ShortcutOperation::kCreateAlways:
+      return chrome::mojom::ShortcutOperation::kCreateAlways;
+    case base::win::ShortcutOperation::kReplaceExisting:
+      return chrome::mojom::ShortcutOperation::kReplaceExisting;
+    case base::win::ShortcutOperation::kUpdateExisting:
+      return chrome::mojom::ShortcutOperation::kUpdateExisting;
+  }
+  NOTREACHED();
+  return chrome::mojom::ShortcutOperation::kCreateAlways;
+}
+
+// static
+bool EnumTraits<chrome::mojom::ShortcutOperation,
+                ::base::win::ShortcutOperation>::
+    FromMojom(chrome::mojom::ShortcutOperation input,
+              ::base::win::ShortcutOperation* output) {
+  switch (input) {
+    case chrome::mojom::ShortcutOperation::kCreateAlways:
+      *output = base::win::ShortcutOperation::kCreateAlways;
+      return true;
+    case chrome::mojom::ShortcutOperation::kReplaceExisting:
+      *output = base::win::ShortcutOperation::kReplaceExisting;
+      return true;
+    case chrome::mojom::ShortcutOperation::kUpdateExisting:
+      *output = base::win::ShortcutOperation::kUpdateExisting;
+      return true;
+  }
+
+  NOTREACHED();
+  return false;
+}
+
+// static
+bool StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec>::
+    Read(chrome::mojom::FileFilterSpecDataView input, ui::FileFilterSpec* out) {
+  return input.ReadDescription(&out->description) &&
+         input.ReadExtensionSpec(&out->extension_spec);
+}
+
+// static
 bool EnumTraits<chrome::mojom::CertificateType, CertificateInfo::Type>::
     FromMojom(chrome::mojom::CertificateType input,
               CertificateInfo::Type* output) {
@@ -172,10 +219,42 @@
 }
 
 // static
-bool StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec>::
-    Read(chrome::mojom::FileFilterSpecDataView input, ui::FileFilterSpec* out) {
-  return input.ReadDescription(&out->description) &&
-         input.ReadExtensionSpec(&out->extension_spec);
+base::span<const uint8_t> StructTraits<chrome::mojom::ClsIdDataView,
+                                       ::CLSID>::bytes(const ::CLSID& input) {
+  return base::make_span(reinterpret_cast<const uint8_t*>(&input),
+                         sizeof(input));
+}
+
+// static
+bool StructTraits<chrome::mojom::ClsIdDataView, ::CLSID>::Read(
+    chrome::mojom::ClsIdDataView data,
+    ::CLSID* out) {
+  ArrayDataView<uint8_t> bytes_view;
+  data.GetBytesDataView(&bytes_view);
+  DCHECK_EQ(bytes_view.size(), sizeof(*out));
+
+  const ::CLSID* cls_id = reinterpret_cast<const ::CLSID*>(bytes_view.data());
+
+  memcpy(out, cls_id, sizeof(*out));
+  return true;
+}
+
+//  static
+bool StructTraits<chrome::mojom::ShortcutPropertiesDataView,
+                  base::win::ShortcutProperties>::
+    Read(chrome::mojom::ShortcutPropertiesDataView input,
+         base::win::ShortcutProperties* out) {
+  out->icon_index = input.icon_index();
+  out->dual_mode = input.dual_mode();
+  out->options = input.options();
+
+  // out->toast_activator_clsid
+  return input.ReadTarget(&out->target) &&
+         input.ReadWorkingDir(&out->working_dir) &&
+         input.ReadToastActivatorClsid(&out->toast_activator_clsid) &&
+         input.ReadDescription(&out->description) &&
+         input.ReadArguments(&out->arguments) && input.ReadIcon(&out->icon) &&
+         input.ReadAppId(&out->app_id);
 }
 
 // static
diff --git a/chrome/services/util_win/public/mojom/util_win_mojom_traits.h b/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
index 44e773c..4aa81136 100644
--- a/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
+++ b/chrome/services/util_win/public/mojom/util_win_mojom_traits.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/files/file_path.h"
+#include "base/win/shortcut.h"
 #include "chrome/browser/win/conflicts/module_info.h"
 #include "chrome/browser/win/conflicts/module_info_util.h"
 #include "chrome/services/util_win/public/mojom/util_win.mojom-shared.h"
@@ -33,6 +34,78 @@
 };
 
 template <>
+struct EnumTraits<chrome::mojom::ShortcutOperation,
+                  base::win::ShortcutOperation> {
+  static chrome::mojom::ShortcutOperation ToMojom(
+      base::win::ShortcutOperation input);
+  static bool FromMojom(chrome::mojom::ShortcutOperation input,
+                        base::win::ShortcutOperation* output);
+};
+
+template <>
+struct StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec> {
+  static const std::u16string& description(const ui::FileFilterSpec& input) {
+    return input.description;
+  }
+  static const std::u16string& extension_spec(const ui::FileFilterSpec& input) {
+    return input.extension_spec;
+  }
+
+  static bool Read(chrome::mojom::FileFilterSpecDataView data,
+                   ui::FileFilterSpec* output);
+};
+
+template <>
+struct StructTraits<chrome::mojom::ClsIdDataView, ::CLSID> {
+  static base::span<const uint8_t> bytes(const ::CLSID& input);
+  static bool Read(chrome::mojom::ClsIdDataView data, ::CLSID* out);
+};
+
+template <>
+struct StructTraits<chrome::mojom::ShortcutPropertiesDataView,
+                    base::win::ShortcutProperties> {
+  static const base::FilePath& target(
+      const base::win::ShortcutProperties& input) {
+    return input.target;
+  }
+  static const base::FilePath& working_dir(
+      const base::win::ShortcutProperties& input) {
+    return input.working_dir;
+  }
+  static const std::wstring& arguments(
+      const base::win::ShortcutProperties& input) {
+    return input.arguments;
+  }
+  static const std::wstring& description(
+      const base::win::ShortcutProperties& input) {
+    return input.description;
+  }
+  static const base::FilePath& icon(
+      const base::win::ShortcutProperties& input) {
+    return input.icon;
+  }
+  static int icon_index(const base::win::ShortcutProperties& input) {
+    return input.icon_index;
+  }
+  static const std::wstring& app_id(
+      const base::win::ShortcutProperties& input) {
+    return input.app_id;
+  }
+  static bool dual_mode(const base::win::ShortcutProperties& input) {
+    return input.dual_mode;
+  }
+  static const CLSID& toast_activator_clsid(
+      const base::win::ShortcutProperties& input) {
+    return input.toast_activator_clsid;
+  }
+  static uint32_t options(const base::win::ShortcutProperties& input) {
+    return input.options;
+  }
+  static bool Read(chrome::mojom::ShortcutPropertiesDataView data,
+                   base::win::ShortcutProperties* output);
+};
+
+template <>
 struct StructTraits<chrome::mojom::InspectionResultDataView,
                     ModuleInspectionResult> {
   static const std::u16string& location(const ModuleInspectionResult& input);
@@ -53,19 +126,6 @@
 };
 
 template <>
-struct StructTraits<chrome::mojom::FileFilterSpecDataView, ui::FileFilterSpec> {
-  static const std::u16string& description(const ui::FileFilterSpec& input) {
-    return input.description;
-  }
-  static const std::u16string& extension_spec(const ui::FileFilterSpec& input) {
-    return input.extension_spec;
-  }
-
-  static bool Read(chrome::mojom::FileFilterSpecDataView data,
-                   ui::FileFilterSpec* output);
-};
-
-template <>
 struct StructTraits<chrome::mojom::AntiVirusProductDataView,
                     metrics::SystemProfileProto_AntiVirusProduct> {
   static const std::string& product_name(
diff --git a/chrome/services/util_win/util_win_impl.cc b/chrome/services/util_win/util_win_impl.cc
index 8ac4b4c4..7edd11af 100644
--- a/chrome/services/util_win/util_win_impl.cc
+++ b/chrome/services/util_win/util_win_impl.cc
@@ -253,6 +253,16 @@
   std::move(callback).Run();
 }
 
+void UtilWinImpl::CreateOrUpdateShortcutLink(
+    const base::FilePath& shortcut_path,
+    const base::win::ShortcutProperties& properties,
+    base::win::ShortcutOperation operation,
+    CreateOrUpdateShortcutLinkCallback callback) {
+  bool ret = base::win::CreateOrUpdateShortcutLink(shortcut_path, properties,
+                                                   operation);
+  std::move(callback).Run(ret);
+}
+
 void UtilWinImpl::CallExecuteSelectFile(
     ui::SelectFileDialog::Type type,
     uint32_t owner,
diff --git a/chrome/services/util_win/util_win_impl.h b/chrome/services/util_win/util_win_impl.h
index 5077c0b..e392651 100644
--- a/chrome/services/util_win/util_win_impl.h
+++ b/chrome/services/util_win/util_win_impl.h
@@ -28,6 +28,11 @@
   void IsPinnedToTaskbar(IsPinnedToTaskbarCallback callback) override;
   void UnpinShortcuts(const std::vector<base::FilePath>& shortcut_paths,
                       UnpinShortcutsCallback callback) override;
+  void CreateOrUpdateShortcutLink(
+      const base::FilePath& shortcut_path,
+      const base::win::ShortcutProperties& properties,
+      base::win::ShortcutOperation operation,
+      CreateOrUpdateShortcutLinkCallback callback) override;
   void CallExecuteSelectFile(ui::SelectFileDialog::Type type,
                              uint32_t owner,
                              const std::u16string& title,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 914751b8..2c8c4480 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -352,6 +352,7 @@
 
     if (enable_extensions) {
       public_deps += [
+        "//chrome/browser/extensions:test_support",
         "//extensions/browser:test_support",
         "//extensions/common:test_support",
       ]
@@ -708,9 +709,8 @@
         "//fuchsia/engine:web_engine_shell",
         "//fuchsia/engine:web_engine_with_webui_installer",
       ]
-    } else if (fuchsia_browser_type == "chrome") {
-      data_deps += [ "//chrome/app:chrome_fuchsia" ]
     }
+    data_deps += [ "//chrome/app:chrome_fuchsia" ]
   }
 } else {
   group("telemetry_gpu_integration_test") {
@@ -8539,8 +8539,6 @@
       "../browser/extensions/api/tabs/tabs_interactive_test.cc",
       "../browser/extensions/api/tabs/window_open_interactive_apitest.cc",
       "../browser/extensions/app_window_uitest.cc",
-      "../browser/extensions/chrome_extension_test_notification_observer.cc",
-      "../browser/extensions/chrome_extension_test_notification_observer.h",
       "../browser/extensions/extension_apitest.cc",
       "../browser/extensions/extension_browsertest.cc",
       "../browser/extensions/extension_commands_global_registry_apitest.cc",
@@ -9089,6 +9087,10 @@
         "../browser/ui/views/profiles/profile_bubble_interactive_uitest.cc",
       ]
     }
+
+    if (enable_print_preview) {
+      sources += [ "../browser/window_placement/window_placement_printing_interactive_uitest.cc" ]
+    }
   }
 }
 
diff --git a/chrome/test/base/always_on_top_window_killer_win.cc b/chrome/test/base/always_on_top_window_killer_win.cc
index 57b630e..ebac322 100644
--- a/chrome/test/base/always_on_top_window_killer_win.cc
+++ b/chrome/test/base/always_on_top_window_killer_win.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "chrome/test/base/always_on_top_window_killer_win.h"
-#include "base/memory/raw_ptr.h"
 
 #include <Windows.h>
 
@@ -11,9 +10,9 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
+#include "base/memory/raw_ptr.h"
 #include "chrome/test/base/process_lineage_win.h"
 #include "chrome/test/base/save_desktop_snapshot_win.h"
 #include "ui/display/win/screen_win.h"
@@ -121,9 +120,9 @@
 // static
 std::wstring WindowEnumerator::GetWindowClass(HWND hwnd) {
   wchar_t buffer[257];  // Max is 256.
-  buffer[base::size(buffer) - 1] = L'\0';
-  int name_len = ::GetClassName(hwnd, &buffer[0], base::size(buffer));
-  if (name_len <= 0 || static_cast<size_t>(name_len) >= base::size(buffer))
+  buffer[std::size(buffer) - 1] = L'\0';
+  int name_len = ::GetClassName(hwnd, &buffer[0], std::size(buffer));
+  if (name_len <= 0 || static_cast<size_t>(name_len) >= std::size(buffer))
     return std::wstring();
   return std::wstring(&buffer[0], name_len);
 }
diff --git a/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc b/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc
index 845d9fc..aac089b7e 100644
--- a/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc
+++ b/chrome/test/base/chromeos/fake_ash_test_chrome_browser_main_extra_parts.cc
@@ -8,6 +8,7 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "chrome/browser/ash/crosapi/browser_manager.h"
 #include "chrome/browser/ash/crosapi/crosapi_ash.h"
 #include "chrome/browser/ash/crosapi/crosapi_manager.h"
 #include "chrome/browser/ash/crosapi/test_controller_ash.h"
@@ -62,6 +63,7 @@
 
   crosapi::CrosapiManager::Get()->crosapi_ash()->SetTestControllerForTesting(
       test_controller_ash_.get());
+  crosapi::BrowserManager::Get()->DisableAutoLaunchForTesting();
 
   // Call this at the end of PostBrowserStart().
   AshIsReadyForTesting();
diff --git a/chrome/test/base/in_process_browser_test_browsertest.cc b/chrome/test/base/in_process_browser_test_browsertest.cc
index 2967a0e..30e708b 100644
--- a/chrome/test/base/in_process_browser_test_browsertest.cc
+++ b/chrome/test/base/in_process_browser_test_browsertest.cc
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/test/base/in_process_browser_test.h"
+
 #include <stddef.h>
 #include <string.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "build/build_config.h"
 #include "chrome/browser/after_startup_task_utils.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_view_host.h"
@@ -92,7 +92,7 @@
     "http://www.google.com/",
     "http://www.cnn.com/"
   };
-  for (size_t i = 0; i < base::size(kURLs); ++i) {
+  for (size_t i = 0; i < std::size(kURLs); ++i) {
     GURL url(kURLs[i]);
     LoadFailObserver observer(contents);
     ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
diff --git a/chrome/test/base/interactive_test_utils_win.cc b/chrome/test/base/interactive_test_utils_win.cc
index 25f5347ebe..c916517 100644
--- a/chrome/test/base/interactive_test_utils_win.cc
+++ b/chrome/test/base/interactive_test_utils_win.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -71,7 +70,7 @@
     // Emit some diagnostic information about the foreground window and its
     // owning process.
     wchar_t window_title[256];
-    GetWindowText(foreground_window, window_title, base::size(window_title));
+    GetWindowText(foreground_window, window_title, std::size(window_title));
 
     std::wstring lineage_str;
     std::wstring window_contents;
diff --git a/chrome/test/chromedriver/capabilities.cc b/chrome/test/chromedriver/capabilities.cc
index 258c17fc..ff4f4faf 100644
--- a/chrome/test/chromedriver/capabilities.cc
+++ b/chrome/test/chromedriver/capabilities.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/json/string_escape.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
@@ -322,7 +321,7 @@
     const std::string kSocksProxy = "socksProxy";
     const base::Value* option_value = nullptr;
     std::string proxy_servers;
-    for (size_t i = 0; i < base::size(proxy_servers_options); ++i) {
+    for (size_t i = 0; i < std::size(proxy_servers_options); ++i) {
       option_value = proxy_dict->FindPath(proxy_servers_options[i][0]);
       if (option_value == nullptr || option_value->is_none()) {
         continue;
diff --git a/chrome/test/chromedriver/chrome/chrome_finder.cc b/chrome/test/chromedriver/chrome/chrome_finder.cc
index 05d3e61..83d2773 100644
--- a/chrome/test/chromedriver/chrome/chrome_finder.cc
+++ b/chrome/test/chromedriver/chrome/chrome_finder.cc
@@ -12,7 +12,6 @@
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -153,7 +152,7 @@
   LOG_IF(ERROR, browser_exes_array[0].empty()) << "Unsupported platform.";
 
   std::vector<base::FilePath> browser_exes(
-      browser_exes_array, browser_exes_array + base::size(browser_exes_array));
+      browser_exes_array, browser_exes_array + std::size(browser_exes_array));
   base::FilePath module_dir;
 #if BUILDFLAG(IS_FUCHSIA)
   // Use -1 to allow this to compile.
diff --git a/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc b/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
index 40bd39793..98f5a41 100644
--- a/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
+++ b/chrome/test/chromedriver/chrome/heap_snapshot_taker.cc
@@ -5,9 +5,9 @@
 #include "chrome/test/chromedriver/chrome/heap_snapshot_taker.h"
 
 #include <stddef.h>
+
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/values.h"
 #include "chrome/test/chromedriver/chrome/devtools_client.h"
@@ -46,7 +46,7 @@
       "HeapProfiler.collectGarbage",
       "HeapProfiler.takeHeapSnapshot"
   };
-  for (size_t i = 0; i < base::size(kMethods); ++i) {
+  for (size_t i = 0; i < std::size(kMethods); ++i) {
     Status status = client_->SendCommand(kMethods[i], params);
     if (status.IsError())
       return status;
diff --git a/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc b/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
index 592eba3..3fe9574b 100644
--- a/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
+++ b/chrome/test/chromedriver/chrome/heap_snapshot_taker_unittest.cc
@@ -11,7 +11,6 @@
 #include <string>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "chrome/test/chromedriver/chrome/status.h"
 #include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
@@ -40,7 +39,7 @@
   Status SendAddHeapSnapshotChunkEvent() {
     base::DictionaryValue event_params;
     event_params.SetInteger("uid", uid_);
-    for (size_t i = 0; i < base::size(chunks); ++i) {
+    for (size_t i = 0; i < std::size(chunks); ++i) {
       event_params.SetString("chunk", chunks[i]);
       Status status = listeners_.front()->OnEvent(
           this, "HeapProfiler.addHeapSnapshotChunk", event_params);
diff --git a/chrome/test/chromedriver/key_converter.cc b/chrome/test/chromedriver/key_converter.cc
index 7a662648..e7602aa 100644
--- a/chrome/test/chromedriver/key_converter.cc
+++ b/chrome/test/chromedriver/key_converter.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversion_utils.h"
@@ -172,7 +171,7 @@
 bool KeyCodeFromSpecialWebDriverKey(char16_t key, ui::KeyboardCode* key_code) {
   int index = static_cast<int>(key) - 0xE000U;
   bool is_special_key =
-      index >= 0 && index < static_cast<int>(base::size(kSpecialWebDriverKeys));
+      index >= 0 && index < static_cast<int>(std::size(kSpecialWebDriverKeys));
   if (is_special_key)
     *key_code = kSpecialWebDriverKeys[index];
   return is_special_key;
@@ -578,7 +577,7 @@
     }
 
     // Create the key events.
-    int number_modifiers = base::size(kModifiers);
+    int number_modifiers = std::size(kModifiers);
     bool necessary_modifiers[number_modifiers];
     for (int j = 0; j < number_modifiers; ++j) {
       necessary_modifiers[j] = all_modifiers & kModifiers[j].mask &&
@@ -630,7 +629,7 @@
 
   std::string key;
   if (code_point >= kNormalisedKeyValueBase &&
-      code_point < kNormalisedKeyValueBase + base::size(kNormalisedKeyValue)) {
+      code_point < kNormalisedKeyValueBase + std::size(kNormalisedKeyValue)) {
     key = kNormalisedKeyValue[code_point - kNormalisedKeyValueBase];
   }
   if (key.size() == 0)
diff --git a/chrome/test/chromedriver/key_converter_unittest.cc b/chrome/test/chromedriver/key_converter_unittest.cc
index 5e8eef9..e35758c 100644
--- a/chrome/test/chromedriver/key_converter_unittest.cc
+++ b/chrome/test/chromedriver/key_converter_unittest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/test/chromedriver/key_converter.h"
+
 #include <stddef.h>
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/test/chromedriver/chrome/status.h"
 #include "chrome/test/chromedriver/chrome/ui_events.h"
-#include "chrome/test/chromedriver/key_converter.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/test/keyboard_layout.h"
 
@@ -324,7 +324,7 @@
         << "Index: " << i;
     if (i == 0) {
       EXPECT_EQ(0u, events.size()) << "Index: " << i;
-    } else if (i >= base::size(kTextForKeys) || kTextForKeys[i] == 0) {
+    } else if (i >= std::size(kTextForKeys) || kTextForKeys[i] == 0) {
       EXPECT_EQ(2u, events.size()) << "Index: " << i;
     } else {
       ASSERT_EQ(3u, events.size()) << "Index: " << i;
diff --git a/chrome/test/chromedriver/keycode_text_conversion_x.cc b/chrome/test/chromedriver/keycode_text_conversion_x.cc
index 5108681..83bee518 100644
--- a/chrome/test/chromedriver/keycode_text_conversion_x.cc
+++ b/chrome/test/chromedriver/keycode_text_conversion_x.cc
@@ -2,16 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/test/chromedriver/keycode_text_conversion.h"
-
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
+
 #include <algorithm>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/test/chromedriver/chrome/ui_events.h"
+#include "chrome/test/chromedriver/keycode_text_conversion.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/gfx/x/connection.h"
@@ -90,9 +89,9 @@
   KeyCodeAndXKeyCode find;
   find.key_code = key_code;
   const KeyCodeAndXKeyCode* found = std::lower_bound(
-      kKeyCodeToXKeyCode, kKeyCodeToXKeyCode + base::size(kKeyCodeToXKeyCode),
+      kKeyCodeToXKeyCode, kKeyCodeToXKeyCode + std::size(kKeyCodeToXKeyCode),
       find);
-  if (found >= kKeyCodeToXKeyCode + base::size(kKeyCodeToXKeyCode) ||
+  if (found >= kKeyCodeToXKeyCode + std::size(kKeyCodeToXKeyCode) ||
       found->key_code != key_code)
     return -1;
   return found->x_key_code;
diff --git a/chrome/test/chromedriver/logging.cc b/chrome/test/chromedriver/logging.cc
index da38ba6..0d0d8c3 100644
--- a/chrome/test/chromedriver/logging.cc
+++ b/chrome/test/chromedriver/logging.cc
@@ -13,7 +13,6 @@
 
 #include "base/command_line.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
@@ -64,7 +63,7 @@
 const char* LevelToName(Log::Level level) {
   const int index = level - Log::kAll;
   CHECK_GE(index, 0);
-  CHECK_LT(static_cast<size_t>(index), base::size(kLevelToName));
+  CHECK_LT(static_cast<size_t>(index), std::size(kLevelToName));
   return kLevelToName[index];
 }
 
@@ -181,7 +180,7 @@
 const char WebDriverLog::kDevToolsType[] = "devtools";
 
 bool WebDriverLog::NameToLevel(const std::string& name, Log::Level* out_level) {
-  for (size_t i = 0; i < base::size(kNameToLevel); ++i) {
+  for (size_t i = 0; i < std::size(kNameToLevel); ++i) {
     if (name == kNameToLevel[i].name) {
       *out_level = kNameToLevel[i].level;
       return true;
diff --git a/chrome/test/chromedriver/logging_unittest.cc b/chrome/test/chromedriver/logging_unittest.cc
index 226d7c55..5fab4096 100644
--- a/chrome/test/chromedriver/logging_unittest.cc
+++ b/chrome/test/chromedriver/logging_unittest.cc
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/test/chromedriver/logging.h"
+
 #include <stddef.h>
 
 #include <memory>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
@@ -16,7 +17,6 @@
 #include "chrome/test/chromedriver/chrome/log.h"
 #include "chrome/test/chromedriver/chrome/status.h"
 #include "chrome/test/chromedriver/command_listener.h"
-#include "chrome/test/chromedriver/logging.h"
 #include "chrome/test/chromedriver/session.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -30,7 +30,7 @@
 
 TEST(Logging, NameLevelConversionHappy) {
   // All names map to a valid enum value.
-  for (int i = 0; static_cast<size_t>(i) < base::size(kAllWdLevels); ++i) {
+  for (int i = 0; static_cast<size_t>(i) < std::size(kAllWdLevels); ++i) {
     Log::Level level = static_cast<Log::Level>(-1);
     EXPECT_TRUE(WebDriverLog::NameToLevel(kAllWdLevels[i], &level));
     EXPECT_LE(Log::kAll, level);
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc
index 1e23252..848b2ad5 100644
--- a/chrome/test/chromedriver/server/chromedriver_server.cc
+++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -344,7 +344,7 @@
       "(add this switch if seeing errors related to shared memory)",
 #endif
     };
-    for (size_t i = 0; i < base::size(kOptionAndDescriptions) - 1; i += 2) {
+    for (size_t i = 0; i < std::size(kOptionAndDescriptions) - 1; i += 2) {
       options += base::StringPrintf(
           "  --%-30s%s\n",
           kOptionAndDescriptions[i], kOptionAndDescriptions[i + 1]);
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc
index dce9197..31426db 100644
--- a/chrome/test/chromedriver/server/http_handler.cc
+++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"  // For CHECK macros.
@@ -1000,7 +999,7 @@
                         base::BindRepeating(&ExecuteSendCommandFromWebSocket))),
   };
   command_map_ =
-      std::make_unique<CommandMap>(commands, commands + base::size(commands));
+      std::make_unique<CommandMap>(commands, commands + std::size(commands));
 }
 
 HttpHandler::~HttpHandler() {}
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_2.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_2.json
index be5c030..9d979d0e 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_2.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_2.json
@@ -11,7 +11,7 @@
     "chromeos_system_extension": {},
     "externally_connectable": {
       "matches": [
-        "*://hpcs-appschr.hpcloud.hp.com/*"
+        "https://hpcs-appschr.hpcloud.hp.com/*"
       ]
     },
     "options_page": "options.html"
diff --git a/chrome/test/data/webui/cr_components/BUILD.gn b/chrome/test/data/webui/cr_components/BUILD.gn
index ad4af16..e7ac768e3 100644
--- a/chrome/test/data/webui/cr_components/BUILD.gn
+++ b/chrome/test/data/webui/cr_components/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//crypto/features.gni")
 import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/typescript/ts_library.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 
@@ -29,6 +30,37 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
+if (use_nss_certs) {
+  # Test files that contain // <if expr> and therefore require preprocessing.
+  preprocessed_files = [ "certificate_manager_test.ts" ]
+  if (is_chromeos_ash) {
+    preprocessed_files += [ "certificate_manager_provisioning_test.ts" ]
+  }
+}
+
+# Test files that do not require preprocessing. If adding // <if expr> to any
+# file below, move it to the list above.
+non_preprocessed_files = [
+  "most_visited_focus_test.ts",
+  "most_visited_test.ts",
+  "most_visited_test_support.ts",
+]
+
+preprocessed_folder = "$target_gen_dir/preprocessed"
+
+if (use_nss_certs) {
+  preprocess_if_expr("preprocess") {
+    in_folder = "."
+    out_folder = preprocessed_folder
+    in_files = preprocessed_files
+  }
+}
+
+copy("copy") {
+  sources = non_preprocessed_files
+  outputs = [ "$preprocessed_folder/{{source_target_relative}}" ]
+}
+
 generate_grd("build_grdp") {
   grd_prefix = "webui_cr_components"
   out_grd = "$target_gen_dir/resources.grdp"
@@ -39,17 +71,24 @@
 }
 
 ts_library("build_ts") {
-  root_dir = "./"
+  root_dir = preprocessed_folder
   out_dir = "$target_gen_dir/tsc"
   tsconfig_base = "tsconfig_base.json"
   path_mappings = [ "chrome://webui-test/*|" +
                     rebase_path("$root_gen_dir/chrome/test/data/webui/tsc/*",
                                 target_gen_dir) ]
-  in_files = [
-    "most_visited_focus_test.ts",
-    "most_visited_test.ts",
-    "most_visited_test_support.ts",
-  ]
+  in_files = non_preprocessed_files
   deps = [ "//ui/webui/resources/cr_components/most_visited:build_ts" ]
-  extra_deps = [ "..:generate_definitions" ]
+
+  extra_deps = [
+    ":copy",
+    "..:generate_definitions",
+  ]
+
+  if (use_nss_certs) {
+    in_files += preprocessed_files
+    deps +=
+        [ "//ui/webui/resources/cr_components/certificate_manager:build_ts" ]
+    extra_deps += [ ":preprocess" ]
+  }
 }
diff --git a/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js b/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.ts
similarity index 65%
rename from chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js
rename to chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.ts
index c084048..0096076 100644
--- a/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.js
+++ b/chrome/test/data/webui/cr_components/certificate_manager_provisioning_test.ts
@@ -3,28 +3,28 @@
 // found in the LICENSE file.
 
 import 'chrome://settings/strings.m.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_list.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_entry.js';
 
-import {CertificateProvisioningViewDetailsActionEvent} from 'chrome://resources/cr_components/certificate_manager/certificate_manager_types.js';
-import {CertificateProvisioningBrowserProxyImpl} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js';
+import {CertificateProvisioningActionEventDetail, CertificateProvisioningViewDetailsActionEvent} from 'chrome://resources/cr_components/certificate_manager/certificate_manager_types.js';
+import {CertificateProvisioningBrowserProxy, CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_browser_proxy.js';
 import {CertificateProvisioningDetailsDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.js';
 import {CertificateProvisioningEntryElement} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_entry.js';
 import {CertificateProvisioningListElement} from 'chrome://resources/cr_components/certificate_manager/certificate_provisioning_list.js';
 import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
-import {TestBrowserProxy} from '../test_browser_proxy.js';
-import {eventToPromise} from '../test_util.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 
 /**
  * A test version of CertificateProvisioningBrowserProxy.
  * Provides helper methods for allowing tests to know when a method was called,
  * as well as specifying mock responses.
- *
- * @implements {CertificateProvisioningBrowserProxy}
  */
-class TestCertificateProvisioningBrowserProxy extends TestBrowserProxy {
+class TestCertificateProvisioningBrowserProxy extends TestBrowserProxy
+    implements CertificateProvisioningBrowserProxy {
   constructor() {
     super([
       'refreshCertificateProvisioningProcesses',
@@ -32,24 +32,20 @@
     ]);
   }
 
-  /** override */
   refreshCertificateProvisioningProcesses() {
     this.methodCalled('refreshCertificateProvisioningProcesses');
   }
 
-  /** override */
-  triggerCertificateProvisioningProcessUpdate(certProfileId, isDeviceWide) {
+  triggerCertificateProvisioningProcessUpdate(
+      certProfileId: string, isDeviceWide: boolean) {
     this.methodCalled(
         'triggerCertificateProvisioningProcessUpdate',
         {certProfileId, isDeviceWide});
   }
 }
 
-/**
- * @param {boolean} isUpdated
- * @return {!CertificateProvisioningProcess}
- */
-function createSampleCertificateProvisioningProcess(isUpdated) {
+function createSampleCertificateProvisioningProcess(isUpdated: boolean):
+    CertificateProvisioningProcess {
   return {
     certProfileId: 'dummyProfileId',
     certProfileName: 'Dummy Profile Name',
@@ -61,41 +57,30 @@
   };
 }
 
-/**
- * @param {?CertificateProvisioningListElement} certProvisioningList
- * @return {!NodeList<!Element>}
- */
-function getEntries(certProvisioningList) {
-  assertTrue(!!certProvisioningList);
-  return certProvisioningList.shadowRoot.querySelectorAll(
+function getEntries(certProvisioningList: CertificateProvisioningListElement):
+    NodeListOf<CertificateProvisioningEntryElement> {
+  return certProvisioningList.shadowRoot!.querySelectorAll(
       'certificate-provisioning-entry');
 }
 
 suite('CertificateProvisioningEntryTests', function() {
-  /** @type {!CertificateProvisioningEntryElement} */
-  let entry;
+  let entry: CertificateProvisioningEntryElement;
+  let browserProxy: TestCertificateProvisioningBrowserProxy;
 
-  /** @type {?TestCertificateProvisioningBrowserProxy} */
-  let browserProxy = null;
-
-  /**
-   * @return {!Promise} A promise firing once
-   *     |CertificateProvisioningViewDetailsActionEvent| fires.
-   */
-  function actionEventToPromise() {
+  function actionEventToPromise():
+      Promise<CustomEvent<CertificateProvisioningActionEventDetail>> {
     return eventToPromise(CertificateProvisioningViewDetailsActionEvent, entry);
   }
 
   setup(function() {
     browserProxy = new TestCertificateProvisioningBrowserProxy();
     CertificateProvisioningBrowserProxyImpl.setInstance(browserProxy);
-    entry = /** @type {!CertificateProvisioningEntryElement} */ (
-        document.createElement('certificate-provisioning-entry'));
+    entry = document.createElement('certificate-provisioning-entry');
     entry.model = createSampleCertificateProvisioningProcess(false);
     document.body.appendChild(entry);
 
     // Bring up the popup menu for the following tests to use.
-    entry.shadowRoot.querySelector('#dots').click();
+    entry.$.dots.click();
     flush();
   });
 
@@ -105,31 +90,26 @@
 
   // Test case where 'Details' option is tapped.
   test('MenuOptions_Details', function() {
-    const detailsButton = entry.shadowRoot.querySelector('#details');
+    const detailsButton =
+        entry.shadowRoot!.querySelector<HTMLElement>('#details');
+    assertTrue(!!detailsButton);
     const waitForActionEvent = actionEventToPromise();
     detailsButton.click();
     return waitForActionEvent.then(function(event) {
-      const detail =
-          /** @type {!CertificateProvisioningActionEventDetail} */ (
-              event.detail);
-      assertEquals(entry.model, detail.model);
+      assertEquals(entry.model, event.detail.model);
     });
   });
 });
 
 suite('CertificateManagerProvisioningTests', function() {
-  /** @type {?CertificateProvisioningListElement} */
-  let certProvisioningList = null;
-
-  /** @type {?TestCertificateProvisioningBrowserProxy} */
-  let browserProxy = null;
+  let certProvisioningList: CertificateProvisioningListElement;
+  let browserProxy: TestCertificateProvisioningBrowserProxy;
 
   setup(function() {
     browserProxy = new TestCertificateProvisioningBrowserProxy();
     CertificateProvisioningBrowserProxyImpl.setInstance(browserProxy);
     certProvisioningList =
-        /** @type {!CertificateProvisioningListElement} */ (
-            document.createElement('certificate-provisioning-list'));
+        document.createElement('certificate-provisioning-list');
     document.body.appendChild(certProvisioningList);
   });
 
@@ -162,48 +142,41 @@
     const anchorForTest = document.createElement('a');
     document.body.appendChild(anchorForTest);
 
-    assertFalse(!!certProvisioningList.shadowRoot.querySelector(dialogId));
+    assertFalse(!!certProvisioningList.shadowRoot!.querySelector(dialogId));
     const whenDialogOpen =
         eventToPromise('cr-dialog-open', certProvisioningList);
     certProvisioningList.dispatchEvent(
         new CustomEvent(CertificateProvisioningViewDetailsActionEvent, {
           bubbles: true,
           composed: true,
-          detail:
-              /** @type {!CertificateProvisioningActionEventDetail} */ ({
-                model: createSampleCertificateProvisioningProcess(false),
-                anchor: anchorForTest
-              })
+          detail: {
+            model: createSampleCertificateProvisioningProcess(false),
+            anchor: anchorForTest
+          }
         }));
 
     return whenDialogOpen
         .then(() => {
           const dialog =
-              /** @type {!CertificateProvisioningDetailsDialogElement} */ (
-                  certProvisioningList.shadowRoot.querySelector(dialogId));
+              certProvisioningList.shadowRoot!.querySelector(dialogId);
           assertTrue(!!dialog);
           const whenDialogClosed = eventToPromise('close', dialog);
-          dialog.shadowRoot.querySelector('#dialog')
-              .shadowRoot.querySelector('#close')
-              .click();
+          dialog.$.dialog.shadowRoot!.querySelector<HTMLElement>(
+                                         '#close')!.click();
           return whenDialogClosed;
         })
         .then(() => {
           const dialog =
-              certProvisioningList.shadowRoot.querySelector(dialogId);
+              certProvisioningList.shadowRoot!.querySelector(dialogId);
           assertFalse(!!dialog);
         });
   });
 });
 
 suite('DetailsDialogTests', function() {
-  /** @type {?TestCertificateProvisioningBrowserProxy} */
-  let browserProxy = null;
-
-  /** @type {?CertificateProvisioningListElement} */
-  let certProvisioningList = null;
-
-  let dialog = null;
+  let browserProxy: TestCertificateProvisioningBrowserProxy;
+  let certProvisioningList: CertificateProvisioningListElement;
+  let dialog: CertificateProvisioningDetailsDialogElement;
 
   setup(async function() {
     document.body.innerHTML = '';
@@ -212,8 +185,7 @@
     CertificateProvisioningBrowserProxyImpl.setInstance(browserProxy);
 
     certProvisioningList =
-        /** @type {!CertificateProvisioningListElement} */ (
-            document.createElement('certificate-provisioning-list'));
+        document.createElement('certificate-provisioning-list');
     document.body.appendChild(certProvisioningList);
 
     const anchorForTest = document.createElement('a');
@@ -221,25 +193,23 @@
 
     // Open the details dialog for testing.
     const dialogId = 'certificate-provisioning-details-dialog';
-    assertFalse(!!certProvisioningList.shadowRoot.querySelector(dialogId));
+    assertFalse(!!certProvisioningList.shadowRoot!.querySelector(dialogId));
     const whenDialogOpen =
         eventToPromise('cr-dialog-open', certProvisioningList);
     certProvisioningList.dispatchEvent(
         new CustomEvent(CertificateProvisioningViewDetailsActionEvent, {
           bubbles: true,
           composed: true,
-          detail:
-              /** @type {!CertificateProvisioningActionEventDetail} */ ({
-                model: createSampleCertificateProvisioningProcess(false),
-                anchor: anchorForTest
-              })
+          detail: {
+            model: createSampleCertificateProvisioningProcess(false),
+            anchor: anchorForTest
+          }
         }));
     await whenDialogOpen;
-    dialog = /** @type {!CertificateProvisioningDetailsDialogElement} */ (
-        certProvisioningList.shadowRoot.querySelector(dialogId));
+    dialog = certProvisioningList.shadowRoot!.querySelector(dialogId)!;
     // Check if the dialog is initialized and opened.
     assertTrue(!!dialog);
-    assertTrue(dialog.shadowRoot.querySelector('#dialog').open);
+    assertTrue(dialog.$.dialog.open);
   });
 
   test('RefreshProcess', async function() {
@@ -252,7 +222,7 @@
     assertEquals(dialog.model.certProfileId, certProfileId);
     assertEquals(dialog.model.isDeviceWide, isDeviceWide);
     // Check that the dialog is still open.
-    assertTrue(dialog.shadowRoot.querySelector('#dialog').open);
+    assertTrue(dialog.$.dialog.open);
   });
 
   /**
@@ -283,6 +253,6 @@
     webUIListenerCallback('certificate-provisioning-processes-changed', []);
     flush();
     // Check that the dialog closes if the process no longer exists.
-    assertFalse(dialog.shadowRoot.querySelector('#dialog').open);
+    assertFalse(dialog.$.dialog.open);
   });
 });
diff --git a/chrome/test/data/webui/cr_components/certificate_manager_test.js b/chrome/test/data/webui/cr_components/certificate_manager_test.js
deleted file mode 100644
index 110945cc..0000000
--- a/chrome/test/data/webui/cr_components/certificate_manager_test.js
+++ /dev/null
@@ -1,1022 +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.
-
-// These test suites test the certificate-manager shared component in the
-// context of the Settings privacy page. This simplifies the test setup and
-// provides better context for testing.
-
-// clang-format off
-import 'chrome://settings/strings.m.js';
-
-import {CaTrustEditDialogElement} from 'chrome://resources/cr_components/certificate_manager/ca_trust_edit_dialog.js';
-import {CertificateDeleteConfirmationDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.js';
-import {CertificateListElement} from 'chrome://resources/cr_components/certificate_manager/certificate_list.js';
-import {CertificateManagerElement} from 'chrome://resources/cr_components/certificate_manager/certificate_manager.js';
-import {CertificateAction, CertificateActionEvent} from 'chrome://resources/cr_components/certificate_manager/certificate_manager_types.js';
-import {CertificatePasswordDecryptionDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_password_decryption_dialog.js';
-import {CertificatePasswordEncryptionDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_password_encryption_dialog.js';
-import {CertificateSubentryElement} from 'chrome://resources/cr_components/certificate_manager/certificate_subentry.js';
-import {CertificatesBrowserProxyImpl, CertificateType} from 'chrome://resources/cr_components/certificate_manager/certificates_browser_proxy.js';
-import {isChromeOS, webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
-import {keyEventOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../chai_assert.js';
-import {TestBrowserProxy} from '../test_browser_proxy.js';
-import {eventToPromise} from '../test_util.js';
-// clang-format on
-
-  /**
-   * A test version of CertificatesBrowserProxy. Provides helper methods
-   * for allowing tests to know when a method was called, as well as
-   * specifying mock responses.
-   *
-   * @implements {CertificatesBrowserProxy}
-   */
-  class TestCertificatesBrowserProxy extends TestBrowserProxy {
-    constructor() {
-      super([
-        'deleteCertificate',
-        'editCaCertificateTrust',
-        'exportCertificate',
-        'exportPersonalCertificate',
-        'exportPersonalCertificatePasswordSelected',
-        'getCaCertificateTrust',
-        'importCaCertificate',
-        'importCaCertificateTrustSelected',
-        'importPersonalCertificate',
-        'importPersonalCertificatePasswordSelected',
-        'importServerCertificate',
-        'refreshCertificates',
-        'viewCertificate',
-      ]);
-
-      /** @private {!CaTrustInfo} */
-      this.caTrustInfo_ = {ssl: true, email: true, objSign: true};
-
-      /** @private {?CertificatesError} */
-      this.certificatesError_ = null;
-    }
-
-    /** @param {!CaTrustInfo} caTrustInfo */
-    setCaCertificateTrust(caTrustInfo) {
-      this.caTrustInfo_ = caTrustInfo;
-    }
-
-    /** @override */
-    getCaCertificateTrust(id) {
-      this.methodCalled('getCaCertificateTrust', id);
-      return Promise.resolve(this.caTrustInfo_);
-    }
-
-    /** @override */
-    importServerCertificate() {
-      this.methodCalled('importServerCertificate');
-      return Promise.resolve();
-    }
-
-    /** @override */
-    importCaCertificate() {
-      this.methodCalled('importCaCertificate');
-      return Promise.resolve('dummyName');
-    }
-
-    /** @override */
-    importCaCertificateTrustSelected(ssl, email, objSign) {
-      this.methodCalled(
-          'importCaCertificateTrustSelected',
-          {ssl: ssl, email: email, objSign: objSign});
-      return this.fulfillRequest_();
-    }
-
-    /** @override */
-    editCaCertificateTrust(id, ssl, email, objSign) {
-      this.methodCalled(
-          'editCaCertificateTrust',
-          {id: id, ssl: ssl, email: email, objSign: objSign});
-      return this.fulfillRequest_();
-    }
-
-    /**
-     * Forces some of the browser proxy methods to start returning errors.
-     */
-    forceCertificatesError() {
-      this.certificatesError_ = /** @type {!CertificatesError} */ (
-          {title: 'DummyError', description: 'DummyDescription'});
-    }
-
-    /**
-     * @return {!Promise} A promise that is resolved or rejected based on the
-     * value of |certificatesError_|.
-     * @private
-     */
-    fulfillRequest_() {
-      return this.certificatesError_ === null ?
-          Promise.resolve() :
-          Promise.reject(this.certificatesError_);
-    }
-
-    /** @override */
-    deleteCertificate(id) {
-      this.methodCalled('deleteCertificate', id);
-      return this.fulfillRequest_();
-    }
-
-    /** @override */
-    exportPersonalCertificatePasswordSelected(password) {
-      this.methodCalled('exportPersonalCertificatePasswordSelected', password);
-      return this.fulfillRequest_();
-    }
-
-    /** @override */
-    importPersonalCertificate(useHardwareBacked) {
-      this.methodCalled('importPersonalCertificate', useHardwareBacked);
-      return Promise.resolve(true);
-    }
-
-    /** @override */
-    importPersonalCertificatePasswordSelected(password) {
-      this.methodCalled('importPersonalCertificatePasswordSelected', password);
-      return this.fulfillRequest_();
-    }
-
-    /** @override */
-    refreshCertificates() {
-      this.methodCalled('refreshCertificates');
-    }
-
-    /** @override */
-    viewCertificate(id) {
-      this.methodCalled('viewCertificate', id);
-    }
-
-    /** @override */
-    exportCertificate(id) {
-      this.methodCalled('exportCertificate', id);
-    }
-
-    /** @override */
-    exportPersonalCertificate(id) {
-      this.methodCalled('exportPersonalCertificate', id);
-      return Promise.resolve();
-    }
-
-    /** @override */
-    cancelImportExportCertificate() {}
-  }
-
-  /** @return {!CertificatesOrgGroup} */
-  function createSampleCertificateOrgGroup() {
-    return {
-      id: 'dummyCertificateId',
-      name: 'dummyCertificateName',
-      containsPolicyCerts: false,
-      subnodes: [createSampleCertificateSubnode()],
-    };
-  }
-
-  /** @return {!CertificateSubnode} */
-  function createSampleCertificateSubnode() {
-    return {
-      extractable: false,
-      id: 'dummySubnodeId',
-      name: 'dummySubnodeName',
-      policy: false,
-      canBeDeleted: true,
-      canBeEdited: true,
-      untrusted: false,
-      urlLocked: false,
-      webTrustAnchor: false,
-    };
-  }
-
-  /**
-   * Triggers an 'input' event on the given text input field (which triggers
-   * validation to occur for password fields being tested in this file).
-   * @param {!HTMLElement} element
-   */
-  function triggerInputEvent(element) {
-    // The actual key code is irrelevant for tests.
-    const kSpaceBar = 32;
-    keyEventOn(element, 'input', kSpaceBar);
-  }
-
-  suite('CaTrustEditDialogTests', function() {
-    /** @type {?CaTrustEditDialogElement} */
-    let dialog = null;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    /** @type {!CaTrustInfo} */
-    const caTrustInfo = {ssl: true, email: false, objSign: false};
-
-    setup(async function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      browserProxy.setCaCertificateTrust(caTrustInfo);
-
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      dialog = /** @type {!CaTrustEditDialogElement} */ (
-          document.createElement('ca-trust-edit-dialog'));
-    });
-
-    teardown(function() {
-      dialog.remove();
-    });
-
-    test('EditSuccess', function() {
-      dialog.model = createSampleCertificateSubnode();
-      document.body.appendChild(dialog);
-
-      return browserProxy.whenCalled('getCaCertificateTrust')
-          .then(function(id) {
-            assertEquals(dialog.model.id, id);
-            assertEquals(
-                caTrustInfo.ssl,
-                dialog.shadowRoot.querySelector('#ssl').checked);
-            assertEquals(
-                caTrustInfo.email,
-                dialog.shadowRoot.querySelector('#email').checked);
-            assertEquals(
-                caTrustInfo.objSign,
-                dialog.shadowRoot.querySelector('#objSign').checked);
-
-            // Simulate toggling all checkboxes.
-            dialog.shadowRoot.querySelector('#ssl').click();
-            dialog.shadowRoot.querySelector('#email').click();
-            dialog.shadowRoot.querySelector('#objSign').click();
-
-            // Simulate clicking 'OK'.
-            dialog.shadowRoot.querySelector('#ok').click();
-
-            return browserProxy.whenCalled('editCaCertificateTrust');
-          })
-          .then(function(args) {
-            assertEquals(dialog.model.id, args.id);
-            // Checking that the values sent to C++ are reflecting the
-            // changes made by the user (toggling all checkboxes).
-            assertEquals(caTrustInfo.ssl, !args.ssl);
-            assertEquals(caTrustInfo.email, !args.email);
-            assertEquals(caTrustInfo.objSign, !args.objSign);
-            // Check that the dialog is closed.
-            assertFalse(dialog.shadowRoot.querySelector('#dialog').open);
-          });
-    });
-
-    test('ImportSuccess', function() {
-      dialog.model = {name: 'Dummy certificate name'};
-      document.body.appendChild(dialog);
-
-      assertFalse(dialog.shadowRoot.querySelector('#ssl').checked);
-      assertFalse(dialog.shadowRoot.querySelector('#email').checked);
-      assertFalse(dialog.shadowRoot.querySelector('#objSign').checked);
-
-      dialog.shadowRoot.querySelector('#ssl').click();
-      dialog.shadowRoot.querySelector('#email').click();
-
-      // Simulate clicking 'OK'.
-      dialog.shadowRoot.querySelector('#ok').click();
-      return browserProxy.whenCalled('importCaCertificateTrustSelected')
-          .then(function(args) {
-            assertTrue(args.ssl);
-            assertTrue(args.email);
-            assertFalse(args.objSign);
-          });
-    });
-
-    test('EditError', function() {
-      dialog.model = createSampleCertificateSubnode();
-      document.body.appendChild(dialog);
-      browserProxy.forceCertificatesError();
-
-      const whenErrorEventFired = eventToPromise('certificates-error', dialog);
-
-      return browserProxy.whenCalled('getCaCertificateTrust')
-          .then(function() {
-            dialog.shadowRoot.querySelector('#ok').click();
-            return browserProxy.whenCalled('editCaCertificateTrust');
-          })
-          .then(function() {
-            return whenErrorEventFired;
-          });
-    });
-  });
-
-  suite('CertificateDeleteConfirmationDialogTests', function() {
-    /** @type {!CertificateDeleteConfirmationDialogElement} */
-    let dialog;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    /** @type {!CertificateSubnode} */
-    const model = createSampleCertificateSubnode();
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      dialog = /** @type {!CertificateDeleteConfirmationDialogElement} */ (
-          document.createElement('certificate-delete-confirmation-dialog'));
-      dialog.model = model;
-      dialog.certificateType = CertificateType.PERSONAL;
-      document.body.appendChild(dialog);
-    });
-
-    teardown(function() {
-      dialog.remove();
-    });
-
-    test('DeleteSuccess', function() {
-      assertTrue(dialog.shadowRoot.querySelector('#dialog').open);
-      // Check that the dialog title includes the certificate name.
-      const titleEl = dialog.shadowRoot.querySelector('#dialog').querySelector(
-          '[slot=title]');
-      assertTrue(titleEl.textContent.includes(model.name));
-
-      // Simulate clicking 'OK'.
-      dialog.shadowRoot.querySelector('#ok').click();
-
-      return browserProxy.whenCalled('deleteCertificate').then(function(id) {
-        assertEquals(model.id, id);
-        // Check that the dialog is closed.
-        assertFalse(dialog.shadowRoot.querySelector('#dialog').open);
-      });
-    });
-
-    test('DeleteError', function() {
-      browserProxy.forceCertificatesError();
-      const whenErrorEventFired = eventToPromise('certificates-error', dialog);
-
-      // Simulate clicking 'OK'.
-      dialog.shadowRoot.querySelector('#ok').click();
-      return browserProxy.whenCalled('deleteCertificate').then(function(id) {
-        assertEquals(model.id, id);
-        // Ensure that the 'error' event was fired.
-        return whenErrorEventFired;
-      });
-    });
-  });
-
-  suite('CertificatePasswordEncryptionDialogTests', function() {
-    /** @type {?CertificatePasswordEncryptionDialogElement} */
-    let dialog = null;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    /** @type {!CertificateSubnode} */
-    const model = createSampleCertificateSubnode();
-
-    const methodName = 'exportPersonalCertificatePasswordSelected';
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      dialog = /** @type {!CertificatePasswordEncryptionDialogElement} */ (
-          document.createElement('certificate-password-encryption-dialog'));
-      dialog.model = model;
-      document.body.appendChild(dialog);
-    });
-
-    teardown(function() {
-      dialog.remove();
-    });
-
-    test('EncryptSuccess', function() {
-      const passwordInputElements =
-          dialog.shadowRoot.querySelector('#dialog').querySelectorAll(
-              'cr-input');
-      const passwordInputElement =
-          /** @type {!HTMLElement} */ (passwordInputElements[0]);
-      const confirmPasswordInputElement =
-          /** @type {!HTMLElement} */ (passwordInputElements[1]);
-
-      assertTrue(dialog.shadowRoot.querySelector('#dialog').open);
-      assertTrue(dialog.shadowRoot.querySelector('#ok').disabled);
-
-      // Test that the 'OK' button is disabled when the password fields are
-      // empty (even though they both have the same value).
-      triggerInputEvent(passwordInputElement);
-      assertTrue(dialog.shadowRoot.querySelector('#ok').disabled);
-
-      // Test that the 'OK' button is disabled until the two password fields
-      // match.
-      passwordInputElement.value = 'foopassword';
-      triggerInputEvent(passwordInputElement);
-      assertTrue(dialog.shadowRoot.querySelector('#ok').disabled);
-      confirmPasswordInputElement.value = passwordInputElement.value;
-      triggerInputEvent(confirmPasswordInputElement);
-      assertFalse(dialog.shadowRoot.querySelector('#ok').disabled);
-
-      // Simulate clicking 'OK'.
-      dialog.shadowRoot.querySelector('#ok').click();
-
-      return browserProxy.whenCalled(methodName).then(function(password) {
-        assertEquals(passwordInputElement.value, password);
-        // Check that the dialog is closed.
-        assertFalse(dialog.shadowRoot.querySelector('#dialog').open);
-      });
-    });
-
-    test('EncryptError', function() {
-      browserProxy.forceCertificatesError();
-
-      const passwordInputElements =
-          dialog.shadowRoot.querySelector('#dialog').querySelectorAll(
-              'cr-input');
-      const passwordInputElement =
-          /** @type {!HTMLElement} */ (passwordInputElements[0]);
-      passwordInputElement.value = 'foopassword';
-      const confirmPasswordInputElement =
-          /** @type {!HTMLElement} */ (passwordInputElements[1]);
-      confirmPasswordInputElement.value = passwordInputElement.value;
-      triggerInputEvent(passwordInputElement);
-
-      const whenErrorEventFired = eventToPromise('certificates-error', dialog);
-      dialog.shadowRoot.querySelector('#ok').click();
-
-      return browserProxy.whenCalled(methodName).then(function() {
-        return whenErrorEventFired;
-      });
-    });
-  });
-
-  suite('CertificatePasswordDecryptionDialogTests', function() {
-    /** @type {?CertificatePasswordDecryptionDialogElement} */
-    let dialog = null;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    const methodName = 'importPersonalCertificatePasswordSelected';
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      dialog = /** @type {!CertificatePasswordDecryptionDialogElement} */ (
-          document.createElement('certificate-password-decryption-dialog'));
-      document.body.appendChild(dialog);
-    });
-
-    teardown(function() {
-      dialog.remove();
-    });
-
-    test('DecryptSuccess', function() {
-      const passwordInputElement =
-          dialog.shadowRoot.querySelector('#dialog').querySelector('cr-input');
-      assertTrue(dialog.shadowRoot.querySelector('#dialog').open);
-
-      // Test that the 'OK' button is enabled even when the password field is
-      // empty.
-      assertEquals('', passwordInputElement.value);
-      assertFalse(dialog.shadowRoot.querySelector('#ok').disabled);
-
-      passwordInputElement.value = 'foopassword';
-      assertFalse(dialog.shadowRoot.querySelector('#ok').disabled);
-
-      // Simulate clicking 'OK'.
-      dialog.shadowRoot.querySelector('#ok').click();
-
-      return browserProxy.whenCalled(methodName).then(function(password) {
-        assertEquals(passwordInputElement.value, password);
-        // Check that the dialog is closed.
-        assertFalse(dialog.shadowRoot.querySelector('#dialog').open);
-      });
-    });
-
-    test('DecryptError', function() {
-      browserProxy.forceCertificatesError();
-      // Simulate entering some password.
-      const passwordInputElement = /** @type {!HTMLElement} */ (
-          dialog.shadowRoot.querySelector('#dialog').querySelector('cr-input'));
-      passwordInputElement.value = 'foopassword';
-      triggerInputEvent(passwordInputElement);
-
-      const whenErrorEventFired = eventToPromise('certificates-error', dialog);
-      dialog.shadowRoot.querySelector('#ok').click();
-      return browserProxy.whenCalled(methodName).then(function() {
-        return whenErrorEventFired;
-      });
-    });
-  });
-
-  suite('CertificateSubentryTests', function() {
-    /** @type {!CertificateSubentryElement} */
-    let subentry;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    /**
-     * @return {!Promise} A promise firing once |CertificateActionEvent| fires.
-     */
-    const actionEventToPromise = function() {
-      return eventToPromise(CertificateActionEvent, subentry);
-    };
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      subentry = /** @type {!CertificateSubentryElement} */ (
-          document.createElement('certificate-subentry'));
-      subentry.model = createSampleCertificateSubnode();
-      subentry.certificateType = CertificateType.PERSONAL;
-      document.body.appendChild(subentry);
-
-      // Bring up the popup menu for the following tests to use.
-      subentry.shadowRoot.querySelector('#dots').click();
-      flush();
-    });
-
-    teardown(function() {
-      subentry.remove();
-    });
-
-    // Test case where 'View' option is tapped.
-    test('MenuOptions_View', function() {
-      const viewButton = subentry.shadowRoot.querySelector('#view');
-      viewButton.click();
-      return browserProxy.whenCalled('viewCertificate').then(function(id) {
-        assertEquals(subentry.model.id, id);
-      });
-    });
-
-    // Test that the 'Edit' option is only shown when appropriate and that
-    // once tapped the correct event is fired.
-    test('MenuOptions_Edit', function() {
-      const editButton = subentry.shadowRoot.querySelector('#edit');
-      assertTrue(!!editButton);
-
-      let model = createSampleCertificateSubnode();
-      model.canBeEdited = false;
-      subentry.model = model;
-      assertTrue(editButton.hidden);
-
-      model = createSampleCertificateSubnode();
-      model.canBeEdited = true;
-      subentry.model = model;
-      assertFalse(editButton.hidden);
-
-      subentry.model = createSampleCertificateSubnode();
-      const waitForActionEvent = actionEventToPromise();
-      editButton.click();
-      return waitForActionEvent.then(function(event) {
-        const detail =
-            /** @type {!CertificateActionEventDetail} */ (event.detail);
-        assertEquals(CertificateAction.EDIT, detail.action);
-        assertEquals(subentry.model.id, detail.subnode.id);
-        assertEquals(subentry.certificateType, detail.certificateType);
-      });
-    });
-
-    // Test that the 'Delete' option is only shown when appropriate and that
-    // once tapped the correct event is fired.
-    test('MenuOptions_Delete', function() {
-      const deleteButton = subentry.shadowRoot.querySelector('#delete');
-      assertTrue(!!deleteButton);
-
-      // Should be disabled when 'model.canBeDeleted' is false.
-      const model = createSampleCertificateSubnode();
-      model.canBeDeleted = false;
-      subentry.model = model;
-      assertTrue(deleteButton.hidden);
-
-      subentry.model = createSampleCertificateSubnode();
-      const waitForActionEvent = actionEventToPromise();
-      deleteButton.click();
-      return waitForActionEvent.then(function(event) {
-        const detail =
-            /** @type {!CertificateActionEventDetail} */ (event.detail);
-        assertEquals(CertificateAction.DELETE, detail.action);
-        assertEquals(subentry.model.id, detail.subnode.id);
-      });
-    });
-
-    // Test that the 'Export' option is always shown when the certificate type
-    // is not PERSONAL and that once tapped the correct event is fired.
-    test('MenuOptions_Export', function() {
-      subentry.certificateType = CertificateType.SERVER;
-      const exportButton = subentry.shadowRoot.querySelector('#export');
-      assertTrue(!!exportButton);
-      assertFalse(exportButton.hidden);
-      exportButton.click();
-      return browserProxy.whenCalled('exportCertificate').then(function(id) {
-        assertEquals(subentry.model.id, id);
-      });
-    });
-
-    // Test case of exporting a PERSONAL certificate.
-    test('MenuOptions_ExportPersonal', function() {
-      const exportButton = subentry.shadowRoot.querySelector('#export');
-      assertTrue(!!exportButton);
-
-      // Should be disabled when 'model.extractable' is false.
-      assertTrue(exportButton.hidden);
-
-      const model = createSampleCertificateSubnode();
-      model.extractable = true;
-      subentry.model = model;
-      assertFalse(exportButton.hidden);
-
-      const waitForActionEvent = actionEventToPromise();
-      exportButton.click();
-      return browserProxy.whenCalled('exportPersonalCertificate')
-          .then(function(id) {
-            assertEquals(subentry.model.id, id);
-
-            // A promise firing once |CertificateActionEvent| is
-            // fired.
-            return waitForActionEvent;
-          })
-          .then(function(event) {
-            const detail =
-                /** @type {!CertificateActionEventDetail} */ (event.detail);
-            assertEquals(CertificateAction.EXPORT_PERSONAL, detail.action);
-            assertEquals(subentry.model.id, detail.subnode.id);
-          });
-    });
-  });
-
-  suite('CertificateManagerTests', function() {
-    /** @type {?CertificateManagerElement} */
-    let page = null;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    /** @enum {number} */
-    const CertificateCategoryIndex = {
-      PERSONAL: 0,
-      SERVER: 1,
-      CA: 2,
-      OTHER: 3,
-    };
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      page = /** @type {!CertificateManagerElement} */ (
-          document.createElement('certificate-manager'));
-      document.body.appendChild(page);
-    });
-
-    teardown(function() {
-      page.remove();
-    });
-
-    /**
-     * Test that the page requests information from the browser on startup and
-     * that it gets populated accordingly.
-     */
-    test('Initialization', function() {
-      // Trigger all category tabs to be added to the DOM.
-      const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-      paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-      flush();
-      paperTabsElement.selected = CertificateCategoryIndex.SERVER;
-      flush();
-      paperTabsElement.selected = CertificateCategoryIndex.CA;
-      flush();
-      paperTabsElement.selected = CertificateCategoryIndex.OTHER;
-      flush();
-      const certificateLists =
-          page.shadowRoot.querySelectorAll('certificate-list');
-      assertEquals(4, certificateLists.length);
-
-      const assertCertificateListLength = function(listIndex, expectedSize) {
-        // Need to switch to the corresponding tab before querying the DOM.
-        paperTabsElement.selected = listIndex;
-        flush();
-        const certificateEntries =
-            certificateLists[listIndex].shadowRoot.querySelectorAll(
-                'certificate-entry');
-        assertEquals(expectedSize, certificateEntries.length);
-      };
-
-      assertCertificateListLength(CertificateCategoryIndex.PERSONAL, 0);
-      assertCertificateListLength(CertificateCategoryIndex.SERVER, 0);
-      assertCertificateListLength(CertificateCategoryIndex.CA, 0);
-      assertCertificateListLength(CertificateCategoryIndex.OTHER, 0);
-
-      return browserProxy.whenCalled('refreshCertificates').then(function() {
-        // Simulate response for personal and CA certificates.
-        webUIListenerCallback(
-            'certificates-changed', 'personalCerts',
-            [createSampleCertificateOrgGroup()]);
-        webUIListenerCallback('certificates-changed', 'caCerts', [
-          createSampleCertificateOrgGroup(), createSampleCertificateOrgGroup()
-        ]);
-        flush();
-
-        assertCertificateListLength(CertificateCategoryIndex.PERSONAL, 1);
-        assertCertificateListLength(CertificateCategoryIndex.SERVER, 0);
-        assertCertificateListLength(CertificateCategoryIndex.CA, 2);
-        assertCertificateListLength(CertificateCategoryIndex.OTHER, 0);
-      });
-    });
-
-    /**
-     * Tests that a dialog opens as a response to a
-     * CertificateActionEvent.
-     * @param {string} dialogTagName The type of dialog to test.
-     * @param {CertificateActionEventDetail} eventDetail
-     * @return {!Promise}
-     */
-    function testDialogOpensOnAction(dialogTagName, eventDetail) {
-      assertFalse(!!page.shadowRoot.querySelector(dialogTagName));
-      const whenDialogOpen = eventToPromise('cr-dialog-open', page);
-      page.dispatchEvent(new CustomEvent(
-          CertificateActionEvent,
-          {bubbles: true, composed: true, detail: eventDetail}));
-
-      // Some dialogs are opened after some async operation to fetch initial
-      // data. Ensure that the underlying cr-dialog is actually opened before
-      // returning.
-      return whenDialogOpen.then(() => {
-        assertTrue(!!page.shadowRoot.querySelector(dialogTagName));
-      });
-    }
-
-    test('OpensDialog_DeleteConfirmation', function() {
-      return testDialogOpensOnAction(
-          'certificate-delete-confirmation-dialog',
-          /** @type {!CertificateActionEventDetail} */ ({
-            action: CertificateAction.DELETE,
-            subnode: createSampleCertificateSubnode(),
-            certificateType: CertificateType.PERSONAL
-          }));
-    });
-
-    test('OpensDialog_PasswordEncryption', function() {
-      return testDialogOpensOnAction(
-          'certificate-password-encryption-dialog',
-          /** @type {!CertificateActionEventDetail} */ ({
-            action: CertificateAction.EXPORT_PERSONAL,
-            subnode: createSampleCertificateSubnode(),
-            certificateType: CertificateType.PERSONAL
-          }));
-    });
-
-    test('OpensDialog_PasswordDecryption', function() {
-      return testDialogOpensOnAction(
-          'certificate-password-decryption-dialog',
-          /** @type {!CertificateActionEventDetail} */ ({
-            action: CertificateAction.IMPORT,
-            subnode: createSampleCertificateSubnode(),
-            certificateType: CertificateType.PERSONAL
-          }));
-    });
-
-    test('OpensDialog_CaTrustEdit', function() {
-      return testDialogOpensOnAction(
-          'ca-trust-edit-dialog',
-          /** @type {!CertificateActionEventDetail} */ ({
-            action: CertificateAction.EDIT,
-            subnode: createSampleCertificateSubnode(),
-            certificateType: CertificateType.CA
-          }));
-    });
-
-    test('OpensDialog_CaTrustImport', function() {
-      return testDialogOpensOnAction(
-          'ca-trust-edit-dialog',
-          /** @type {!CertificateActionEventDetail} */ ({
-            action: CertificateAction.IMPORT,
-            subnode: {name: 'Dummy Certificate Name', id: null},
-            certificateType: CertificateType.CA
-          }));
-    });
-
-    if (isChromeOS) {
-      // Test that import buttons are hidden by default.
-      test('ImportButton_Default', function() {
-        const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-        paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-        flush();
-        paperTabsElement.selected = CertificateCategoryIndex.CA;
-        flush();
-        const certificateLists =
-            page.shadowRoot.querySelectorAll('certificate-list');
-        const clientImportButton =
-            certificateLists[0].shadowRoot.querySelector('#import');
-        assertTrue(clientImportButton.hidden);
-        const clientImportAndBindButton =
-            certificateLists[0].shadowRoot.querySelector('#importAndBind');
-        assertTrue(clientImportAndBindButton.hidden);
-        const caImportButton =
-            certificateLists[1].shadowRoot.querySelector('#import');
-        assertTrue(caImportButton.hidden);
-      });
-
-      // Test that ClientCertificateManagementAllowed policy is applied to the
-      // UI when management is allowed.
-      test('ImportButton_ClientPolicyAllowed', function() {
-        const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-        paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-        flush();
-        paperTabsElement.selected = CertificateCategoryIndex.CA;
-        flush();
-        const certificateLists =
-            page.shadowRoot.querySelectorAll('certificate-list');
-
-        return browserProxy.whenCalled('refreshCertificates').then(function() {
-          webUIListenerCallback(
-              'client-import-allowed-changed', true /* clientImportAllowed */);
-          // Verify that import buttons are shown in the client certificate
-          // tab.
-          const clientImportButton =
-              certificateLists[0].shadowRoot.querySelector('#import');
-          assertFalse(clientImportButton.hidden);
-          const clientImportAndBindButton =
-              certificateLists[0].shadowRoot.querySelector('#importAndBind');
-          assertFalse(clientImportAndBindButton.hidden);
-          // Verify that import button is still hidden in the CA certificate
-          // tab.
-          const caImportButton =
-              certificateLists[1].shadowRoot.querySelector('#import');
-          assertTrue(caImportButton.hidden);
-        });
-      });
-
-      // Test that ClientCertificateManagementAllowed policy is applied to the
-      // UI when management is not allowed.
-      test('ImportButton_ClientPolicyDisallowed', function() {
-        const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-        paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-        flush();
-        paperTabsElement.selected = CertificateCategoryIndex.CA;
-        flush();
-        const certificateLists =
-            page.shadowRoot.querySelectorAll('certificate-list');
-
-        return browserProxy.whenCalled('refreshCertificates').then(function() {
-          webUIListenerCallback(
-              'client-import-allowed-changed', false /* clientImportAllowed */);
-          // Verify that import buttons are still hidden in the client
-          // certificate tab.
-          const clientImportButton =
-              certificateLists[0].shadowRoot.querySelector('#import');
-          assertTrue(clientImportButton.hidden);
-          const clientImportAndBindButton =
-              certificateLists[0].shadowRoot.querySelector('#importAndBind');
-          assertTrue(clientImportAndBindButton.hidden);
-          // Verify that import button is still hidden in the CA certificate
-          // tab.
-          const caImportButton =
-              certificateLists[1].shadowRoot.querySelector('#import');
-          assertTrue(caImportButton.hidden);
-        });
-      });
-
-      // Test that CACertificateManagementAllowed policy is applied to the
-      // UI when management is allowed.
-      test('ImportButton_CAPolicyAllowed', function() {
-        const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-        paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-        flush();
-        paperTabsElement.selected = CertificateCategoryIndex.CA;
-        flush();
-        const certificateLists =
-            page.shadowRoot.querySelectorAll('certificate-list');
-
-        return browserProxy.whenCalled('refreshCertificates').then(function() {
-          webUIListenerCallback(
-              'ca-import-allowed-changed', true /* clientImportAllowed */);
-          // Verify that import buttons are still hidden in the client
-          // certificate tab.
-          const clientImportButton =
-              certificateLists[0].shadowRoot.querySelector('#import');
-          assertTrue(clientImportButton.hidden);
-          const clientImportAndBindButton =
-              certificateLists[0].shadowRoot.querySelector('#importAndBind');
-          assertTrue(clientImportAndBindButton.hidden);
-          // Verify that import button is shown in the CA certificate tab.
-          const caImportButton =
-              certificateLists[1].shadowRoot.querySelector('#import');
-          assertFalse(caImportButton.hidden);
-        });
-      });
-
-      // Test that CACertificateManagementAllowed policy is applied to the
-      // UI when management is not allowed.
-      test('ImportButton_CAPolicyDisallowed', function() {
-        const paperTabsElement = page.shadowRoot.querySelector('cr-tabs');
-        paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
-        flush();
-        paperTabsElement.selected = CertificateCategoryIndex.CA;
-        flush();
-        const certificateLists =
-            page.shadowRoot.querySelectorAll('certificate-list');
-
-        return browserProxy.whenCalled('refreshCertificates').then(function() {
-          webUIListenerCallback(
-              'ca-import-allowed-changed', false /* clientImportAllowed */);
-          // Verify that import buttons are still hidden in the client
-          // certificate tab.
-          const clientImportButton =
-              certificateLists[0].shadowRoot.querySelector('#import');
-          assertTrue(clientImportButton.hidden);
-          const clientImportAndBindButton =
-              certificateLists[0].shadowRoot.querySelector('#importAndBind');
-          assertTrue(clientImportAndBindButton.hidden);
-          // Verify that import button is still hidden in the CA certificate
-          // tab.
-          const caImportButton =
-              certificateLists[1].shadowRoot.querySelector('#import');
-          assertTrue(caImportButton.hidden);
-        });
-      });
-    }
-  });
-
-  suite('CertificateListTests', function() {
-    /** @type {?CertificateListElement} */
-    let element = null;
-
-    /** @type {?TestCertificatesBrowserProxy} */
-    let browserProxy = null;
-
-    setup(function() {
-      browserProxy = new TestCertificatesBrowserProxy();
-      CertificatesBrowserProxyImpl.setInstance(browserProxy);
-      document.body.innerHTML = '';
-      element = /** @type {!CertificateListElement} */ (
-          document.createElement('certificate-list'));
-      document.body.appendChild(element);
-    });
-
-    teardown(function() {
-      element.remove();
-    });
-
-    /**
-     * Tests the "Import" button functionality.
-     * @param {!CertificateType} certificateType
-     * @param {string} proxyMethodName The name of the proxy method expected
-     *     to be called.
-     * @param {boolean} actionEventExpected Whether a
-     *     CertificateActionEvent is expected to fire as a result tapping the
-     *     Import button.
-     * @param {boolean} bindBtn Whether to click on the import and bind btn.
-     */
-    function testImportForCertificateType(
-        certificateType, proxyMethodName, actionEventExpected, bindBtn) {
-      element.certificateType = certificateType;
-      flush();
-
-      const importButton = bindBtn ?
-          element.shadowRoot.querySelector('#importAndBind') :
-          element.shadowRoot.querySelector('#import');
-      assertTrue(!!importButton);
-
-      const waitForActionEvent = actionEventExpected ?
-          eventToPromise(CertificateActionEvent, element) :
-          Promise.resolve(null);
-
-      importButton.click();
-      return browserProxy.whenCalled(proxyMethodName)
-          .then(function(arg) {
-            if (proxyMethodName === 'importPersonalCertificate') {
-              assertNotEquals(arg, undefined);
-              assertEquals(arg, bindBtn);
-            }
-            return waitForActionEvent;
-          })
-          .then(function(event) {
-            if (actionEventExpected) {
-              assertEquals(CertificateAction.IMPORT, event.detail.action);
-              assertEquals(certificateType, event.detail.certificateType);
-            }
-          });
-    }
-
-    test('ImportButton_Personal', function() {
-      return testImportForCertificateType(
-          CertificateType.PERSONAL, 'importPersonalCertificate', true, false);
-    });
-
-    if (isChromeOS) {
-      test('ImportAndBindButton_Personal', function() {
-        return testImportForCertificateType(
-            CertificateType.PERSONAL, 'importPersonalCertificate', true, true);
-      });
-    }
-
-    test('ImportButton_Server', function() {
-      return testImportForCertificateType(
-          CertificateType.SERVER, 'importServerCertificate', false, false);
-    });
-
-    test('ImportButton_CA', function() {
-      return testImportForCertificateType(
-          CertificateType.CA, 'importCaCertificate', true, false);
-    });
-  });
diff --git a/chrome/test/data/webui/cr_components/certificate_manager_test.ts b/chrome/test/data/webui/cr_components/certificate_manager_test.ts
new file mode 100644
index 0000000..f84b115
--- /dev/null
+++ b/chrome/test/data/webui/cr_components/certificate_manager_test.ts
@@ -0,0 +1,956 @@
+// 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.
+
+// These test suites test the certificate-manager shared component in the
+// context of the Settings privacy page. This simplifies the test setup and
+// provides better context for testing.
+
+// clang-format off
+import 'chrome://settings/strings.m.js';
+import 'chrome://resources/cr_components/certificate_manager/ca_trust_edit_dialog.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_password_encryption_dialog.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_list.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_password_decryption_dialog.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_manager.js';
+import 'chrome://resources/cr_components/certificate_manager/certificate_subentry.js';
+
+import {CaTrustEditDialogElement} from 'chrome://resources/cr_components/certificate_manager/ca_trust_edit_dialog.js';
+import {CertificateDeleteConfirmationDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.js';
+import {CertificateListElement} from 'chrome://resources/cr_components/certificate_manager/certificate_list.js';
+import {CertificateManagerElement} from 'chrome://resources/cr_components/certificate_manager/certificate_manager.js';
+import {CertificateAction, CertificateActionEvent, CertificateActionEventDetail} from 'chrome://resources/cr_components/certificate_manager/certificate_manager_types.js';
+import {CertificatePasswordDecryptionDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_password_decryption_dialog.js';
+import {CertificatePasswordEncryptionDialogElement} from 'chrome://resources/cr_components/certificate_manager/certificate_password_encryption_dialog.js';
+import {CertificateSubentryElement} from 'chrome://resources/cr_components/certificate_manager/certificate_subentry.js';
+import {CaTrustInfo, CertificatesBrowserProxy, CertificatesBrowserProxyImpl, CertificatesError, CertificatesOrgGroup, CertificateSubnode, CertificateType} from 'chrome://resources/cr_components/certificate_manager/certificates_browser_proxy.js';
+import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
+import {keyEventOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+// clang-format on
+
+/**
+ * A test version of CertificatesBrowserProxy. Provides helper methods
+ * for allowing tests to know when a method was called, as well as
+ * specifying mock responses.
+ */
+class TestCertificatesBrowserProxy extends TestBrowserProxy implements
+    CertificatesBrowserProxy {
+  private caTrustInfo_: CaTrustInfo;
+  private certificatesError_: CertificatesError|null = null;
+
+  constructor() {
+    super([
+      'deleteCertificate',
+      'editCaCertificateTrust',
+      'exportCertificate',
+      'exportPersonalCertificate',
+      'exportPersonalCertificatePasswordSelected',
+      'getCaCertificateTrust',
+      'importCaCertificate',
+      'importCaCertificateTrustSelected',
+      'importPersonalCertificate',
+      'importPersonalCertificatePasswordSelected',
+      'importServerCertificate',
+      'refreshCertificates',
+      'viewCertificate',
+    ]);
+
+    this.caTrustInfo_ = {ssl: true, email: true, objSign: true};
+  }
+
+  setCaCertificateTrust(caTrustInfo: CaTrustInfo) {
+    this.caTrustInfo_ = caTrustInfo;
+  }
+
+  getCaCertificateTrust(id: string) {
+    this.methodCalled('getCaCertificateTrust', id);
+    return Promise.resolve(this.caTrustInfo_);
+  }
+
+  importServerCertificate() {
+    this.methodCalled('importServerCertificate');
+    return Promise.resolve();
+  }
+
+  importCaCertificate() {
+    this.methodCalled('importCaCertificate');
+    return Promise.resolve('dummyName');
+  }
+
+  importCaCertificateTrustSelected(
+      ssl: boolean, email: boolean, objSign: boolean) {
+    this.methodCalled(
+        'importCaCertificateTrustSelected',
+        {ssl: ssl, email: email, objSign: objSign});
+    return this.fulfillRequest_();
+  }
+
+  editCaCertificateTrust(
+      id: string, ssl: boolean, email: boolean, objSign: boolean) {
+    this.methodCalled('editCaCertificateTrust', {id, ssl, email, objSign});
+    return this.fulfillRequest_();
+  }
+
+  /**
+   * Forces some of the browser proxy methods to start returning errors.
+   */
+  forceCertificatesError() {
+    this.certificatesError_ = {
+      title: 'DummyError',
+      description: 'DummyDescription'
+    };
+  }
+
+  /**
+   * @return A promise that is resolved or rejected based on the
+   *     value of |certificatesError_|.
+   */
+  private fulfillRequest_(): Promise<void> {
+    return this.certificatesError_ === null ?
+        Promise.resolve() :
+        Promise.reject(this.certificatesError_);
+  }
+
+  deleteCertificate(id: string) {
+    this.methodCalled('deleteCertificate', id);
+    return this.fulfillRequest_();
+  }
+
+  exportPersonalCertificatePasswordSelected(password: string) {
+    this.methodCalled('exportPersonalCertificatePasswordSelected', password);
+    return this.fulfillRequest_();
+  }
+
+  importPersonalCertificate(useHardwareBacked: boolean) {
+    this.methodCalled('importPersonalCertificate', useHardwareBacked);
+    return Promise.resolve(true);
+  }
+
+  importPersonalCertificatePasswordSelected(password: string) {
+    this.methodCalled('importPersonalCertificatePasswordSelected', password);
+    return this.fulfillRequest_();
+  }
+
+  refreshCertificates() {
+    this.methodCalled('refreshCertificates');
+  }
+
+  viewCertificate(id: string) {
+    this.methodCalled('viewCertificate', id);
+  }
+
+  exportCertificate(id: string) {
+    this.methodCalled('exportCertificate', id);
+  }
+
+  exportPersonalCertificate(id: string) {
+    this.methodCalled('exportPersonalCertificate', id);
+    return Promise.resolve();
+  }
+
+  cancelImportExportCertificate() {}
+}
+
+function createSampleCertificateOrgGroup(): CertificatesOrgGroup {
+  return {
+    id: 'dummyCertificateId',
+    name: 'dummyCertificateName',
+    containsPolicyCerts: false,
+    subnodes: [createSampleCertificateSubnode()],
+  };
+}
+
+function createSampleCertificateSubnode(): CertificateSubnode {
+  return {
+    extractable: false,
+    id: 'dummySubnodeId',
+    name: 'dummySubnodeName',
+    policy: false,
+    canBeDeleted: true,
+    canBeEdited: true,
+    untrusted: false,
+    webTrustAnchor: false,
+  };
+}
+
+/**
+ * Triggers an 'input' event on the given text input field (which triggers
+ * validation to occur for password fields being tested in this file).
+ */
+function triggerInputEvent(element: HTMLElement) {
+  // The actual key code is irrelevant for tests.
+  const kSpaceBar = 32;
+  keyEventOn(element, 'input', kSpaceBar);
+}
+
+suite('CaTrustEditDialogTests', function() {
+  let dialog: CaTrustEditDialogElement;
+
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  const caTrustInfo: CaTrustInfo = {ssl: true, email: false, objSign: false};
+
+  setup(async function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    browserProxy.setCaCertificateTrust(caTrustInfo);
+
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    dialog = document.createElement('ca-trust-edit-dialog');
+  });
+
+  teardown(function() {
+    dialog.remove();
+  });
+
+  test('EditSuccess', function() {
+    dialog.model = createSampleCertificateSubnode();
+    document.body.appendChild(dialog);
+
+    return browserProxy.whenCalled('getCaCertificateTrust')
+        .then(function(id) {
+          assertEquals((dialog.model as CertificateSubnode).id, id);
+          assertEquals(caTrustInfo.ssl, dialog.$.ssl.checked);
+          assertEquals(caTrustInfo.email, dialog.$.email.checked);
+          assertEquals(caTrustInfo.objSign, dialog.$.objSign.checked);
+
+          // Simulate toggling all checkboxes.
+          dialog.$.ssl.click();
+          dialog.$.email.click();
+          dialog.$.objSign.click();
+
+          // Simulate clicking 'OK'.
+          dialog.$.ok.click();
+
+          return browserProxy.whenCalled('editCaCertificateTrust');
+        })
+        .then(function(args) {
+          assertEquals((dialog.model as CertificateSubnode).id, args.id);
+          // Checking that the values sent to C++ are reflecting the
+          // changes made by the user (toggling all checkboxes).
+          assertEquals(caTrustInfo.ssl, !args.ssl);
+          assertEquals(caTrustInfo.email, !args.email);
+          assertEquals(caTrustInfo.objSign, !args.objSign);
+          // Check that the dialog is closed.
+          assertFalse(dialog.$.dialog.open);
+        });
+  });
+
+  test('ImportSuccess', function() {
+    dialog.model = {name: 'Dummy certificate name'};
+    document.body.appendChild(dialog);
+
+    assertFalse(dialog.$.ssl.checked);
+    assertFalse(dialog.$.email.checked);
+    assertFalse(dialog.$.objSign.checked);
+
+    dialog.$.ssl.click();
+    dialog.$.email.click();
+
+    // Simulate clicking 'OK'.
+    dialog.$.ok.click();
+    return browserProxy.whenCalled('importCaCertificateTrustSelected')
+        .then(function(args) {
+          assertTrue(args.ssl);
+          assertTrue(args.email);
+          assertFalse(args.objSign);
+        });
+  });
+
+  test('EditError', function() {
+    dialog.model = createSampleCertificateSubnode();
+    document.body.appendChild(dialog);
+    browserProxy.forceCertificatesError();
+
+    const whenErrorEventFired = eventToPromise('certificates-error', dialog);
+
+    return browserProxy.whenCalled('getCaCertificateTrust')
+        .then(function() {
+          dialog.$.ok.click();
+          return browserProxy.whenCalled('editCaCertificateTrust');
+        })
+        .then(function() {
+          return whenErrorEventFired;
+        });
+  });
+});
+
+suite('CertificateDeleteConfirmationDialogTests', function() {
+  let dialog: CertificateDeleteConfirmationDialogElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  const model = createSampleCertificateSubnode();
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    dialog = document.createElement('certificate-delete-confirmation-dialog');
+    dialog.model = model;
+    dialog.certificateType = CertificateType.PERSONAL;
+    document.body.appendChild(dialog);
+  });
+
+  teardown(function() {
+    dialog.remove();
+  });
+
+  test('DeleteSuccess', function() {
+    assertTrue(dialog.$.dialog.open);
+    // Check that the dialog title includes the certificate name.
+    const titleEl = dialog.$.dialog.querySelector('[slot=title]');
+    assertTrue(!!titleEl);
+    assertTrue(titleEl.textContent!.includes(model.name));
+
+    // Simulate clicking 'OK'.
+    dialog.$.ok.click();
+
+    return browserProxy.whenCalled('deleteCertificate').then(function(id) {
+      assertEquals(model.id, id);
+      // Check that the dialog is closed.
+      assertFalse(dialog.$.dialog.open);
+    });
+  });
+
+  test('DeleteError', function() {
+    browserProxy.forceCertificatesError();
+    const whenErrorEventFired = eventToPromise('certificates-error', dialog);
+
+    // Simulate clicking 'OK'.
+    dialog.$.ok.click();
+    return browserProxy.whenCalled('deleteCertificate').then(function(id) {
+      assertEquals(model.id, id);
+      // Ensure that the 'error' event was fired.
+      return whenErrorEventFired;
+    });
+  });
+});
+
+suite('CertificatePasswordEncryptionDialogTests', function() {
+  let dialog: CertificatePasswordEncryptionDialogElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  const methodName = 'exportPersonalCertificatePasswordSelected';
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    dialog = document.createElement('certificate-password-encryption-dialog');
+    document.body.appendChild(dialog);
+  });
+
+  teardown(function() {
+    dialog.remove();
+  });
+
+  test('EncryptSuccess', function() {
+    const passwordInputElements = dialog.$.dialog.querySelectorAll('cr-input');
+    const passwordInputElement = passwordInputElements[0];
+    assertTrue(!!passwordInputElement);
+    const confirmPasswordInputElement = passwordInputElements[1];
+    assertTrue(!!confirmPasswordInputElement);
+
+    assertTrue(dialog.$.dialog.open);
+    assertTrue(dialog.$.ok.disabled);
+
+    // Test that the 'OK' button is disabled when the password fields are
+    // empty (even though they both have the same value).
+    triggerInputEvent(passwordInputElement);
+    assertTrue(dialog.$.ok.disabled);
+
+    // Test that the 'OK' button is disabled until the two password fields
+    // match.
+    passwordInputElement.value = 'foopassword';
+    triggerInputEvent(passwordInputElement);
+    assertTrue(dialog.$.ok.disabled);
+    confirmPasswordInputElement.value = passwordInputElement.value;
+    triggerInputEvent(confirmPasswordInputElement);
+    assertFalse(dialog.$.ok.disabled);
+
+    // Simulate clicking 'OK'.
+    dialog.$.ok.click();
+
+    return browserProxy.whenCalled(methodName).then(function(password) {
+      assertEquals(passwordInputElement.value, password);
+      // Check that the dialog is closed.
+      assertFalse(dialog.$.dialog.open);
+    });
+  });
+
+  test('EncryptError', function() {
+    browserProxy.forceCertificatesError();
+
+    const passwordInputElements = dialog.$.dialog.querySelectorAll('cr-input');
+    const passwordInputElement = passwordInputElements[0];
+    assertTrue(!!passwordInputElement);
+    const confirmPasswordInputElement = passwordInputElements[1];
+    assertTrue(!!confirmPasswordInputElement);
+
+    passwordInputElement.value = 'foopassword';
+    confirmPasswordInputElement.value = passwordInputElement.value;
+    triggerInputEvent(passwordInputElement);
+
+    const whenErrorEventFired = eventToPromise('certificates-error', dialog);
+    dialog.$.ok.click();
+
+    return browserProxy.whenCalled(methodName).then(function() {
+      return whenErrorEventFired;
+    });
+  });
+});
+
+suite('CertificatePasswordDecryptionDialogTests', function() {
+  let dialog: CertificatePasswordDecryptionDialogElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  const methodName = 'importPersonalCertificatePasswordSelected';
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    dialog = document.createElement('certificate-password-decryption-dialog');
+    document.body.appendChild(dialog);
+  });
+
+  teardown(function() {
+    dialog.remove();
+  });
+
+  test('DecryptSuccess', function() {
+    const passwordInputElement = dialog.$.dialog.querySelector('cr-input');
+    assertTrue(!!passwordInputElement);
+    assertTrue(dialog.$.dialog.open);
+
+    // Test that the 'OK' button is enabled even when the password field is
+    // empty.
+    assertEquals('', passwordInputElement.value);
+    assertFalse(dialog.$.ok.disabled);
+
+    passwordInputElement.value = 'foopassword';
+    assertFalse(dialog.$.ok.disabled);
+
+    // Simulate clicking 'OK'.
+    dialog.$.ok.click();
+
+    return browserProxy.whenCalled(methodName).then(function(password) {
+      assertEquals(passwordInputElement.value, password);
+      // Check that the dialog is closed.
+      assertFalse(dialog.$.dialog.open);
+    });
+  });
+
+  test('DecryptError', function() {
+    browserProxy.forceCertificatesError();
+    // Simulate entering some password.
+    const passwordInputElement = dialog.$.dialog.querySelector('cr-input');
+    assertTrue(!!passwordInputElement);
+    passwordInputElement.value = 'foopassword';
+    triggerInputEvent(passwordInputElement);
+
+    const whenErrorEventFired = eventToPromise('certificates-error', dialog);
+    dialog.$.ok.click();
+    return browserProxy.whenCalled(methodName).then(function() {
+      return whenErrorEventFired;
+    });
+  });
+});
+
+suite('CertificateSubentryTests', function() {
+  let subentry: CertificateSubentryElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  /**
+   * @return A promise firing once |CertificateActionEvent| fires.
+   */
+  function actionEventToPromise():
+      Promise<CustomEvent<CertificateActionEventDetail>> {
+    return eventToPromise(CertificateActionEvent, subentry);
+  }
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    subentry = document.createElement('certificate-subentry');
+    subentry.model = createSampleCertificateSubnode();
+    subentry.certificateType = CertificateType.PERSONAL;
+    document.body.appendChild(subentry);
+
+    // Bring up the popup menu for the following tests to use.
+    subentry.$.dots.click();
+    flush();
+  });
+
+  teardown(function() {
+    subentry.remove();
+  });
+
+  // Test case where 'View' option is tapped.
+  test('MenuOptions_View', function() {
+    const viewButton = subentry.shadowRoot!.querySelector<HTMLElement>('#view');
+    assertTrue(!!viewButton);
+    viewButton.click();
+    return browserProxy.whenCalled('viewCertificate').then(function(id) {
+      assertEquals(subentry.model.id, id);
+    });
+  });
+
+  // Test that the 'Edit' option is only shown when appropriate and that
+  // once tapped the correct event is fired.
+  test('MenuOptions_Edit', function() {
+    const editButton = subentry.shadowRoot!.querySelector<HTMLElement>('#edit');
+    assertTrue(!!editButton);
+
+    let model = createSampleCertificateSubnode();
+    model.canBeEdited = false;
+    subentry.model = model;
+    assertTrue(editButton.hidden);
+
+    model = createSampleCertificateSubnode();
+    model.canBeEdited = true;
+    subentry.model = model;
+    assertFalse(editButton.hidden);
+
+    subentry.model = createSampleCertificateSubnode();
+    const waitForActionEvent = actionEventToPromise();
+    editButton.click();
+    return waitForActionEvent.then(function(event) {
+      const detail = event.detail;
+      assertEquals(CertificateAction.EDIT, detail.action);
+      assertEquals(
+          subentry.model.id, (detail.subnode as CertificateSubnode).id);
+      assertEquals(subentry.certificateType, detail.certificateType);
+    });
+  });
+
+  // Test that the 'Delete' option is only shown when appropriate and that
+  // once tapped the correct event is fired.
+  test('MenuOptions_Delete', function() {
+    const deleteButton =
+        subentry.shadowRoot!.querySelector<HTMLElement>('#delete');
+    assertTrue(!!deleteButton);
+
+    // Should be disabled when 'model.canBeDeleted' is false.
+    const model = createSampleCertificateSubnode();
+    model.canBeDeleted = false;
+    subentry.model = model;
+    assertTrue(deleteButton.hidden);
+
+    subentry.model = createSampleCertificateSubnode();
+    const waitForActionEvent = actionEventToPromise();
+    deleteButton.click();
+    return waitForActionEvent.then(function(event) {
+      const detail = event.detail;
+      assertEquals(CertificateAction.DELETE, detail.action);
+      assertEquals(
+          subentry.model.id, (detail.subnode as CertificateSubnode).id);
+    });
+  });
+
+  // Test that the 'Export' option is always shown when the certificate type
+  // is not PERSONAL and that once tapped the correct event is fired.
+  test('MenuOptions_Export', function() {
+    subentry.certificateType = CertificateType.SERVER;
+    const exportButton =
+        subentry.shadowRoot!.querySelector<HTMLElement>('#export');
+    assertTrue(!!exportButton);
+    assertFalse(exportButton.hidden);
+    exportButton.click();
+    return browserProxy.whenCalled('exportCertificate').then(function(id) {
+      assertEquals(subentry.model.id, id);
+    });
+  });
+
+  // Test case of exporting a PERSONAL certificate.
+  test('MenuOptions_ExportPersonal', function() {
+    const exportButton =
+        subentry.shadowRoot!.querySelector<HTMLElement>('#export');
+    assertTrue(!!exportButton);
+
+    // Should be disabled when 'model.extractable' is false.
+    assertTrue(exportButton.hidden);
+
+    const model = createSampleCertificateSubnode();
+    model.extractable = true;
+    subentry.model = model;
+    assertFalse(exportButton.hidden);
+
+    const waitForActionEvent = actionEventToPromise();
+    exportButton.click();
+    return browserProxy.whenCalled('exportPersonalCertificate')
+        .then(function(id) {
+          assertEquals(subentry.model.id, id);
+
+          // A promise firing once |CertificateActionEvent| is
+          // fired.
+          return waitForActionEvent;
+        })
+        .then(function(event) {
+          const detail = event.detail;
+          assertEquals(CertificateAction.EXPORT_PERSONAL, detail.action);
+          assertEquals(
+              subentry.model.id, (detail.subnode as CertificateSubnode).id);
+        });
+  });
+});
+
+suite('CertificateManagerTests', function() {
+  let page: CertificateManagerElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  enum CertificateCategoryIndex {
+    PERSONAL = 0,
+    SERVER = 1,
+    CA = 2,
+    OTHER = 3,
+  }
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    page = document.createElement('certificate-manager');
+    document.body.appendChild(page);
+  });
+
+  teardown(function() {
+    page.remove();
+  });
+
+  /**
+   * Test that the page requests information from the browser on startup and
+   * that it gets populated accordingly.
+   */
+  test('Initialization', function() {
+    // Trigger all category tabs to be added to the DOM.
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.SERVER;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.OTHER;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+    assertEquals(4, certificateLists.length);
+
+    function assertCertificateListLength(
+        listIndex: CertificateCategoryIndex, expectedSize: number) {
+      // Need to switch to the corresponding tab before querying the DOM.
+      assertTrue(!!paperTabsElement);
+      paperTabsElement.selected = listIndex;
+      flush();
+      const certificateEntries =
+          certificateLists[listIndex]!.shadowRoot!.querySelectorAll(
+              'certificate-entry');
+      assertEquals(expectedSize, certificateEntries.length);
+    }
+
+    assertCertificateListLength(CertificateCategoryIndex.PERSONAL, 0);
+    assertCertificateListLength(CertificateCategoryIndex.SERVER, 0);
+    assertCertificateListLength(CertificateCategoryIndex.CA, 0);
+    assertCertificateListLength(CertificateCategoryIndex.OTHER, 0);
+
+    return browserProxy.whenCalled('refreshCertificates').then(function() {
+      // Simulate response for personal and CA certificates.
+      webUIListenerCallback(
+          'certificates-changed', 'personalCerts',
+          [createSampleCertificateOrgGroup()]);
+      webUIListenerCallback('certificates-changed', 'caCerts', [
+        createSampleCertificateOrgGroup(), createSampleCertificateOrgGroup()
+      ]);
+      flush();
+
+      assertCertificateListLength(CertificateCategoryIndex.PERSONAL, 1);
+      assertCertificateListLength(CertificateCategoryIndex.SERVER, 0);
+      assertCertificateListLength(CertificateCategoryIndex.CA, 2);
+      assertCertificateListLength(CertificateCategoryIndex.OTHER, 0);
+    });
+  });
+
+  /**
+   * Tests that a dialog opens as a response to a CertificateActionEvent.
+   * @param dialogTagName The type of dialog to test.
+   */
+  function testDialogOpensOnAction(
+      dialogTagName: string,
+      eventDetail: CertificateActionEventDetail): Promise<void> {
+    assertFalse(!!page.shadowRoot!.querySelector(dialogTagName));
+    const whenDialogOpen = eventToPromise('cr-dialog-open', page);
+    page.dispatchEvent(new CustomEvent(
+        CertificateActionEvent,
+        {bubbles: true, composed: true, detail: eventDetail}));
+
+    // Some dialogs are opened after some async operation to fetch initial
+    // data. Ensure that the underlying cr-dialog is actually opened before
+    // returning.
+    return whenDialogOpen.then(() => {
+      assertTrue(!!page.shadowRoot!.querySelector(dialogTagName));
+    });
+  }
+
+  test('OpensDialog_DeleteConfirmation', function() {
+    return testDialogOpensOnAction('certificate-delete-confirmation-dialog', {
+      action: CertificateAction.DELETE,
+      subnode: createSampleCertificateSubnode(),
+      certificateType: CertificateType.PERSONAL,
+      anchor: page,
+    });
+  });
+
+  test('OpensDialog_PasswordEncryption', function() {
+    return testDialogOpensOnAction('certificate-password-encryption-dialog', {
+      action: CertificateAction.EXPORT_PERSONAL,
+      subnode: createSampleCertificateSubnode(),
+      certificateType: CertificateType.PERSONAL,
+      anchor: page,
+    });
+  });
+
+  test('OpensDialog_PasswordDecryption', function() {
+    return testDialogOpensOnAction('certificate-password-decryption-dialog', {
+      action: CertificateAction.IMPORT,
+      subnode: createSampleCertificateSubnode(),
+      certificateType: CertificateType.PERSONAL,
+      anchor: page,
+    });
+  });
+
+  test('OpensDialog_CaTrustEdit', function() {
+    return testDialogOpensOnAction('ca-trust-edit-dialog', {
+      action: CertificateAction.EDIT,
+      subnode: createSampleCertificateSubnode(),
+      certificateType: CertificateType.CA,
+      anchor: page,
+    });
+  });
+
+  test('OpensDialog_CaTrustImport', function() {
+    return testDialogOpensOnAction('ca-trust-edit-dialog', {
+      action: CertificateAction.IMPORT,
+      subnode: {name: 'Dummy Certificate Name', id: ''},
+      certificateType: CertificateType.CA,
+      anchor: page,
+    });
+  });
+
+  // <if expr="chromeos_ash">
+  // Test that import buttons are hidden by default.
+  test('ImportButton_Default', function() {
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+    const clientImportButton = certificateLists[0]!.$.import;
+    assertTrue(clientImportButton.hidden);
+    const clientImportAndBindButton = certificateLists[0]!.$.importAndBind;
+    assertTrue(clientImportAndBindButton.hidden);
+    const caImportButton = certificateLists[1]!.$.import;
+    assertTrue(caImportButton.hidden);
+  });
+
+  // Test that ClientCertificateManagementAllowed policy is applied to the
+  // UI when management is allowed.
+  test('ImportButton_ClientPolicyAllowed', function() {
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+
+    return browserProxy.whenCalled('refreshCertificates').then(function() {
+      webUIListenerCallback(
+          'client-import-allowed-changed', true /* clientImportAllowed */);
+      // Verify that import buttons are shown in the client certificate
+      // tab.
+      const clientImportButton = certificateLists[0]!.$.import;
+      assertFalse(clientImportButton.hidden);
+      const clientImportAndBindButton = certificateLists[0]!.$.importAndBind;
+      assertFalse(clientImportAndBindButton.hidden);
+      // Verify that import button is still hidden in the CA certificate
+      // tab.
+      const caImportButton = certificateLists[1]!.$.import;
+      assertTrue(caImportButton.hidden);
+    });
+  });
+
+  // Test that ClientCertificateManagementAllowed policy is applied to the
+  // UI when management is not allowed.
+  test('ImportButton_ClientPolicyDisallowed', function() {
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+
+    return browserProxy.whenCalled('refreshCertificates').then(function() {
+      webUIListenerCallback(
+          'client-import-allowed-changed', false /* clientImportAllowed */);
+      // Verify that import buttons are still hidden in the client
+      // certificate tab.
+      const clientImportButton = certificateLists[0]!.$.import;
+      assertTrue(clientImportButton.hidden);
+      const clientImportAndBindButton = certificateLists[0]!.$.importAndBind;
+      assertTrue(clientImportAndBindButton.hidden);
+      // Verify that import button is still hidden in the CA certificate
+      // tab.
+      const caImportButton = certificateLists[1]!.$.import;
+      assertTrue(caImportButton.hidden);
+    });
+  });
+
+  // Test that CACertificateManagementAllowed policy is applied to the
+  // UI when management is allowed.
+  test('ImportButton_CAPolicyAllowed', function() {
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+
+    return browserProxy.whenCalled('refreshCertificates').then(function() {
+      webUIListenerCallback(
+          'ca-import-allowed-changed', true /* clientImportAllowed */);
+      // Verify that import buttons are still hidden in the client
+      // certificate tab.
+      const clientImportButton = certificateLists[0]!.$.import;
+      assertTrue(clientImportButton.hidden);
+      const clientImportAndBindButton = certificateLists[0]!.$.importAndBind;
+      assertTrue(clientImportAndBindButton.hidden);
+      // Verify that import button is shown in the CA certificate tab.
+      const caImportButton = certificateLists[1]!.$.import;
+      assertFalse(caImportButton.hidden);
+    });
+  });
+
+  // Test that CACertificateManagementAllowed policy is applied to the
+  // UI when management is not allowed.
+  test('ImportButton_CAPolicyDisallowed', function() {
+    const paperTabsElement = page.shadowRoot!.querySelector('cr-tabs');
+    assertTrue(!!paperTabsElement);
+    paperTabsElement.selected = CertificateCategoryIndex.PERSONAL;
+    flush();
+    paperTabsElement.selected = CertificateCategoryIndex.CA;
+    flush();
+    const certificateLists =
+        page.shadowRoot!.querySelectorAll('certificate-list');
+
+    return browserProxy.whenCalled('refreshCertificates').then(function() {
+      webUIListenerCallback(
+          'ca-import-allowed-changed', false /* clientImportAllowed */);
+      // Verify that import buttons are still hidden in the client
+      // certificate tab.
+      const clientImportButton = certificateLists[0]!.$.import;
+      assertTrue(clientImportButton.hidden);
+      const clientImportAndBindButton = certificateLists[0]!.$.importAndBind;
+      assertTrue(clientImportAndBindButton.hidden);
+      // Verify that import button is still hidden in the CA certificate
+      // tab.
+      const caImportButton = certificateLists[1]!.$.import;
+      assertTrue(caImportButton.hidden);
+    });
+  });
+  // </if>
+});
+
+suite('CertificateListTests', function() {
+  let element: CertificateListElement;
+  let browserProxy: TestCertificatesBrowserProxy;
+
+  setup(function() {
+    browserProxy = new TestCertificatesBrowserProxy();
+    CertificatesBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = '';
+    element = document.createElement('certificate-list');
+    document.body.appendChild(element);
+  });
+
+  teardown(function() {
+    element.remove();
+  });
+
+  /**
+   * Tests the "Import" button functionality.
+   * @param proxyMethodName The name of the proxy method expected to be
+   *     called.
+   * @param actionEventExpected Whether a CertificateActionEvent is expected
+   *     to fire as a result tapping the Import button.
+   * @param bindBtn Whether to click on the import and bind btn.
+   */
+  function testImportForCertificateType(
+      certificateType: CertificateType, proxyMethodName: string,
+      actionEventExpected: boolean, bindBtn: boolean) {
+    element.certificateType = certificateType;
+    flush();
+
+    const importButton = bindBtn ?
+        element.shadowRoot!.querySelector<HTMLElement>('#importAndBind') :
+        element.shadowRoot!.querySelector<HTMLElement>('#import');
+    assertTrue(!!importButton);
+
+    const waitForActionEvent = actionEventExpected ?
+        eventToPromise(CertificateActionEvent, element) :
+        Promise.resolve(null);
+
+    importButton.click();
+    return browserProxy.whenCalled(proxyMethodName)
+        .then(function(arg) {
+          if (proxyMethodName === 'importPersonalCertificate') {
+            assertNotEquals(arg, undefined);
+            assertEquals(arg, bindBtn);
+          }
+          return waitForActionEvent;
+        })
+        .then(function(event) {
+          if (actionEventExpected) {
+            assertEquals(CertificateAction.IMPORT, event.detail.action);
+            assertEquals(certificateType, event.detail.certificateType);
+          }
+        });
+  }
+
+  test('ImportButton_Personal', function() {
+    return testImportForCertificateType(
+        CertificateType.PERSONAL, 'importPersonalCertificate', true, false);
+  });
+
+  // <if expr="chromeos_ash">
+  test('ImportAndBindButton_Personal', function() {
+    return testImportForCertificateType(
+        CertificateType.PERSONAL, 'importPersonalCertificate', true, true);
+  });
+  // </if>
+
+  test('ImportButton_Server', function() {
+    return testImportForCertificateType(
+        CertificateType.SERVER, 'importServerCertificate', false, false);
+  });
+
+  test('ImportButton_CA', function() {
+    return testImportForCertificateType(
+        CertificateType.CA, 'importCaCertificate', true, false);
+  });
+});
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js
index 395a54c..c98d897 100644
--- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js
+++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/activation_code_page_test.js
@@ -10,7 +10,7 @@
 // #import {assertTrue} from '../../../chai_assert.js';
 // #import {FakeMediaDevices} from './fake_media_devices.m.js';
 // #import {FakeBarcodeDetector, FakeImageCapture} from './fake_barcode_detector.m.js';
-// #import {eventToPromise, flushTasks} from 'chrome://test/test_util.js';
+// #import {eventToPromise, flushTasks, waitAfterNextRender} from 'chrome://test/test_util.js';
 // clang-format on
 
 suite('CrComponentsActivationCodePageTest', function() {
@@ -52,6 +52,8 @@
     mediaDevices = new cellular_setup.FakeMediaDevices();
     mediaDevices.addDevice();
     activationCodePage.setMediaDevices(mediaDevices);
+    mediaDevices.resolveEnumerateDevices();
+    await waitAfterNextRender(activationCodePage);
     Polymer.dom.flush();
   });
 
@@ -99,7 +101,8 @@
 
     // Click the start scanning button.
     startScanningButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     // The video should be visible and start scanning UI hidden.
     assertFalse(video.hidden);
@@ -145,7 +148,8 @@
 
     // Mock, no media devices present
     mediaDevices.removeDevice();
-    await flushAsync();
+    mediaDevices.resolveEnumerateDevices();
+    await waitAfterNextRender(activationCodePage);
 
     // When no camera device is present qrCodeDetector container should
     // not be shown
@@ -154,8 +158,7 @@
     assertFalse(!!qrCodeDetectorContainer);
   });
 
-  // TODO(b/217936048) Disable flaky test. Renable when test is fixed.
-  test.skip('Switch camera button states', async function() {
+  test('Switch camera button states', async function() {
     await flushAsync();
     const video = activationCodePage.$$('#video');
     const startScanningButton = activationCodePage.$$('#startScanningButton');
@@ -171,7 +174,8 @@
 
     // Click the start scanning button.
     startScanningButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     // The video should be visible and switch camera button hidden.
     assertFalse(video.hidden);
@@ -180,14 +184,16 @@
 
     // Add a new video device.
     mediaDevices.addDevice();
-    await flushAsync();
+    mediaDevices.resolveEnumerateDevices();
+    await waitAfterNextRender(activationCodePage);
 
     // The switch camera button should now be visible.
     assertFalse(switchCameraButton.hidden);
     assertTrue(mediaDevices.isStreamingUserFacingCamera);
 
     switchCameraButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     // The second device should now be streaming.
     assertFalse(mediaDevices.isStreamingUserFacingCamera);
@@ -195,7 +201,8 @@
 
     // Switch back.
     switchCameraButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     // The first device should be streaming again.
     assertTrue(mediaDevices.isStreamingUserFacingCamera);
@@ -203,14 +210,16 @@
 
     // Switch to the second device again.
     switchCameraButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     assertFalse(mediaDevices.isStreamingUserFacingCamera);
     assertFalse(switchCameraButton.hidden);
 
     // Disconnect the second device.
     mediaDevices.removeDevice();
-    await flushAsync();
+    mediaDevices.resolveEnumerateDevices();
+    await waitAfterNextRender(activationCodePage);
 
     // The first device should now be streaming and the switch camera button
     // hidden.
@@ -338,7 +347,8 @@
 
         // Click the start scanning button.
         startScanningButton.click();
-        await flushAsync();
+        mediaDevices.resolveGetUserMedia();
+        await waitAfterNextRender(activationCodePage);
 
         // Mock camera scanning a code.
         await intervalFunction();
@@ -379,7 +389,8 @@
 
     // Click the start scanning button.
     startScanningButton.click();
-    await flushAsync();
+    mediaDevices.resolveGetUserMedia();
+    await waitAfterNextRender(activationCodePage);
 
     assertFalse(getVideo().hidden);
 
@@ -409,7 +420,8 @@
 
         // Click the start scanning button.
         startScanningButton.click();
-        await flushAsync();
+        mediaDevices.resolveGetUserMedia();
+        await waitAfterNextRender(activationCodePage);
 
         assertFalse(getVideo().hidden);
         assertTrue(!!activationCodePage.getQrCodeDetectorTimerForTest());
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js
index 876981ce..89d7add6bb 100644
--- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js
+++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/fake_media_devices.js
@@ -10,6 +10,12 @@
     constructor() {
       this.isStreamingUserFacingCamera = true;
       this.devices_ = [];
+
+      /** @private {?function()} */
+      this.enumerateDevicesResolver_ = null;
+
+      /** @private {?function()} */
+      this.getMediaDevicesResolver_ = null;
     }
 
     /** @override */
@@ -20,10 +26,19 @@
     /** @override */
     enumerateDevices() {
       return new Promise((res, rej) => {
-        res(this.devices_);
+        this.enumerateDevicesResolver_ = res;
       });
     }
 
+    /**
+     * Resolves promise returned from enumerateDevices().
+     */
+    resolveEnumerateDevices() {
+      assertTrue(
+          !!this.enumerateDevicesResolver_, 'enumerateDevices was not called');
+      this.enumerateDevicesResolver_(this.devices_);
+    }
+
     /** @override */
     getSupportedConstraints() {
       return null;
@@ -41,10 +56,19 @@
       this.isStreamingUserFacingCamera =
           constraints.video.facingMode === 'user';
       return new Promise((res, rej) => {
-        res(new MediaStream());
+        this.getMediaDevicesResolver_ = res;
       });
     }
 
+    /**
+     * Resolves promise returned from getUserMedia().
+     */
+    resolveGetUserMedia() {
+      assertTrue(
+          !!this.getMediaDevicesResolver_, 'getUserMedia was not called');
+      this.getMediaDevicesResolver_(new MediaStream);
+    }
+
     /** @override */
     removeEventListener(event, fn) {}
 
diff --git a/chrome/test/data/webui/cr_components/cr_components_browsertest.js b/chrome/test/data/webui/cr_components/cr_components_browsertest.js
index 7d606eec..0ff9e07 100644
--- a/chrome/test/data/webui/cr_components/cr_components_browsertest.js
+++ b/chrome/test/data/webui/cr_components/cr_components_browsertest.js
@@ -60,7 +60,7 @@
 var CrComponentsCertificateManagerTest = class extends CrComponentsBrowserTest {
   /** @override */
   get browsePreload() {
-    return 'chrome://settings/test_loader.html?module=cr_components/certificate_manager_test.js';
+    return 'chrome://settings/test_loader.html?module=cr_components/certificate_manager_test.js&host=webui-test';
   }
 };
 
@@ -82,7 +82,7 @@
     class extends CrComponentsCertificateManagerTest {
   /** @override */
   get browsePreload() {
-    return 'chrome://settings/test_loader.html?module=cr_components/certificate_manager_provisioning_test.js';
+    return 'chrome://settings/test_loader.html?module=cr_components/certificate_manager_provisioning_test.js&host=webui-test';
   }
 };
 
diff --git a/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.ts b/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.ts
index 92bdea63..2e8b653 100644
--- a/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.ts
+++ b/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.ts
@@ -10,6 +10,7 @@
 
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
 import {MockController} from 'chrome://webui-test/mock_controller.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
 // clang-format on
 
 class FakeMediaQueryList extends EventTarget implements MediaQueryList {
@@ -76,16 +77,19 @@
   let progressArc: CrFingerprintProgressArcElement;
   let canvas: HTMLCanvasElement;
 
-  const black: Color = {r: 0, g: 0, b: 0};
-  const blue: Color = {r: 0, g: 0, b: 255};
-  const white: Color = {r: 255, g: 255, b: 255};
+  const canvasColor: Color = {r: 0, g: 0, b: 255};
+  const canvasColorStr: string = 'rgba(0,0,255,1.0)';
+  const circleBackgroundColor: Color = {r: 0, g: 255, b: 0};
+  const circleBackgroundColorStr: string = 'rgba(0,255,0,1.0)';
+  const circleProgressColor: Color = {r: 255, g: 0, b: 0};
+  const circleProgressColorStr: string = 'rgba(255,0,0,1.0)';
 
   let mockController: MockController;
   let fakeMediaQueryList: FakeMediaQueryList;
 
   function clearCanvas(canvas: HTMLCanvasElement) {
     const ctx = canvas.getContext('2d')!;
-    ctx.fillStyle = 'rgba(255,255,255,1.0)';
+    ctx.fillStyle = canvasColorStr;
     ctx.fillRect(0, 0, canvas.width, canvas.height);
   }
 
@@ -93,7 +97,6 @@
     mockController = new MockController();
     const matchMediaMock =
         mockController.createFunctionMock(window, 'matchMedia');
-    matchMediaMock.addExpectation('(prefers-color-scheme: dark)');
     fakeMediaQueryList = new FakeMediaQueryList('(prefers-color-scheme: dark)');
     matchMediaMock.returnValue = fakeMediaQueryList;
 
@@ -108,8 +111,8 @@
     canvas.height = 150;
     progressArc.circleRadius = 50;
     progressArc.canvasCircleStrokeWidth = 3;
-    progressArc.canvasCircleBackgroundColor = 'rgba(0,0,0,1.0)';
-    progressArc.canvasCircleProgressColor = 'rgba(0,0,255,1.0)';
+    progressArc.canvasCircleBackgroundColor = circleBackgroundColorStr;
+    progressArc.canvasCircleProgressColor = circleProgressColorStr;
     clearCanvas(progressArc.$.canvas);
     flush();
   });
@@ -148,64 +151,93 @@
     }
   }
 
-  test('TestDrawArc', function() {
-    // Verify that by drawing an arc from 0 to PI/2 with radius 50 and center at
-    // (150, 75), points along that arc should be blue, and points not on that
-    // arc should remain white.
-    progressArc.drawArc(0, Math.PI / 2, progressArc.canvasCircleProgressColor);
-    let expectedPointsOnArc = [
-      {x: 200, y: 75} /* 0rad */, {x: 185, y: 110} /* PI/4rad */,
-      {x: 150, y: 125} /* PI/2rad */
+  test('TestSetProgress', async () => {
+    // Angles on HTML canvases start at 0 radians on the positive x-axis and
+    // increase in the clockwise direction. Progress is drawn starting from the
+    // top of the circle (3pi/2 rad). We will check the colors drawn at angles
+    // 7pi/4, pi/4, 3pi/4, and 5pi/4 rad (respectively 12.5%, 37.5%, 62.5%, and
+    // 87.5% progress completed).
+    const checkPoints = [
+      {x: 185, y: 40} /* 7pi/4 rad */, {x: 185, y: 110} /* pi/4 rad */,
+      {x: 115, y: 110} /* 3pi/4 rad */, {x: 115, y: 40} /* 5pi/4 rad */
     ];
-    let expectedPointsNotOnArc =
-        [{x: 115, y: 110} /* 3PI/4rad */, {x: 100, y: 75} /* PI */];
-    assertListOfColorsEqual(blue, expectedPointsOnArc);
-    assertListOfColorsEqual(white, expectedPointsNotOnArc);
 
-    // After clearing, the points that were blue should be white.
-    clearCanvas(progressArc.$.canvas);
-    assertListOfColorsEqual(white, expectedPointsOnArc);
+    const testCases = [
+      // Verify that no progress is drawn when no progress has been made.
+      {
+        'setProgressArgs': {
+          'prevPercentComplete': 0,
+          'currPercentComplete': 0,
+          'isComplete': false
+        },
+        'progressArcPoints': [],
+        'backgroundArcPoints': checkPoints
+      },
+      // Verify that progress is drawn starting from the top of the circle
+      // (3pi/2 rad) and moving clockwise.
+      {
+        'setProgressArgs': {
+          'prevPercentComplete': 0,
+          'currPercentComplete': 40,
+          'isComplete': false
+        },
+        'progressArcPoints': [
+          {x: 185, y: 40} /* 7pi/4 rad */, {x: 185, y: 110} /* pi/4 rad */
+        ],
+        'backgroundArcPoints': [
+          {x: 115, y: 110} /* 3pi/4 rad */, {x: 115, y: 40} /* 5pi/4 rad */
+        ]
+      },
+      // Verify that the progress drawn includes progress made previously.
+      {
+        'setProgressArgs': {
+          'prevPercentComplete': 40,
+          'currPercentComplete': 80,
+          'isComplete': false
+        },
+        'progressArcPoints': [
+          {x: 185, y: 40} /* 7pi/4 rad */, {x: 185, y: 110} /* pi/4 rad */,
+          {x: 115, y: 110} /* 3pi/4 rad */
+        ],
+        'backgroundArcPoints': [
+          {x: 115, y: 40} /* 5pi/4 rad */
+        ]
+      },
+      // Verify that progress past 100% gets capped rather than wrapping around.
+      {
+        'setProgressArgs': {
+          'prevPercentComplete': 80,
+          'currPercentComplete': 160,
+          'isComplete': false
+        },
+        'progressArcPoints': checkPoints,
+        'backgroundArcPoints': []
+      },
+      // Verify that if the enrollment is complete, maximum progress is drawn.
+      {
+        'setProgressArgs': {
+          'prevPercentComplete': 80,
+          'currPercentComplete': 80,
+          'isComplete': true
+        },
+        'progressArcPoints': checkPoints,
+        'backgroundArcPoints': []
+      }
+    ];
 
-    // Verify that by drawing an arc from 3PI/2 to 5PI/2 with radius 50 and
-    // center at (150, 75), points along that arc should be blue, and points not
-    // on that arc should remain white.
-    progressArc.drawArc(
-        3 * Math.PI / 2, 5 * Math.PI / 2,
-        progressArc.canvasCircleProgressColor);
-    expectedPointsOnArc = [
-      {x: 150, y: 25} /* 3PI/2 */, {x: 185, y: 40} /* 7PI/4 */,
-      {x: 200, y: 75} /* 2PI */, {x: 185, y: 110} /* 9PI/4 */,
-      {x: 150, y: 125} /* 5PI/2rad */
-    ];
-    expectedPointsNotOnArc = [
-      {x: 115, y: 110} /* 3PI/4rad */, {x: 100, y: 75} /* PI */, {x: 115, y: 40}
-      /* 5PI/4 */
-    ];
-    assertListOfColorsEqual(blue, expectedPointsOnArc);
-    assertListOfColorsEqual(white, expectedPointsNotOnArc);
-  });
+    for (const {setProgressArgs, progressArcPoints, backgroundArcPoints} of
+             testCases) {
+      clearCanvas(canvas);
+      assertListOfColorsEqual(canvasColor, checkPoints);
 
-  test('TestDrawBackgroundCircle', function() {
-    // Verify that by drawing an circle with radius 50 and center at (150, 75),
-    // points along that arc should be black, and points not on that arc should
-    // remain white.
-    progressArc.drawBackgroundCircle();
-    const expectedPointsInCircle = [
-      {x: 200, y: 75} /* 0rad */, {x: 150, y: 125} /* PI/2rad */,
-      {x: 100, y: 75} /* PIrad */, {x: 150, y: 25} /* 3PI/2rad */
-    ];
-    const expectedPointsNotInCircle = [
-      {x: 110, y: 75} /* Too left, outside of stroke */,
-      {x: 90, y: 75} /* Too right, inside of stroke */,
-      {x: 200, y: 100} /* Outside of circle */,
-      {x: 150, y: 75} /* In the center */
-    ];
-    assertListOfColorsEqual(black, expectedPointsInCircle);
-    assertListOfColorsEqual(white, expectedPointsNotInCircle);
+      progressArc.setProgress(
+          setProgressArgs.prevPercentComplete,
+          setProgressArgs.currPercentComplete, setProgressArgs.isComplete);
+      await eventToPromise('cr-fingerprint-progress-arc-drawn', progressArc);
 
-    // After clearing, the points that were black should be white.
-    clearCanvas(progressArc.$.canvas);
-    assertListOfColorsEqual(white, expectedPointsInCircle);
+      assertListOfColorsEqual(circleProgressColor, progressArcPoints);
+      assertListOfColorsEqual(circleBackgroundColor, backgroundArcPoints);
+    }
   });
 
   test('TestSwitchToDarkMode', function() {
diff --git a/chrome/test/data/webui/history/BUILD.gn b/chrome/test/data/webui/history/BUILD.gn
index 6e0ea7a..e8ce73c 100644
--- a/chrome/test/data/webui/history/BUILD.gn
+++ b/chrome/test/data/webui/history/BUILD.gn
@@ -10,7 +10,7 @@
   "history_clusters/utils.ts",
   "history_drawer_test.ts",
   "history_item_focus_test.ts",
-  "history_item_test.js",
+  "history_item_test.ts",
   "history_list_focus_test.ts",
   "history_list_test.ts",
   "history_metrics_test.ts",
@@ -18,7 +18,7 @@
   "history_routing_test.ts",
   "history_routing_with_query_param_test.ts",
   "history_supervised_user_test.ts",
-  "history_synced_device_manager_focus_test.js",
+  "history_synced_device_manager_focus_test.ts",
   "history_synced_tabs_test.ts",
   "history_toolbar_focus_test.ts",
   "history_toolbar_test.ts",
diff --git a/chrome/test/data/webui/history/history_item_test.js b/chrome/test/data/webui/history/history_item_test.ts
similarity index 62%
rename from chrome/test/data/webui/history/history_item_test.js
rename to chrome/test/data/webui/history/history_item_test.ts
index 14362b6..ef5233b 100644
--- a/chrome/test/data/webui/history/history_item_test.js
+++ b/chrome/test/data/webui/history/history_item_test.ts
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {BrowserServiceImpl, ensureLazyLoaded} from 'chrome://history/history.js';
+import 'chrome://history/history.js';
+
+import {BrowserServiceImpl, HistoryItemElement, HistoryListElement} from 'chrome://history/history.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/test_util.js';
 
 import {TestBrowserService} from './test_browser_service.js';
@@ -25,14 +28,14 @@
 ];
 
 suite('<history-item> unit test', function() {
-  let item;
+  let item: HistoryItemElement;
 
   setup(function() {
     document.body.innerHTML = '';
     BrowserServiceImpl.setInstance(new TestBrowserService());
 
     item = document.createElement('history-item');
-    item.item = TEST_HISTORY_RESULTS[0];
+    item.item = TEST_HISTORY_RESULTS[0]!;
     document.body.appendChild(item);
   });
 
@@ -61,14 +64,14 @@
 
     time.dispatchEvent(new CustomEvent('mouseover'));
     const initialTitle = time.title;
-    item.item = TEST_HISTORY_RESULTS[5];
+    item.item = TEST_HISTORY_RESULTS[5]!;
     time.dispatchEvent(new CustomEvent('mouseover'));
     assertNotEquals(initialTitle, time.title);
   });
 });
 
 suite('<history-item> integration test', function() {
-  let element;
+  let element: HistoryListElement;
 
   setup(function() {
     document.body.innerHTML = '';
@@ -82,60 +85,61 @@
   });
 
   function getHistoryData() {
-    return element.$['infinite-list'].items;
+    return element.$['infinite-list'].items!;
   }
 
   test('basic separator insertion', function() {
-    element.addNewResults(TEST_HISTORY_RESULTS);
+    element.addNewResults(TEST_HISTORY_RESULTS, false, true);
     return flushTasks().then(function() {
       flush();
       // Check that the correct number of time gaps are inserted.
-      const items = element.shadowRoot.querySelectorAll('history-item');
+      const items = element.shadowRoot!.querySelectorAll('history-item');
 
-      assertTrue(items[0].hasTimeGap);
-      assertTrue(items[1].hasTimeGap);
-      assertFalse(items[2].hasTimeGap);
-      assertTrue(items[3].hasTimeGap);
-      assertFalse(items[4].hasTimeGap);
-      assertFalse(items[5].hasTimeGap);
+      assertTrue(items[0]!.hasTimeGap);
+      assertTrue(items[1]!.hasTimeGap);
+      assertFalse(items[2]!.hasTimeGap);
+      assertTrue(items[3]!.hasTimeGap);
+      assertFalse(items[4]!.hasTimeGap);
+      assertFalse(items[5]!.hasTimeGap);
     });
   });
 
   test('separator insertion for search', function() {
-    element.addNewResults(SEARCH_HISTORY_RESULTS);
+    element.addNewResults(SEARCH_HISTORY_RESULTS, false, true);
     element.searchedTerm = 'search';
 
     return flushTasks().then(function() {
       flush();
-      const items = element.shadowRoot.querySelectorAll('history-item');
+      const items = element.shadowRoot!.querySelectorAll('history-item');
 
-      assertTrue(items[0].hasTimeGap);
-      assertFalse(items[1].hasTimeGap);
-      assertFalse(items[2].hasTimeGap);
+      assertTrue(items[0]!.hasTimeGap);
+      assertFalse(items[1]!.hasTimeGap);
+      assertFalse(items[2]!.hasTimeGap);
     });
   });
 
-  test('separator insertion after deletion', function() {
-    element.addNewResults(TEST_HISTORY_RESULTS);
-    return flushTasks().then(function() {
-      flush();
-      const items = element.shadowRoot.querySelectorAll('history-item');
+  test('separator insertion after deletion', async function() {
+    element.addNewResults(TEST_HISTORY_RESULTS, false, true);
+    await flushTasks();
+    const items = element.shadowRoot!.querySelectorAll('history-item');
 
-      element.removeItemsByIndex_([3]);
-      assertEquals(5, getHistoryData().length);
+    element.removeItemsByIndexForTesting([3]);
+    await flushTasks();
 
-      // Checks that a new time gap separator has been inserted.
-      assertTrue(items[2].hasTimeGap);
+    // Checks that a new time gap separator has been inserted.
+    assertEquals(5, getHistoryData().length);
+    assertTrue(items[2]!.hasTimeGap);
 
-      element.removeItemsByIndex_([3]);
+    element.removeItemsByIndexForTesting([3]);
+    await flushTasks();
 
-      // Checks time gap separator is removed.
-      assertFalse(items[2].hasTimeGap);
-    });
+    // Checks time gap separator is removed.
+    assertEquals(4, element.$['infinite-list'].items!.length);
+    assertFalse(items[2]!.hasTimeGap);
   });
 
   test('remove bookmarks', function() {
-    element.addNewResults(TEST_HISTORY_RESULTS);
+    element.addNewResults(TEST_HISTORY_RESULTS, false, true);
     return flushTasks()
         .then(function() {
           element.set('historyData_.1.starred', true);
@@ -143,10 +147,13 @@
           return flushTasks();
         })
         .then(function() {
-          const items = element.shadowRoot.querySelectorAll('history-item');
+          const items = element.shadowRoot!.querySelectorAll('history-item');
 
-          items[1].$$('#bookmark-star').focus();
-          items[1].$$('#bookmark-star').click();
+          const star = items[1]!.shadowRoot!.querySelector<HTMLElement>(
+              '#bookmark-star');
+          assertTrue(!!star);
+          star.focus();
+          star.click();
 
           // Check that all items matching this url are unstarred.
           assertEquals(getHistoryData()[1].starred, false);
diff --git a/chrome/test/data/webui/history/history_synced_device_manager_focus_test.js b/chrome/test/data/webui/history/history_synced_device_manager_focus_test.ts
similarity index 73%
rename from chrome/test/data/webui/history/history_synced_device_manager_focus_test.js
rename to chrome/test/data/webui/history/history_synced_device_manager_focus_test.ts
index ac01f2d..4a82330 100644
--- a/chrome/test/data/webui/history/history_synced_device_manager_focus_test.js
+++ b/chrome/test/data/webui/history/history_synced_device_manager_focus_test.ts
@@ -2,15 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {ensureLazyLoaded} from 'chrome://history/history.js';
+import 'chrome://history/history.js';
+
+import {ensureLazyLoaded, HistorySyncedDeviceManagerElement} from 'chrome://history/history.js';
 import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
 import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
+import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/test_util.js';
 
-import {createSession, createWindow, polymerSelectAll} from './test_util.js';
+import {createSession, createWindow} from './test_util.js';
 
 suite('<history-synced-device-manager>', function() {
-  let element;
+  let element: HistorySyncedDeviceManagerElement;
 
   setup(function() {
     document.body.innerHTML = '';
@@ -34,13 +37,13 @@
 
     element.sessionList = sessionList;
 
-    let cards;
-    let focused;
-
     await flushTasks();
-    cards = polymerSelectAll(element, 'history-synced-device-card');
+    let cards =
+        element.shadowRoot!.querySelectorAll('history-synced-device-card');
+    assertTrue(!!cards[0]);
+    assertTrue(!!cards[1]);
 
-    focused = cards[0].$['menu-button'];
+    let focused = cards[0].$['menu-button'];
     focused.focus();
 
     // Go to the collapse button.
@@ -50,7 +53,8 @@
 
     // Go to the first url.
     pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-    focused = polymerSelectAll(cards[0], '.website-link')[0];
+    focused =
+        cards[0].shadowRoot!.querySelectorAll<HTMLElement>('.website-link')[0]!;
     assertEquals(focused, getDeepActiveElement());
 
     // Collapse the first card.
@@ -74,15 +78,18 @@
 
     // First card's urls are focusable again.
     pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-    focused = polymerSelectAll(cards[0], '.website-link')[0];
+    focused =
+        cards[0].shadowRoot!.querySelectorAll<HTMLElement>('.website-link')[0]!;
     assertEquals(focused, getDeepActiveElement());
 
     // Remove the second URL from the first card.
-    sessionList[0].windows[0].tabs.splice(1, 1);
+    sessionList[0]!.windows[0]!.tabs.splice(1, 1);
     element.sessionList = sessionList.slice();
     await flushTasks();
 
-    cards = polymerSelectAll(element, 'history-synced-device-card');
+    cards = element.shadowRoot!.querySelectorAll('history-synced-device-card');
+    assertTrue(!!cards[0]);
+    assertTrue(!!cards[1]);
 
     // Go to the next card's menu buttons.
     pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
@@ -90,7 +97,8 @@
     assertEquals(focused, getDeepActiveElement());
 
     pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
-    focused = polymerSelectAll(cards[0], '.website-link')[0];
+    focused =
+        cards[0].shadowRoot!.querySelectorAll<HTMLElement>('.website-link')[0]!;
     assertEquals(focused, getDeepActiveElement());
 
     // Remove the second card.
@@ -98,7 +106,8 @@
     element.sessionList = sessionList.slice();
     await flushTasks();
 
-    cards = polymerSelectAll(element, 'history-synced-device-card');
+    cards = element.shadowRoot!.querySelectorAll('history-synced-device-card');
+    assertTrue(!!cards[1]);
 
     // Pressing down goes to the next card.
     pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
diff --git a/chrome/test/data/webui/history/tsconfig_base.json b/chrome/test/data/webui/history/tsconfig_base.json
index c7bb73b..ca011a1 100644
--- a/chrome/test/data/webui/history/tsconfig_base.json
+++ b/chrome/test/data/webui/history/tsconfig_base.json
@@ -1,7 +1,6 @@
 {
   "extends": "../../../../../tools/typescript/tsconfig_base.json",
   "compilerOptions": {
-    "allowJs": true,
     "typeRoots": [
        "./../../../../../third_party/node/node_modules/@types"
     ],
diff --git a/chrome/test/data/webui/settings/chromeos/internet_known_networks_page_tests.js b/chrome/test/data/webui/settings/chromeos/internet_known_networks_page_tests.js
index 821f46c..3cc753e 100644
--- a/chrome/test/data/webui/settings/chromeos/internet_known_networks_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/internet_known_networks_page_tests.js
@@ -107,5 +107,54 @@
           deepLinkElement, getDeepActiveElement(),
           'Preferred list elem should be focused for settingId=7.');
     });
+
+    test('Known networks policy icon a11y label', async () => {
+      const mojom = chromeos.networkConfig.mojom;
+      internetKnownNetworksPage.networkType = mojom.NetworkType.kWiFi;
+      mojoApi_.setNetworkTypeEnabledState(mojom.NetworkType.kWiFi, true);
+      const preferredWifi =
+          OncMojo.getDefaultNetworkState(mojom.NetworkType.kWiFi, 'wifi2');
+      preferredWifi.priority = 1;
+      preferredWifi.source = mojom.OncSource.kDevicePolicy;
+      const notPreferredWifi =
+          OncMojo.getDefaultNetworkState(mojom.NetworkType.kWiFi, 'wifi1');
+      notPreferredWifi.source = mojom.OncSource.kDevicePolicy;
+      setNetworksForTest(mojom.NetworkType.kWiFi, [
+        notPreferredWifi,
+        preferredWifi,
+      ]);
+
+      const params = new URLSearchParams;
+      params.append('settingId', '7');
+      settings.Router.getInstance().navigateTo(
+          settings.routes.KNOWN_NETWORKS, params);
+
+      await flushAsync();
+
+      assertEquals(2, internetKnownNetworksPage.networkStateList_.length);
+      const preferredList =
+          internetKnownNetworksPage.$$('#preferredNetworkList');
+      assertTrue(!!preferredList);
+
+      const preferredPolicyIcon =
+          preferredList.querySelector('cr-policy-indicator');
+      assertTrue(!!preferredPolicyIcon);
+      assertEquals(
+          preferredPolicyIcon.iconAriaLabel,
+          internetKnownNetworksPage.i18n(
+              'networkA11yManagedByAdministrator', 'wifi2'));
+
+      const notPreferredList =
+          internetKnownNetworksPage.$$('#notPreferredNetworkList');
+      assertTrue(!!notPreferredList);
+
+      const notPreferredPolicyIcon =
+          notPreferredList.querySelector('cr-policy-indicator');
+      assertTrue(!!notPreferredPolicyIcon);
+      assertEquals(
+          notPreferredPolicyIcon.iconAriaLabel,
+          internetKnownNetworksPage.i18n(
+              'networkA11yManagedByAdministrator', 'wifi1'));
+    });
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js b/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js
index b4f1f7c..9296c1e 100644
--- a/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js
@@ -120,10 +120,6 @@
   setup(async () => {
     browserProxy = new TestPeripheralDataAccessBrowserProxy();
     settings.PeripheralDataAccessBrowserProxyImpl.instance_ = browserProxy;
-    loadTimeData.overrideValues({
-      pciguardUiEnabled: false,
-    });
-
     PolymerTest.clearBody();
     privacyPage = document.createElement('os-settings-privacy-page');
     document.body.appendChild(privacyPage);
@@ -425,10 +421,6 @@
     metricsConsentBrowserProxy = new TestMetricsConsentBrowserProxy();
     settings.MetricsConsentBrowserProxyImpl.instance_ =
         metricsConsentBrowserProxy;
-
-    loadTimeData.overrideValues({
-      pciguardUiEnabled: false,
-    });
   });
 
   async function setUpPage(prefName, isConfigurable) {
@@ -549,9 +541,6 @@
     browserProxy = new TestPeripheralDataAccessBrowserProxy();
     settings.PeripheralDataAccessBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
-    loadTimeData.overrideValues({
-      pciguardUiEnabled: true,
-    });
   });
 
   teardown(function() {
diff --git a/chrome/test/webapps/coverage/coverage_cros.tsv b/chrome/test/webapps/coverage/coverage_cros.tsv
index 1de0233..b5765ad7 100644
--- a/chrome/test/webapps/coverage/coverage_cros.tsv
+++ b/chrome/test/webapps/coverage/coverage_cros.tsv
@@ -1,556 +1,624 @@
-# This is a generated file.

-# Full coverage: 45%, with partial coverage: 65%

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑

-navigate_crashed_url🌑	check_create_shortcut_not_shown🌑

-navigate_crashed_url🌑	check_install_icon_not_shown🌑

-navigate_notfound_url🌕	check_create_shortcut_not_shown🌑

-navigate_notfound_url🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_tabbed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_tabbed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

+# This is a generated file.
+# Full coverage: 41%, with partial coverage: 58%
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑
+navigate_crashed_url🌑	check_create_shortcut_not_shown🌑
+navigate_crashed_url🌑	check_install_icon_not_shown🌑
+navigate_notfound_url🌕	check_create_shortcut_not_shown🌑
+navigate_notfound_url🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_tabbed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_tabbed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_app_in_list_tabbed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_app_in_list_windowed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_app_settings_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
diff --git a/chrome/test/webapps/coverage/coverage_linux.tsv b/chrome/test/webapps/coverage/coverage_linux.tsv
index f948227..2e940bf 100644
--- a/chrome/test/webapps/coverage/coverage_linux.tsv
+++ b/chrome/test/webapps/coverage/coverage_linux.tsv
@@ -1,641 +1,715 @@
-# This is a generated file.

-# Full coverage: 48%, with partial coverage: 67%

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑

-navigate_crashed_url🌑	check_create_shortcut_not_shown🌑

-navigate_crashed_url🌑	check_install_icon_not_shown🌑

-navigate_notfound_url🌕	check_create_shortcut_not_shown🌑

-navigate_notfound_url🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_menu_option_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

+# This is a generated file.
+# Full coverage: 45%, with partial coverage: 62%
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑
+navigate_crashed_url🌑	check_create_shortcut_not_shown🌑
+navigate_crashed_url🌑	check_install_icon_not_shown🌑
+navigate_notfound_url🌕	check_create_shortcut_not_shown🌑
+navigate_notfound_url🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑
+sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_menu_option_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
diff --git a/chrome/test/webapps/coverage/coverage_mac.tsv b/chrome/test/webapps/coverage/coverage_mac.tsv
index 07429f8..1382083 100644
--- a/chrome/test/webapps/coverage/coverage_mac.tsv
+++ b/chrome/test/webapps/coverage/coverage_mac.tsv
@@ -1,641 +1,715 @@
-# This is a generated file.

-# Full coverage: 41%, with partial coverage: 58%

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑

-navigate_crashed_url🌑	check_create_shortcut_not_shown🌑

-navigate_crashed_url🌑	check_install_icon_not_shown🌑

-navigate_notfound_url🌕	check_create_shortcut_not_shown🌑

-navigate_notfound_url🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_menu_option_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteC🌑

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

+# This is a generated file.
+# Full coverage: 38%, with partial coverage: 54%
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	check_app_in_list_windowed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	install_locally_SiteC🌑	check_app_in_list_windowed_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	install_locally_SiteC🌑	navigate_browser_SiteC🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	install_locally_SiteC🌑	navigate_browser_SiteC🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	install_locally_SiteC🌑	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_display_minimal_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	install_locally_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_chrome_apps_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌕	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑
+navigate_crashed_url🌑	check_create_shortcut_not_shown🌑
+navigate_crashed_url🌑	check_install_icon_not_shown🌑
+navigate_notfound_url🌕	check_create_shortcut_not_shown🌑
+navigate_notfound_url🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌑	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑
+sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_menu_option_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteC🌑
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_app_in_list_not_locally_installed_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_list_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	sync_turn_off🌑	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌑	sync_turn_on🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌑	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌑	uninstall_from_list_SiteA🌑	switch_profile_clients_Client1🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
diff --git a/chrome/test/webapps/coverage/coverage_win.tsv b/chrome/test/webapps/coverage/coverage_win.tsv
index 719b6d47f..47202dc 100644
--- a/chrome/test/webapps/coverage/coverage_win.tsv
+++ b/chrome/test/webapps/coverage/coverage_win.tsv
@@ -1,641 +1,715 @@
-# This is a generated file.

-# Full coverage: 49%, with partial coverage: 68%

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_app_in_list_windowed_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑

-install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕

-install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑

-install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑

-install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕

-install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕

-install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕

-install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑

-install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑

-navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteA🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕

-switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑

-navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓

-navigate_browser_SiteC🌕	check_create_shortcut_shown🌑

-navigate_browser_SiteC🌕	check_install_icon_not_shown🌕

-navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑

-navigate_crashed_url🌑	check_create_shortcut_not_shown🌑

-navigate_crashed_url🌑	check_install_icon_not_shown🌑

-navigate_notfound_url🌕	check_create_shortcut_not_shown🌑

-navigate_notfound_url🌕	check_install_icon_not_shown🌕

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_is_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	uninstall_policy_app_SiteA🌑	check_app_in_list_windowed_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓

-install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	uninstall_policy_app_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑

-navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑

-sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑

-sync_turn_off🌕	install_menu_option_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓

-sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

-install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓

+# This is a generated file.
+# Full coverage: 45%, with partial coverage: 62%
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	accept_app_update_dialog🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	clear_app_badge_SiteA🌑	check_app_badge_empty_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_pwa_site_a_to_SiteB🌑	close_custom_toolbar🌑	check_app_navigation_is_start_url🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	close_custom_toolbar🌕	check_app_navigation_is_start_url🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	create_shortcuts_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_list_empty🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_profile🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_profile🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	manifest_update_title_SiteA🌑	deny_app_update_dialog🌑	check_app_not_in_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_app_in_list_windowed_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	install_locally_SiteC🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_not_exists_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_policy_app_tabbed_no_shortcut_SiteC🌓	check_app_in_list_tabbed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_no_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteB🌓	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_menu_option_SiteB🌕	navigate_browser_SiteB🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteC🌕	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_no_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_policy_app_windowed_shortcut_SiteC🌓	check_app_in_list_windowed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_create_shortcut_not_shown🌑
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteC🌓	navigate_browser_SiteC🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	check_platform_shortcut_and_icon_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_color_correct🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_colors_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_color_correct🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_tab_not_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_not_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_browser_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_menu_option_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_launch_icon_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_chrome_apps_SiteA🌑	check_window_display_minimal🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_display_minimal_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_tabbed_no_shortcut_SiteA🌓	set_open_in_window_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_created🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_launch_icon_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_windowed_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_create_shortcut_windowed_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_omnibox_icon_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_omnibox_icon_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_menu_option_SiteA🌑	check_window_display_standalone🌑
+install_menu_option_SiteA🌕	launch_from_launch_icon_SiteA🌕	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_chrome_apps_SiteA🌓	check_window_display_standalone🌕
+install_menu_option_SiteA🌕	launch_from_platform_shortcut_SiteA🌑	check_window_display_standalone🌑
+install_create_shortcut_tabbed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_omnibox_icon_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_menu_option_SiteA🌕	delete_platform_shortcut_SiteA🌑	create_shortcuts_SiteA🌑	launch_from_platform_shortcut_SiteA🌑	check_window_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	install_locally_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_policy_app_windowed_shortcut_SiteA🌓	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_menu_option_SiteA🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_chrome_apps_SiteA🌓	check_tab_created🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	launch_from_platform_shortcut_SiteA🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_create_shortcut_tabbed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_create_shortcut_tabbed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_tab_created🌑
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_tab_created🌕
+install_policy_app_tabbed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_create_shortcut_windowed_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_omnibox_icon_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_omnibox_icon_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_no_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_policy_app_windowed_shortcut_SiteB🌓	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_menu_option_SiteB🌑	check_window_display_minimal🌑
+install_menu_option_SiteB🌕	launch_from_launch_icon_SiteB🌕	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_chrome_apps_SiteB🌓	check_window_display_minimal🌕
+install_menu_option_SiteB🌕	launch_from_platform_shortcut_SiteB🌑	check_window_display_minimal🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteC🌕	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_create_shortcut_windowed_SiteC🌕	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌓	check_window_created🌕
+install_policy_app_windowed_no_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_menu_option_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_launch_icon_SiteC🌕	check_window_created🌕
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_chrome_apps_SiteC🌑	check_window_created🌑
+install_policy_app_windowed_shortcut_SiteC🌓	launch_from_platform_shortcut_SiteC🌑	check_window_created🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_app_in_list_icon_correct_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	close_pwa🌑	manifest_update_icons_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	close_pwa🌑	launch_from_platform_shortcut_SiteAFoo🌑	close_pwa🌑	navigate_browser_SiteA🌑	check_launch_icon_shown🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_windowed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_menu_option_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_launch_icon_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_chrome_apps_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	manifest_update_title_SiteA🌑	check_update_dialog_not_shown🌑	close_pwa🌑	launch_from_platform_shortcut_SiteA🌑	check_window_title_site_a_is_SiteAUpdated🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteA🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteA🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteABar🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteAFoo🌓	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteAFoo🌕	navigate_browser_SiteABar🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_install_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_policy_app_windowed_shortcut_SiteA🌓	navigate_browser_SiteAFoo🌕	check_launch_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteAFoo🌑	check_launch_icon_shown🌑
+navigate_browser_SiteAFoo🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	navigate_browser_SiteB🌕	check_launch_icon_not_shown🌕
+switch_incognito_profile🌑	navigate_browser_SiteC🌑	check_create_shortcut_not_shown🌑
+navigate_browser_SiteC🌕	check_app_not_in_list_SiteA🌓
+navigate_browser_SiteC🌕	check_create_shortcut_shown🌑
+navigate_browser_SiteC🌕	check_install_icon_not_shown🌕
+navigate_browser_SiteC🌕	check_platform_shortcut_not_exists_SiteA🌑
+navigate_crashed_url🌑	check_create_shortcut_not_shown🌑
+navigate_crashed_url🌑	check_install_icon_not_shown🌑
+navigate_notfound_url🌕	check_create_shortcut_not_shown🌑
+navigate_notfound_url🌕	check_install_icon_not_shown🌕
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_omnibox_icon_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_menu_option_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_launch_icon_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_chrome_apps_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_menu_option_SiteAFoo🌕	close_pwa🌕	manifest_update_scope_site_a_foo_to_SiteA🌑	launch_from_platform_shortcut_SiteAFoo🌑	navigate_pwa_site_a_foo_to_SiteABar🌑	check_no_toolbar🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_custom_toolbar🌕
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	check_window_title_site_a_is_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_omnibox_icon_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_menu_option_SiteA🌕	navigate_pwa_site_a_to_SiteB🌕	open_in_chrome🌑	check_tab_created🌑
+install_create_shortcut_windowed_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_omnibox_icon_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+install_menu_option_SiteA🌕	set_app_badge_SiteA🌑	check_app_badge_has_value_SiteA🌑
+navigate_browser_SiteA🌕	set_app_badge_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	set_open_in_tab_SiteA🌓	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_install_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	set_open_in_window_SiteA🌓	navigate_browser_SiteA🌕	check_launch_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_menu_option_SiteA🌕	switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+switch_incognito_profile🌑	navigate_browser_SiteA🌑	check_install_icon_not_shown🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteC🌕	switch_profile_clients_Client2🌕	check_platform_shortcut_not_exists_SiteC🌑
+sync_turn_off🌕	install_create_shortcut_windowed_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_omnibox_icon_SiteA🌑	sync_turn_on🌑	switch_profile_clients_Client2🌑	check_app_in_list_not_locally_installed_SiteA🌑
+sync_turn_off🌕	install_menu_option_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteA🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteA🌓
+sync_turn_off🌕	install_create_shortcut_windowed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+sync_turn_off🌕	install_create_shortcut_tabbed_SiteC🌕	sync_turn_on🌕	switch_profile_clients_Client2🌕	check_app_in_list_not_locally_installed_SiteC🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_app_in_list_not_locally_installed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_list_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_menu_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	sync_turn_off🌕	uninstall_from_os_SiteA🌕	sync_turn_on🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_install_icon_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	navigate_browser_SiteA🌑	check_launch_icon_not_shown🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_list_SiteA🌑	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_omnibox_icon_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_menu_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_os_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_menu_option_SiteA🌕	uninstall_from_app_settings_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_menu_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_os_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteC🌕	uninstall_from_app_settings_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_omnibox_icon_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_menu_option_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	switch_profile_clients_Client2🌕	uninstall_from_list_SiteA🌕	switch_profile_clients_Client1🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_create_shortcut_tabbed_SiteA🌕	uninstall_from_list_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_app_not_in_list_SiteA🌓
+install_create_shortcut_tabbed_SiteC🌕	uninstall_from_list_SiteC🌕	check_platform_shortcut_not_exists_SiteC🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_tabbed_SiteA🌓
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_tabbed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_create_shortcut_windowed_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_omnibox_icon_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_menu_option_SiteA🌕	install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_app_not_in_list_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_install_icon_shown🌕
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	navigate_browser_SiteA🌕	check_launch_icon_not_shown🌕
+install_policy_app_windowed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_windowed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	uninstall_policy_app_SiteA🌕	check_platform_shortcut_not_exists_SiteA🌑	check_app_not_in_list_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	uninstall_policy_app_SiteA🌑	check_app_in_list_windowed_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_app_in_list_windowed_SiteA🌓
+install_policy_app_tabbed_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌑	uninstall_policy_app_SiteA🌑	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_create_shortcut_windowed_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_omnibox_icon_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
+install_policy_app_tabbed_no_shortcut_SiteA🌓	install_menu_option_SiteA🌕	uninstall_policy_app_SiteA🌕	check_platform_shortcut_and_icon_SiteA🌑
diff --git a/chrome/test/webapps/data/actions.csv b/chrome/test/webapps/data/actions.csv
index 5f0a1b6..a8f087d9 100644
--- a/chrome/test/webapps/data/actions.csv
+++ b/chrome/test/webapps/data/actions.csv
@@ -1,89 +1,98 @@
-# Action base name,Mode (* = default mode),Output Actions,Unique Identifier (next: 89),Deprecated,Deprecated,Deprecated,Deprecated,Status,Description,"Metadata, implementation bug, etc",Short Name - new & shortened,command 1,command 2
-launch_from_platform_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,1,,,,,Awaiting Platform Integration,Lauch an app from a platform shortcut on the user's desktop or start menu.,,1,git-grep-replace _1 _1 chrome/browser/sync/test/integration,git-grep-replace _1 _1 chrome/browser/ui/views/web_apps
-check_app_badge_empty,SiteA* | SiteB,,2,,,,,Awaiting Platform Integration,Check that the 'badge' on the app icon is empty,,2,git-grep-replace _2 _2 chrome/browser/sync/test/integration,git-grep-replace _2 _2 chrome/browser/ui/views/web_apps
-check_app_badge_has_value,SiteA* | SiteB,,3,,,,,Awaiting Platform Integration,Check that the 'badge' on the app icon has a value,,3,git-grep-replace _3 _3 chrome/browser/sync/test/integration,git-grep-replace _3 _3 chrome/browser/ui/views/web_apps
-clear_app_badge,SiteA* | SiteB,,4,,,,,Awaiting Platform Integration,The WebApp clears the 'badge' value from it's icon,,4,git-grep-replace _4 _4 chrome/browser/sync/test/integration,git-grep-replace _4 _4 chrome/browser/ui/views/web_apps
-drag_url_to_apps_list,,,5,,,,,Awaiting Platform Integration,"Open chrome://apps in a separage window, and drag a url (highlight & drag url from the omnibox) to the chrome://apps page",,5,git-grep-replace _5 _5 chrome/browser/sync/test/integration,git-grep-replace _5 _5 chrome/browser/ui/views/web_apps
-set_app_badge,SiteA* | SiteB,,6,,,,,Awaiting Platform Integration,Set the app badge for the given site to a value.,,6,git-grep-replace _6 _6 chrome/browser/sync/test/integration,git-grep-replace _6 _6 chrome/browser/ui/views/web_apps
-check_platform_shortcut_and_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,7,,,,,Awaiting Script Processing,The icon of the platform shortcut (on the desktop) is correct,"cliffordcheng@, doc",7,git-grep-replace _7 _7 chrome/browser/sync/test/integration,git-grep-replace _7 _7 chrome/browser/ui/views/web_apps
-manifest_update_scope_site_a_foo_to,SiteA* | SiteAFoo | SiteABar,,8,,,,,Awaiting Script Processing,"Update the scope of site a/foo/, to the given scope",,8,git-grep-replace _8 _8 chrome/browser/sync/test/integration,git-grep-replace _8 _8 chrome/browser/ui/views/web_apps
-navigate_pwa_site_a_foo_to,SiteA* | SiteAFoo | SiteABar | SiteB,,9,,,,,Awaiting Script Processing,Navigates the PWA window of the SiteAFoo pwa to a given site.,,9,git-grep-replace _9 _9 chrome/browser/sync/test/integration,git-grep-replace _9 _9 chrome/browser/ui/views/web_apps
-uninstall_from_list,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,10,,,,,Implemented,"Uninstall the webapp from wherever apps are listed by chrome. On WML, this is from chrome://apps, and on ChromeOS, this is from the 'launcher'",,10,git-grep-replace _10 _10 chrome/browser/sync/test/integration,git-grep-replace _10 _10 chrome/browser/ui/views/web_apps
-check_app_in_list_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,11,,,,,Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the app opens in a window by right clicking on it to see if the ""open in window"" option is checked, and by launching it to see if it opens in a separate window.",,11,git-grep-replace _11 _11 chrome/browser/sync/test/integration,git-grep-replace _11 _11 chrome/browser/ui/views/web_apps
-check_app_in_list_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,12,,,,,Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the app opens in a tab by right clicking on it to see if the ""open in window"" option is unchecked, and by launching it to see if it opens in a browser tab (and not a window).",,12,git-grep-replace _12 _12 chrome/browser/sync/test/integration,git-grep-replace _12 _12 chrome/browser/ui/views/web_apps
-check_app_list_empty,,,13,,,,,Implemented,"The app list is empty (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer).",,13,git-grep-replace _13 _13 chrome/browser/sync/test/integration,git-grep-replace _13 _13 chrome/browser/ui/views/web_apps
-check_app_navigation_is_start_url,,,14,,,,,Implemented,,,14,git-grep-replace _14 _14 chrome/browser/sync/test/integration,git-grep-replace _14 _14 chrome/browser/ui/views/web_apps
-check_app_not_in_list,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,15,,,,,Implemented,"Check that the given app is NOT in the app list. On desktop, this is chrome://apps, and on ChromeOS, this is the app drawer.",,15,git-grep-replace _15 _15 chrome/browser/sync/test/integration,git-grep-replace _15 _15 chrome/browser/ui/views/web_apps
-check_custom_toolbar,,,16,,,,,Implemented,Check that the PWA window has a custom toolbar to show the out-of-scope url.,,16,git-grep-replace _16 _16 chrome/browser/sync/test/integration,git-grep-replace _16 _16 chrome/browser/ui/views/web_apps
-check_install_icon_not_shown,,,17,,,,,Implemented,"Check that the ""Install"" icon in the omnibox is not shown",,17,git-grep-replace _17 _17 chrome/browser/sync/test/integration,git-grep-replace _17 _17 chrome/browser/ui/views/web_apps
-check_install_icon_shown,,,18,,,,,Implemented,"Check that the ""Install"" icon in the omnibox is shown",,18,git-grep-replace _18 _18 chrome/browser/sync/test/integration,git-grep-replace _18 _18 chrome/browser/ui/views/web_apps
-check_launch_icon_not_shown,,,19,,,,,Implemented,,,19,git-grep-replace _19 _19 chrome/browser/sync/test/integration,git-grep-replace _19 _19 chrome/browser/ui/views/web_apps
-check_launch_icon_shown,,,20,,,,,Implemented,,,20,git-grep-replace _20 _20 chrome/browser/sync/test/integration,git-grep-replace _20 _20 chrome/browser/ui/views/web_apps
-check_no_toolbar,,,21,,,,,Implemented,,,21,git-grep-replace _21 _21 chrome/browser/sync/test/integration,git-grep-replace _21 _21 chrome/browser/ui/views/web_apps
-check_tab_created,,,22,,,,,Implemented,A tab was created in a chrome browser window,,22,git-grep-replace _22 _22 chrome/browser/sync/test/integration,git-grep-replace _22 _22 chrome/browser/ui/views/web_apps
-check_window_closed,,,23,,,,,Implemented,The window was closed,,23,git-grep-replace _23 _23 chrome/browser/sync/test/integration,git-grep-replace _23 _23 chrome/browser/ui/views/web_apps
-check_window_created,,,24,,,,,Implemented,A window was created.,,24,git-grep-replace _24 _24 chrome/browser/sync/test/integration,git-grep-replace _24 _24 chrome/browser/ui/views/web_apps
-check_window_display_minimal,,,25,,,,,Implemented,"Check that the window is a PWA window, and has minimal browser controls.",,25,git-grep-replace _25 _25 chrome/browser/sync/test/integration,git-grep-replace _25 _25 chrome/browser/ui/views/web_apps
-check_window_display_standalone,,,26,,,,,Implemented,"Check that the window is a PWA window, and has no browser controls.",,26,git-grep-replace _26 _26 chrome/browser/sync/test/integration,git-grep-replace _26 _26 chrome/browser/ui/views/web_apps
-close_custom_toolbar,,,27,,,,,Implemented,Press the 'x' button on the custom toolbar that is towards the top of the WebApp window.,,27,git-grep-replace _27 _27 chrome/browser/sync/test/integration,git-grep-replace _27 _27 chrome/browser/ui/views/web_apps
-close_pwa,,,28,,,,,Implemented,Close the WebApp window.,,28,git-grep-replace _28 _28 chrome/browser/sync/test/integration,git-grep-replace _28 _28 chrome/browser/ui/views/web_apps
-install_create_shortcut_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,29,,,,,Implemented,"Install the given app using the""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut), and de-selecting the ""Open in a window"" checkbox.",,29,git-grep-replace _29 _29 chrome/browser/sync/test/integration,git-grep-replace _29 _29 chrome/browser/ui/views/web_apps
-install_create_shortcut_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,30,,,,,Implemented,"Install the given app using the""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut), and selecting the ""Open in a window"" checkbox.",,30,git-grep-replace _30 _30 chrome/browser/sync/test/integration,git-grep-replace _30 _30 chrome/browser/ui/views/web_apps
-install_omnibox_icon,SiteA* | SiteAFoo | SiteABar | SiteB,,31,,,,,Implemented,,,31,git-grep-replace _31 _31 chrome/browser/sync/test/integration,git-grep-replace _31 _31 chrome/browser/ui/views/web_apps
-install_policy_app_tabbed_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,32,,,,,Implemented,"Add a force-installed enterprise policy app to the user profile (must be managed profile). tabbed, no platform shortcut",,32,git-grep-replace _32 _32 chrome/browser/sync/test/integration,git-grep-replace _32 _32 chrome/browser/ui/views/web_apps
-install_policy_app_windowed_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,33,,,,,Implemented,"Add a force-installed enterprise policy app to the user profile (must be managed profile). windowed, no platform shortcut",,33,git-grep-replace _33 _33 chrome/browser/sync/test/integration,git-grep-replace _33 _33 chrome/browser/ui/views/web_apps
-launch_from_chrome_apps,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,34,,,,,Implemented,"Launch the web app by navigating to chrome://apps, and then clicking on the app icon.",,34,git-grep-replace _34 _34 chrome/browser/sync/test/integration,git-grep-replace _34 _34 chrome/browser/ui/views/web_apps
-launch_from_launch_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,35,,,,,Implemented,"Launch the web app by navigating the browser to the web app, and selecting the launch icon in the omnibox (intent picker),",,35,git-grep-replace _35 _35 chrome/browser/sync/test/integration,git-grep-replace _35 _35 chrome/browser/ui/views/web_apps
-manifest_update_display_minimal,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,36,,,,,Implemented,Updates the display property of the manifest to 'minimal' on the given site's manifest,,36,git-grep-replace _36 _36 chrome/browser/sync/test/integration,git-grep-replace _36 _36 chrome/browser/ui/views/web_apps
-navigate_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,37,,,,,Implemented,Navigate the browser to one of the static sites provided by the testing framework.,,37,git-grep-replace _37 _37 chrome/browser/sync/test/integration,git-grep-replace _37 _37 chrome/browser/ui/views/web_apps
-navigate_notfound_url,,,38,,,,,Implemented,Navigate to a url that returns a 404 server error.,,38,git-grep-replace _38 _38 chrome/browser/sync/test/integration,git-grep-replace _38 _38 chrome/browser/ui/views/web_apps
-navigate_pwa_site_a_to,SiteA* | SiteAFoo | SiteABar | SiteB,,39,,,,,Implemented,Navigates the PWA window of the SiteA pwa to a given site.,,39,git-grep-replace _39 _39 chrome/browser/sync/test/integration,git-grep-replace _39 _39 chrome/browser/ui/views/web_apps
-switch_profile_clients,Client2* | Client1,,40,,,,,Implemented,Switch to a different instance of chrome signed in to the same profile,,40,git-grep-replace _40 _40 chrome/browser/sync/test/integration,git-grep-replace _40 _40 chrome/browser/ui/views/web_apps
-sync_turn_off,,,41,,,,,Implemented,"Turn chrome sync off for ""Apps"": chrome://settings/syncSetup/advanced",,41,git-grep-replace _41 _41 chrome/browser/sync/test/integration,git-grep-replace _41 _41 chrome/browser/ui/views/web_apps
-sync_turn_on,,,42,,,,,Implemented,"Turn chrome sync on for ""Apps"": chrome://settings/syncSetup/advanced",,42,git-grep-replace _42 _42 chrome/browser/sync/test/integration,git-grep-replace _42 _42 chrome/browser/ui/views/web_apps
-uninstall_from_menu,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,43,,,,,Implemented,Uninstall the webapp from the 3-dot menu in the webapp window,,43,git-grep-replace _43 _43 chrome/browser/sync/test/integration,git-grep-replace _43 _43 chrome/browser/ui/views/web_apps
-uninstall_policy_app,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,44,,,,,Implemented,Remove a force-installed policy app to the user profile (must be managed profile),,44,git-grep-replace _44 _44 chrome/browser/sync/test/integration,git-grep-replace _44 _44 chrome/browser/ui/views/web_apps
-check_app_in_list_not_locally_installed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,45,,,,,Internal Impl,"Find the app in the app list (chrome://apps) and check that the given app is in the app list and is not installed. This means the icon is grey, and right clicking on it provides an 'install' option. Win/Mac/Linux only.",,45,git-grep-replace _45 _45 chrome/browser/sync/test/integration,git-grep-replace _45 _45 chrome/browser/ui/views/web_apps
-install_locally,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,46,,,,,Internal Impl,Find the app in the app list (chrome://apps) and install it by right-clicking on the app and selecting the 'install' option. Win/Mac/Linux only.,,46,git-grep-replace _46 _46 chrome/browser/sync/test/integration,git-grep-replace _46 _46 chrome/browser/ui/views/web_apps
-install_menu_option,SiteA* | SiteAFoo | SiteABar | SiteB,,47,,,,,Internal Impl,,,47,git-grep-replace _47 _47 chrome/browser/sync/test/integration,git-grep-replace _47 _47 chrome/browser/ui/views/web_apps
-install_policy_app_tabbed_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,48,,,,,Internal Impl,"Add a force-installed enterprise policy app to the user profile (must be managed profile). tabbed, with platform shortcut",,48,git-grep-replace _48 _48 chrome/browser/sync/test/integration,git-grep-replace _48 _48 chrome/browser/ui/views/web_apps
-install_policy_app_windowed_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,49,,,,,Internal Impl,"Add a force-installed enterprise policy app to the user profile (must be managed profile). windowed, with platform shortcut",,49,git-grep-replace _49 _49 chrome/browser/sync/test/integration,git-grep-replace _49 _49 chrome/browser/ui/views/web_apps
-set_open_in_tab,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,50,,,,,Internal Impl,"Uncheck the ""open in window"" checkbox in the right-click menu of the app icon, in the app list page",,50,git-grep-replace _50 _50 chrome/browser/sync/test/integration,git-grep-replace _50 _50 chrome/browser/ui/views/web_apps
-set_open_in_window,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,51,,,,,Internal Impl,"Check the ""open in window"" checkbox in the right-click menu of the app icon, in the app list page",,51,git-grep-replace _51 _51 chrome/browser/sync/test/integration,git-grep-replace _51 _51 chrome/browser/ui/views/web_apps
-install,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut & install_menu_option & install_create_shortcut_tabbed & install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,52,,,,,N/A (Parameterized Action),,,52,git-grep-replace _52 _52 chrome/browser/sync/test/integration,git-grep-replace _52 _52 chrome/browser/ui/views/web_apps
-install_by_user,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_menu_option & install_create_shortcut_tabbed,53,,,,,N/A (Parameterized Action),,,53,git-grep-replace _53 _53 chrome/browser/sync/test/integration,git-grep-replace _53 _53 chrome/browser/ui/views/web_apps
-install_by_user_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_tabbed,54,,,,,N/A (Parameterized Action),"Install the web app configured to open in a tab. This is done by the selecting the Tools->""Create Shortcut..."" menu option in the 3-dot menu, and deselecting the ""open in a window"" checkbox",,54,git-grep-replace _54 _54 chrome/browser/sync/test/integration,git-grep-replace _54 _54 chrome/browser/ui/views/web_apps
-install_by_user_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_menu_option,55,,,,,N/A (Parameterized Action),"Install the web app configured to open in a window. This is done in 3 different ways: 1) Clicking on the install icon in the omnibox, 2) Selecting the ""Install _"" menu option in the 3-dot menu, or 3) Selecting the Tools->""Create Shortcut..."" menu option in the 3-dot menu and checking the ""Open in a window"" checkbox",,55,git-grep-replace _55 _55 chrome/browser/sync/test/integration,git-grep-replace _55 _55 chrome/browser/ui/views/web_apps
-install_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_tabbed_no_shortcut,56,,,,,N/A (Parameterized Action),,,56,git-grep-replace _56 _56 chrome/browser/sync/test/integration,git-grep-replace _56 _56 chrome/browser/ui/views/web_apps
-install_policy_app,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_tabbed_no_shortcut & install_policy_app_windowed_shortcut & install_policy_app_tabbed_shortcut,57,,,,,N/A (Parameterized Action),,,57,git-grep-replace _57 _57 chrome/browser/sync/test/integration,git-grep-replace _57 _57 chrome/browser/ui/views/web_apps
-install_policy_app_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_tabbed_no_shortcut & install_policy_app_windowed_no_shortcut,58,,,,,N/A (Parameterized Action),,,58,git-grep-replace _58 _58 chrome/browser/sync/test/integration,git-grep-replace _58 _58 chrome/browser/ui/views/web_apps
-install_policy_app_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,59,,,,,N/A (Parameterized Action),,,59,git-grep-replace _59 _59 chrome/browser/sync/test/integration,git-grep-replace _59 _59 chrome/browser/ui/views/web_apps
-install_policy_app_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut,60,,,,,N/A (Parameterized Action),,,60,git-grep-replace _60 _60 chrome/browser/sync/test/integration,git-grep-replace _60 _60 chrome/browser/ui/views/web_apps
-install_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_tabbed & install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,61,,,,,N/A (Parameterized Action),All installation methods that result in a tabbed webapp.,,61,git-grep-replace _61 _61 chrome/browser/sync/test/integration,git-grep-replace _61 _61 chrome/browser/ui/views/web_apps
-install_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut & install_menu_option,62,,,,,N/A (Parameterized Action),All installation methods that result in a windowed webapp.,,62,git-grep-replace _62 _62 chrome/browser/sync/test/integration,git-grep-replace _62 _62 chrome/browser/ui/views/web_apps
-install_with_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_shortcut & install_policy_app_tabbed_shortcut & install_create_shortcut_windowed & install_omnibox_icon & install_menu_option & install_create_shortcut_tabbed,63,,,,,N/A (Parameterized Action),,,63,git-grep-replace _63 _63 chrome/browser/sync/test/integration,git-grep-replace _63 _63 chrome/browser/ui/views/web_apps
-launch,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_launch_icon & launch_from_chrome_apps & launch_from_platform_shortcut,64,,,,,N/A (Parameterized Action),,,64,git-grep-replace _64 _64 chrome/browser/sync/test/integration,git-grep-replace _64 _64 chrome/browser/ui/views/web_apps
-launch_from_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_launch_icon & launch_from_chrome_apps,65,,,,,N/A (Parameterized Action),,,65,git-grep-replace _65 _65 chrome/browser/sync/test/integration,git-grep-replace _65 _65 chrome/browser/ui/views/web_apps
-launch_no_launch_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_chrome_apps & launch_from_platform_shortcut,66,,,,,N/A (Parameterized Action),All ways to launch an app except by using the launch icon - which isn't available for 'browser' apps.,,66,git-grep-replace _66 _66 chrome/browser/sync/test/integration,git-grep-replace _66 _66 chrome/browser/ui/views/web_apps
-uninstall_by_user,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,uninstall_from_list & uninstall_from_menu & uninstall_from_os,67,,,,,N/A (Parameterized Action),,,67,git-grep-replace _67 _67 chrome/browser/sync/test/integration,git-grep-replace _67 _67 chrome/browser/ui/views/web_apps
-manifest_update_icons,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,68,,,,,Not Yet Implemented,Updates the icon field in the manifest of the website.,finnur@ is working on this,68,git-grep-replace _68 _68 chrome/browser/sync/test/integration,git-grep-replace _68 _68 chrome/browser/ui/views/web_apps
-launch_from_menu_option,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,69,,,,,Not Yet Implemented,"Launch the web app by navigating the browser to the web app, and selecting the ""Launch _"" menu option in the 3-dot menu.",P1,69,git-grep-replace _69 _69 chrome/browser/sync/test/integration,git-grep-replace _69 _69 chrome/browser/ui/views/web_apps
-manifest_update_display_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,70,,,,,Not Yet Implemented,Updates the display property of the manifest to 'browser' on the given site's manifest,P1,70,git-grep-replace _70 _70 chrome/browser/sync/test/integration,git-grep-replace _70 _70 chrome/browser/ui/views/web_apps
-open_in_chrome,,,71,,,,,Not Yet Implemented,Click on the 'open in chrome' link in the 3-dot menu of the app window,P1,71,git-grep-replace _71 _71 chrome/browser/sync/test/integration,git-grep-replace _71 _71 chrome/browser/ui/views/web_apps
-create_shortcuts,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,72,,,,,Not Yet Implemented,create shortcut in app list,P2,72,git-grep-replace _72 _72 chrome/browser/sync/test/integration,git-grep-replace _72 _72 chrome/browser/ui/views/web_apps
-switch_incognito_profile,,,73,,,,,Not Yet Implemented,Switch to using incognito mode,P2,73,git-grep-replace _73 _73 chrome/browser/sync/test/integration,git-grep-replace _73 _73 chrome/browser/ui/views/web_apps
-delete_platform_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,74,,,,,Not Yet Implemented,Delete the shortcut that lives on the operating system,P2,74,git-grep-replace _74 _74 chrome/browser/sync/test/integration,git-grep-replace _74 _74 chrome/browser/ui/views/web_apps
-check_app_in_list_icon_correct,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,75,,,,,Not Yet Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the icon for the given app in the app list is correct.",P3,75,git-grep-replace _75 _75 chrome/browser/sync/test/integration,git-grep-replace _75 _75 chrome/browser/ui/views/web_apps
-check_theme_color,SiteA* | SiteAFoo | SiteABar | SiteB,,76,,,,,Not Yet Implemented,Asserts that the theme color of the given app window is correct.,P3,76,git-grep-replace _76 _76 chrome/browser/sync/test/integration,git-grep-replace _76 _76 chrome/browser/ui/views/web_apps
-check_window_color_correct,,,77,,,,,Not Yet Implemented,The color of the window is correct.,P3,77,git-grep-replace _77 _77 chrome/browser/sync/test/integration,git-grep-replace _77 _77 chrome/browser/ui/views/web_apps
-check_window_icon_correct,,,78,,,,,Not Yet Implemented,,P3,78,git-grep-replace _78 _78 chrome/browser/sync/test/integration,git-grep-replace _78 _78 chrome/browser/ui/views/web_apps
-check_window_title_is,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,79,,,,,Not Yet Implemented,Check that the window title is correct,P3,79,git-grep-replace _79 _79 chrome/browser/sync/test/integration,git-grep-replace _79 _79 chrome/browser/ui/views/web_apps
-manifest_update_colors,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,80,,,,,Not Yet Implemented,The website updates it's manifest.json to change the 'theme' color,P3,80,git-grep-replace _80 _80 chrome/browser/sync/test/integration,git-grep-replace _80 _80 chrome/browser/ui/views/web_apps
-navigate_crashed_url,,,81,,,,,Not Yet Implemented,"Navigate to a page that crashes, or simulates a crashed renderer. chrome://crash",P3,81,git-grep-replace _81 _81 chrome/browser/sync/test/integration,git-grep-replace _81 _81 chrome/browser/ui/views/web_apps
-navigate_link_target_blank,,,82,,,,,Not Yet Implemented,"Click on a href link on the current page, where the target of the link is ""_blank""",P3,82,git-grep-replace _82 _82 chrome/browser/sync/test/integration,git-grep-replace _82 _82 chrome/browser/ui/views/web_apps
-delete_profile,,,83,,,,,Not Yet Implemented,Delete the user profile.,P4,83,git-grep-replace _83 _83 chrome/browser/sync/test/integration,git-grep-replace _83 _83 chrome/browser/ui/views/web_apps
-check_platform_shortcut_not_exists,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,84,,,,,WIP,The desktop platform shortcut has been removed.,"cliffordcheng@, doc",84,git-grep-replace _84 _84 chrome/browser/sync/test/integration,git-grep-replace _84 _84 chrome/browser/ui/views/web_apps
-check_create_shortcut_not_shown,,,85,,,,,WIP,"Check that the ""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut) is greyed out",,85,git-grep-replace _85 _85 chrome/browser/sync/test/integration,git-grep-replace _85 _85 chrome/browser/ui/views/web_apps
-check_create_shortcut_shown,,,86,,,,,WIP,"Check that the ""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut) is shown",,86,git-grep-replace _86 _86 chrome/browser/sync/test/integration,git-grep-replace _86 _86 chrome/browser/ui/views/web_apps
-uninstall_from_os,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,87,,,,,WIP,Uninstalls the app from OS integration - e.g. Windows Control Panel / Start menu,,87,git-grep-replace _87 _87 chrome/browser/sync/test/integration,git-grep-replace _87 _87 chrome/browser/ui/views/web_apps
-manifest_update_title,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,88,,,,,,,,88,git-grep-replace _88 _88 chrome/browser/sync/test/integration,git-grep-replace _88 _88 chrome/browser/ui/views/web_apps
\ No newline at end of file
+# Action base name,Mode (* = default mode),Output Actions,Unique Identifier (next: 99),Deprecated,Deprecated,Deprecated,Deprecated,Status,Description,"Metadata, implementation bug, etc"
+launch_from_platform_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,1,,,,,Awaiting Platform Integration,Lauch an app from a platform shortcut on the user's desktop or start menu.,
+check_app_badge_empty,SiteA* | SiteB,,2,,,,,Awaiting Platform Integration,Check that the 'badge' on the app icon is empty,
+check_app_badge_has_value,SiteA* | SiteB,,3,,,,,Awaiting Platform Integration,Check that the 'badge' on the app icon has a value,
+clear_app_badge,SiteA* | SiteB,,4,,,,,Awaiting Platform Integration,The WebApp clears the 'badge' value from it's icon,
+drag_url_to_apps_list,,,5,,,,,Awaiting Platform Integration,"Open chrome://apps in a separage window, and drag a url (highlight & drag url from the omnibox) to the chrome://apps page",
+set_app_badge,SiteA* | SiteB,,6,,,,,Awaiting Platform Integration,Set the app badge for the given site to a value.,
+check_platform_shortcut_and_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,7,,,,,Awaiting Script Processing,The icon of the platform shortcut (on the desktop) is correct,"cliffordcheng@, doc"
+manifest_update_scope_site_a_foo_to,SiteA* | SiteAFoo | SiteABar,,8,,,,,Awaiting Script Processing,"Update the scope of site a/foo/, to the given scope",
+navigate_pwa_site_a_foo_to,SiteA* | SiteAFoo | SiteABar | SiteB,,9,,,,,Awaiting Script Processing,Navigates the PWA window of the SiteAFoo pwa to a given site.,
+uninstall_from_list,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,10,,,,,Implemented,"Uninstall the webapp from wherever apps are listed by chrome. On WML, this is from chrome://apps, and on ChromeOS, this is from the 'launcher'",
+check_app_in_list_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,11,,,,,Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the app opens in a window by right clicking on it to see if the ""open in window"" option is checked, and by launching it to see if it opens in a separate window.",
+check_app_in_list_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,12,,,,,Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the app opens in a tab by right clicking on it to see if the ""open in window"" option is unchecked, and by launching it to see if it opens in a browser tab (and not a window).",
+check_app_list_empty,,,13,,,,,Implemented,"The app list is empty (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer).",
+check_app_navigation_is_start_url,,,14,,,,,Implemented,,
+check_app_not_in_list,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,15,,,,,Implemented,"Check that the given app is NOT in the app list. On desktop, this is chrome://apps, and on ChromeOS, this is the app drawer.",
+check_custom_toolbar,,,16,,,,,Implemented,Check that the PWA window has a custom toolbar to show the out-of-scope url.,
+check_install_icon_not_shown,,,17,,,,,Implemented,"Check that the ""Install"" icon in the omnibox is not shown",
+check_install_icon_shown,,,18,,,,,Implemented,"Check that the ""Install"" icon in the omnibox is shown",
+check_launch_icon_not_shown,,,19,,,,,Implemented,,
+check_launch_icon_shown,,,20,,,,,Implemented,,
+check_no_toolbar,,,21,,,,,Implemented,,
+check_tab_created,,,22,,,,,Implemented,A tab was created in a chrome browser window,
+check_window_closed,,,23,,,,,Implemented,The window was closed,
+check_window_created,,,24,,,,,Implemented,A window was created.,
+check_window_display_minimal,,,25,,,,,Implemented,"Check that the window is a PWA window, and has minimal browser controls.",
+check_window_display_standalone,,,26,,,,,Implemented,"Check that the window is a PWA window, and has no browser controls.",
+close_custom_toolbar,,,27,,,,,Implemented,Press the 'x' button on the custom toolbar that is towards the top of the WebApp window.,
+close_pwa,,,28,,,,,Implemented,Close the WebApp window.,
+install_create_shortcut_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,29,,,,,Implemented,"Install the given app using the""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut), and de-selecting the ""Open in a window"" checkbox.",
+install_create_shortcut_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,30,,,,,Implemented,"Install the given app using the""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut), and selecting the ""Open in a window"" checkbox.",
+install_omnibox_icon,SiteA* | SiteAFoo | SiteABar | SiteB,,31,,,,,Implemented,,
+install_policy_app_tabbed_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,32,,,,,Implemented,"Add a force-installed enterprise policy app to the user profile (must be managed profile). tabbed, no platform shortcut",
+install_policy_app_windowed_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,33,,,,,Implemented,"Add a force-installed enterprise policy app to the user profile (must be managed profile). windowed, no platform shortcut",
+launch_from_chrome_apps,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,34,,,,,Implemented,"Launch the web app by navigating to chrome://apps, and then clicking on the app icon.",
+launch_from_launch_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,35,,,,,Implemented,"Launch the web app by navigating the browser to the web app, and selecting the launch icon in the omnibox (intent picker),",
+manifest_update_display_minimal,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,36,,,,,Implemented,Updates the display property of the manifest to 'minimal' on the given site's manifest,
+navigate_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,37,,,,,Implemented,Navigate the browser to one of the static sites provided by the testing framework.,
+navigate_notfound_url,,,38,,,,,Implemented,Navigate to a url that returns a 404 server error.,
+navigate_pwa_site_a_to,SiteA* | SiteAFoo | SiteABar | SiteB,,39,,,,,Implemented,Navigates the PWA window of the SiteA pwa to a given site.,
+switch_profile_clients,Client2* | Client1,,40,,,,,Implemented,Switch to a different instance of chrome signed in to the same profile,
+sync_turn_off,,,41,,,,,Implemented,"Turn chrome sync off for ""Apps"": chrome://settings/syncSetup/advanced",
+sync_turn_on,,,42,,,,,Implemented,"Turn chrome sync on for ""Apps"": chrome://settings/syncSetup/advanced",
+uninstall_from_menu,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,43,,,,,Implemented,Uninstall the webapp from the 3-dot menu in the webapp window,
+uninstall_policy_app,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,44,,,,,Implemented,Remove a force-installed policy app to the user profile (must be managed profile),
+check_app_in_list_not_locally_installed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,45,,,,,Internal Impl,"Find the app in the app list (chrome://apps) and check that the given app is in the app list and is not installed. This means the icon is grey, and right clicking on it provides an 'install' option. Win/Mac/Linux only.",
+install_locally,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,46,,,,,Internal Impl,Find the app in the app list (chrome://apps) and install it by right-clicking on the app and selecting the 'install' option. Win/Mac/Linux only.,
+install_menu_option,SiteA* | SiteAFoo | SiteABar | SiteB,,47,,,,,Internal Impl,,
+install_policy_app_tabbed_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,48,,,,,Internal Impl,"Add a force-installed enterprise policy app to the user profile (must be managed profile). tabbed, with platform shortcut",
+install_policy_app_windowed_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,49,,,,,Internal Impl,"Add a force-installed enterprise policy app to the user profile (must be managed profile). windowed, with platform shortcut",
+set_open_in_tab,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,50,,,,,Internal Impl,"Uncheck the ""open in window"" checkbox in the right-click menu of the app icon, in the app list page",
+set_open_in_window,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,51,,,,,Internal Impl,"Check the ""open in window"" checkbox in the right-click menu of the app icon, in the app list page",
+install,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut & install_menu_option & install_create_shortcut_tabbed & install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,52,,,,,N/A (Parameterized Action),,
+install_by_user,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_menu_option & install_create_shortcut_tabbed,53,,,,,N/A (Parameterized Action),,
+install_by_user_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_tabbed,54,,,,,N/A (Parameterized Action),"Install the web app configured to open in a tab. This is done by the selecting the Tools->""Create Shortcut..."" menu option in the 3-dot menu, and deselecting the ""open in a window"" checkbox",
+install_by_user_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_menu_option,55,,,,,N/A (Parameterized Action),"Install the web app configured to open in a window. This is done in 3 different ways: 1) Clicking on the install icon in the omnibox, 2) Selecting the ""Install _"" menu option in the 3-dot menu, or 3) Selecting the Tools->""Create Shortcut..."" menu option in the 3-dot menu and checking the ""Open in a window"" checkbox",
+install_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_tabbed_no_shortcut,56,,,,,N/A (Parameterized Action),,
+install_policy_app,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_tabbed_no_shortcut & install_policy_app_windowed_shortcut & install_policy_app_tabbed_shortcut,57,,,,,N/A (Parameterized Action),,
+install_policy_app_no_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_tabbed_no_shortcut & install_policy_app_windowed_no_shortcut,58,,,,,N/A (Parameterized Action),,
+install_policy_app_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,59,,,,,N/A (Parameterized Action),,
+install_policy_app_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut,60,,,,,N/A (Parameterized Action),,
+install_tabbed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_tabbed & install_policy_app_tabbed_shortcut & install_policy_app_tabbed_no_shortcut,61,,,,,N/A (Parameterized Action),All installation methods that result in a tabbed webapp.,
+install_windowed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_create_shortcut_windowed & install_omnibox_icon & install_policy_app_windowed_no_shortcut & install_policy_app_windowed_shortcut & install_menu_option,62,,,,,N/A (Parameterized Action),All installation methods that result in a windowed webapp.,
+install_with_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,install_policy_app_windowed_shortcut & install_policy_app_tabbed_shortcut & install_create_shortcut_windowed & install_omnibox_icon & install_menu_option & install_create_shortcut_tabbed,63,,,,,N/A (Parameterized Action),,
+launch,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_launch_icon & launch_from_chrome_apps & launch_from_platform_shortcut,64,,,,,N/A (Parameterized Action),,
+launch_from_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_launch_icon & launch_from_chrome_apps,65,,,,,N/A (Parameterized Action),,
+launch_no_launch_icon,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,launch_from_menu_option & launch_from_chrome_apps & launch_from_platform_shortcut,66,,,,,N/A (Parameterized Action),All ways to launch an app except by using the launch icon - which isn't available for 'browser' apps.,
+uninstall_by_user,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,uninstall_from_list & uninstall_from_menu & uninstall_from_os & uninstall_from_app_settings,67,,,,,N/A (Parameterized Action),,
+manifest_update_icons,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,68,,,,,Not Yet Implemented,Updates the icon field in the manifest of the website.,finnur@ is working on this
+launch_from_menu_option,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,69,,,,,Not Yet Implemented,"Launch the web app by navigating the browser to the web app, and selecting the ""Launch _"" menu option in the 3-dot menu.",P1
+manifest_update_display_browser,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,70,,,,,Not Yet Implemented,Updates the display property of the manifest to 'browser' on the given site's manifest,P1
+check_tab_not_created,,,94,,,,,Not Yet Implemented,A tab was not created by the last state change action,P1
+open_in_chrome,,,71,,,,,Not Yet Implemented,Click on the 'open in chrome' link in the 3-dot menu of the app window,P1
+create_shortcuts,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,72,,,,,Not Yet Implemented,create shortcut in app list,P2
+switch_incognito_profile,,,73,,,,,Not Yet Implemented,Switch to using incognito mode,P2
+delete_platform_shortcut,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,74,,,,,Not Yet Implemented,Delete the shortcut that lives on the operating system,P2
+check_app_in_list_icon_correct,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,75,,,,,Not Yet Implemented,"Find the app in the app list (on desktop, this is chrome://apps, and on ChromeOS, this is the app drawer). Check that the icon for the given app in the app list is correct.",P3
+check_theme_color,SiteA* | SiteAFoo | SiteABar | SiteB,,76,,,,,Not Yet Implemented,Asserts that the theme color of the given app window is correct.,P3
+check_window_color_correct,,,77,,,,,Not Yet Implemented,The color of the window is correct.,P3
+check_window_icon_correct,,,78,,,,,Not Yet Implemented,,P3
+manifest_update_colors,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,80,,,,,Not Yet Implemented,The website updates it's manifest.json to change the 'theme' color,P3
+navigate_crashed_url,,,81,,,,,Not Yet Implemented,"Navigate to a page that crashes, or simulates a crashed renderer. chrome://crash",P3
+navigate_link_target_blank,,,82,,,,,Not Yet Implemented,"Click on a href link on the current page, where the target of the link is ""_blank""",P3
+delete_profile,,,83,,,,,Not Yet Implemented,Delete the user profile.,P4
+check_platform_shortcut_not_exists,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,84,,,,,WIP,The desktop platform shortcut has been removed.,"cliffordcheng@, doc"
+check_create_shortcut_not_shown,,,85,,,,,WIP,"Check that the ""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut) is greyed out",
+check_create_shortcut_shown,,,86,,,,,WIP,"Check that the ""Create Shortcut"" menu option (3-dot->""More Tools""->""Create Shortcut) is shown",
+uninstall_from_os,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,87,,,,,WIP,Uninstalls the app from OS integration - e.g. Windows Control Panel / Start menu,
+check_window_title_site_a_is,SiteA | SiteAUpdated,,79,,,,,WIP,Check that the window title is correct,finnur@
+manifest_update_title,SiteA,,88,,,,,WIP,The website updates it's manifest.json to change the 'title',finnur@
+accept_app_update_dialog,,,91,,,,,WIP,Click Accept in the App Identity Update dialog,finnur@
+check_update_dialog_not_shown,,,92,,,,,WIP,,finnur@
+deny_app_update_dialog,,,93,,,,,WIP,,finnue@
+launch_app_settings,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,95,,,,,WIP,Launch chrome://app-settings/<app-id> page,phillis@
+launch_app_settings_from_chrome_apps,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,96,,,,,WIP,,phillis@
+launch_app_settings_from_app_window,,,97,,,,,WIP,,phillis@
+uninstall_from_app_settings,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,,98,,,,,WIP,,phillis@
+uninstall_not_locally_installed,SiteA* | SiteAFoo | SiteABar | SiteB | SiteC,uninstall_from_list & uninstall_from_menu & uninstall_from_os,99,,,,,N/A (Parameterized Action),"Uninstall an app by user, the app can be not locally installed.",
\ No newline at end of file
diff --git a/chrome/test/webapps/data/coverage_required.csv b/chrome/test/webapps/data/coverage_required.csv
index f21b9774..cab79637 100644
--- a/chrome/test/webapps/data/coverage_required.csv
+++ b/chrome/test/webapps/data/coverage_required.csv
@@ -1,10 +1,12 @@
 # Platforms,Affected-by State Setup (for easy readability / categorization) - not parsed!,Affected-by Edge Action/s 1 - not parsed!,Affected-by Edge Action 2 - not parsed!,Test (actually run by framework),,,,,,
+WMLC,install_by_user,accept_app_update_dialog,check_window_title_site_a_is(SiteAUpdated),install_by_user(SiteA),manifest_update_title(SiteA),accept_app_update_dialog,close_pwa,launch(SiteA),check_window_title_site_a_is(SiteAUpdated),
 WMLC,set_app_badge,clear_app_badge,check_app_badge_empty,install_by_user_windowed,set_app_badge,clear_app_badge,check_app_badge_empty,,,
 WMLC,install_windowed & navigate_pwa_site_a_to(SiteB),close_custom_toolbar,check_app_navigation_is_start_url,install_windowed,navigate_pwa_site_a_to(SiteB),close_custom_toolbar,check_app_navigation_is_start_url,,,
 WMLC,install_no_shortcut,create_shortcuts,check_platform_shortcut_and_icon,install_no_shortcut,create_shortcuts,check_platform_shortcut_and_icon,,,,
 WMLC,install,delete_profile,check_app_list_empty,install,delete_profile,check_app_list_empty,,,,
 WMLC,install,delete_profile,check_app_not_in_list,install,delete_profile,check_app_not_in_list,,,,
 WMLC,install_with_shortcut,delete_profile,check_platform_shortcut_not_exists,install_with_shortcut,delete_profile,check_platform_shortcut_not_exists,,,,
+WMLC,install_by_user,deny_app_update_dialog,check_app_not_in_list,install_by_user(SiteA),manifest_update_title(SiteA),deny_app_update_dialog,check_app_not_in_list,check_platform_shortcut_not_exists,,
 WMLC,install_policy_app_tabbed,install_by_user_windowed,check_app_in_list_windowed,install_policy_app_tabbed,install_by_user_windowed,check_app_in_list_windowed,,,,
 WMLC,install_policy_app_tabbed,install_by_user_windowed,check_platform_shortcut_and_icon,install_policy_app_tabbed,install_by_user_windowed,check_platform_shortcut_and_icon,,,,
 WMLC,install_policy_app_tabbed,install_by_user_windowed,check_window_created,install_policy_app_tabbed,install_by_user_windowed,check_window_created,,,,
@@ -16,12 +18,12 @@
 WML,install_by_user_windowed & switch_profile_clients,install_locally,check_app_in_list_windowed,install_by_user_windowed,switch_profile_clients,install_locally,check_app_in_list_windowed,,,
 WML,install_by_user_windowed & switch_profile_clients,install_locally,check_install_icon_not_shown,install_by_user_windowed,switch_profile_clients,install_locally,navigate_browser(SiteA),check_install_icon_not_shown,,
 WML,install_by_user_windowed & switch_profile_clients,install_locally,check_launch_icon_shown,install_by_user_windowed,switch_profile_clients,install_locally,navigate_browser(SiteA),check_launch_icon_shown,,
-WML,install_by_user(SiteC) & switch_profile_clients,install_locally(SiteC),check_platform_shortcut_and_icon(SiteC),install_by_user(SiteC),switch_profile_clients,install_locally(SiteC),check_platform_shortcut_and_icon(SiteC),,,
 WML,install_by_user_tabbed(SiteC) & switch_profile_clients,install_locally(SiteC),check_app_in_list_tabbed(SiteC),install_by_user_tabbed(SiteC),switch_profile_clients,install_locally(SiteC),check_app_in_list_tabbed(SiteC),,,
 WML,install_by_user_tabbed(SiteC) & switch_profile_clients,install_locally(SiteC),check_launch_icon_not_shown,install_by_user_tabbed(SiteC),switch_profile_clients,install_locally(SiteC),navigate_browser(SiteC),check_launch_icon_not_shown,,
 WML,install_by_user_windowed(SiteC) & switch_profile_clients,install_locally(SiteC),check_app_in_list_windowed(SiteC),install_by_user_windowed(SiteC),switch_profile_clients,install_locally(SiteC),check_app_in_list_windowed(SiteC),,,
 WML,install_by_user_windowed(SiteC) & switch_profile_clients,install_locally(SiteC),check_install_icon_not_shown,install_by_user_windowed(SiteC),switch_profile_clients,install_locally(SiteC),navigate_browser(SiteC),check_install_icon_not_shown,,
 WML,install_by_user_windowed(SiteC) & switch_profile_clients,install_locally(SiteC),check_launch_icon_shown,install_by_user_windowed(SiteC),switch_profile_clients,install_locally(SiteC),navigate_browser(SiteC),check_launch_icon_shown,,
+WML,install_by_user(SiteC) & switch_profile_clients,install_locally(SiteC),check_platform_shortcut_and_icon(SiteC),install_by_user(SiteC),switch_profile_clients,install_locally(SiteC),check_platform_shortcut_and_icon(SiteC),,,
 WMLC,,install_no_shortcut,check_platform_shortcut_not_exists,install_no_shortcut,check_platform_shortcut_not_exists,,,,,
 WMLC,,install_no_shortcut(SiteC),check_platform_shortcut_not_exists(SiteC),install_no_shortcut(SiteC),check_platform_shortcut_not_exists(SiteC),,,,,
 WMLC,install_by_user_tabbed,install_policy_app_no_shortcut,check_platform_shortcut_and_icon,install_by_user_tabbed,install_policy_app_windowed,check_platform_shortcut_and_icon,,,,
@@ -49,28 +51,35 @@
 WMLC,,install_windowed(SiteC),check_launch_icon_shown,install_windowed(SiteC),navigate_browser(SiteC),check_launch_icon_shown,,,,
 WMLC,,install_with_shortcut,check_platform_shortcut_and_icon,install_policy_app_windowed_shortcut,check_platform_shortcut_and_icon,,,,,
 WMLC,,install_with_shortcut(SiteC),check_platform_shortcut_and_icon(SiteC),install_policy_app_windowed_shortcut,check_platform_shortcut_and_icon(SiteC),,,,,
-WMLC,install_by_user_tabbed & install_policy_app_windowed,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,install_policy_app_windowed,launch_no_launch_icon,check_tab_created,,,
-WMLC,install_by_user_tabbed & switch_profile_clients,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,switch_profile_clients,launch_no_launch_icon,check_tab_created,,,
-WML,install_by_user_tabbed & switch_profile_clients & install_locally,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,switch_profile_clients,install_locally,launch_no_launch_icon,check_tab_created,,
 WMLC,install_by_user_windowed & install_policy_app_tabbed,launch,check_window_created,install_by_user_windowed,install_policy_app_tabbed,launch,check_window_created,,,
 WMLC,install_by_user_windowed & manifest_update_colors,launch,check_window_color_correct,install_by_user_windowed,close_pwa,manifest_update_colors,launch,check_window_color_correct,,
-WMLC,install_by_user_windowed & manifest_update_display_browser,launch,check_window_display_standalone,install_by_user_windowed,close_pwa,manifest_update_display_browser,launch,check_window_display_standalone,,
+WMLC,install_by_user_windowed & manifest_update_display_browser,launch,check_tab_not_created,install_by_user_windowed,close_pwa,manifest_update_display_browser,launch,check_tab_not_created,,
+WMLC,install_by_user_windowed & manifest_update_display_browser,launch,check_window_created,install_by_user_windowed,close_pwa,manifest_update_display_browser,launch,check_window_created,,
+WMLC,install_by_user_windowed & manifest_update_display_browser,launch,check_window_display_minimal,install_by_user_windowed,close_pwa,manifest_update_display_browser,launch,check_window_display_minimal,,
 WMLC,install_by_user_windowed & manifest_update_display_minimal,launch,check_window_display_minimal,install_by_user_windowed,close_pwa,manifest_update_display_minimal,launch,check_window_display_minimal,,
-WML,install_by_user_windowed & switch_profile_clients,launch_no_launch_icon,check_tab_created,install_by_user_windowed,switch_profile_clients,launch_no_launch_icon,check_tab_created,,,
 WML,install_by_user_windowed & switch_profile_clients & install_locally,launch,check_window_created,install_by_user_windowed,switch_profile_clients,install_locally,launch,check_window_created,,
-WMLC,install_tabbed & delete_platform_shortcut & create_shortcuts,launch_from_platform_shortcut,check_tab_created,install_tabbed,delete_platform_shortcut,create_shortcuts,launch_from_platform_shortcut,check_tab_created,,
 WMLC,install_tabbed & set_open_in_window,launch,check_window_created,install_tabbed,set_open_in_window,launch,check_window_created,,,
 WMLC,install_windowed,launch,check_window_created,install_windowed,launch,check_window_created,,,,
 WMLC,install_windowed,launch,check_window_display_standalone,install_windowed,launch,check_window_display_standalone,,,,
+WMLC,install_tabbed & delete_platform_shortcut & create_shortcuts,launch_from_platform_shortcut,check_tab_created,install_tabbed,delete_platform_shortcut,create_shortcuts,launch_from_platform_shortcut,check_tab_created,,
 WMLC,install_windowed & delete_platform_shortcut & create_shortcuts,launch_from_platform_shortcut,check_window_created,install_windowed,delete_platform_shortcut,create_shortcuts,launch_from_platform_shortcut,check_window_created,,
+WMLC,install_by_user_tabbed & install_policy_app_windowed,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,install_policy_app_windowed,launch_no_launch_icon,check_tab_created,,,
+WMLC,install_by_user_tabbed & switch_profile_clients,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,switch_profile_clients,launch_no_launch_icon,check_tab_created,,,
+WML,install_by_user_tabbed & switch_profile_clients & install_locally,launch_no_launch_icon,check_tab_created,install_by_user_tabbed,switch_profile_clients,install_locally,launch_no_launch_icon,check_tab_created,,
+WML,install_by_user_windowed & switch_profile_clients,launch_no_launch_icon,check_tab_created,install_by_user_windowed,switch_profile_clients,launch_no_launch_icon,check_tab_created,,,
 WMLC,install_windowed & set_open_in_tab,launch_no_launch_icon,check_tab_created,install_windowed,set_open_in_tab,launch_no_launch_icon,check_tab_created,,,
-WMLC,install_windowed(SiteB),launch(SiteB),check_window_display_minimal,install_windowed(SiteB),launch(SiteB),check_window_display_minimal,,,,
 WMLC,install_tabbed(SiteC),launch_no_launch_icon(SiteC),check_tab_created,install_tabbed(SiteC),launch_no_launch_icon(SiteC),check_tab_created,,,,
+WMLC,install_windowed(SiteB),launch(SiteB),check_window_display_minimal,install_windowed(SiteB),launch(SiteB),check_window_display_minimal,,,,
 WMLC,install_windowed(SiteC),launch(SiteC),check_window_created,install_windowed(SiteC),launch(SiteC),check_window_created,,,,
 WMLC,install_by_user_windowed,manifest_update_icons,check_app_in_list_icon_correct,install_by_user_windowed,close_pwa,manifest_update_icons,check_app_in_list_icon_correct,,,
 WMLC,install_by_user_windowed,manifest_update_icons,check_platform_shortcut_and_icon,install_by_user_windowed,close_pwa,manifest_update_icons,check_platform_shortcut_and_icon,,,
 WMLC,install_by_user_windowed(SiteAFoo),manifest_update_scope_site_a_foo_to(SiteA),check_install_icon_not_shown,install_by_user_windowed(SiteAFoo),manifest_update_scope_site_a_foo_to(SiteA),close_pwa,launch_from_platform_shortcut(SiteAFoo),close_pwa,navigate_browser(SiteA),check_install_icon_not_shown
 WMLC,install_by_user_windowed(SiteAFoo),manifest_update_scope_site_a_foo_to(SiteA),check_launch_icon_shown,install_by_user_windowed(SiteAFoo),manifest_update_scope_site_a_foo_to(SiteA),close_pwa,launch_from_platform_shortcut(SiteAFoo),close_pwa,navigate_browser(SiteA),check_launch_icon_shown
+WMLC,install_policy_app,manifest_update_title(SiteA),check_window_title_site_a_is(SiteAUpdated),install_policy_app(SiteA),manifest_update_title(SiteA),check_update_dialog_not_shown,close_pwa,launch(SiteA),check_window_title_site_a_is(SiteAUpdated),
+WMLC,switch_incognito_profile,navigate_browser(SiteA),check_create_shortcut_not_shown,switch_incognito_profile,navigate_browser(SiteA),check_create_shortcut_not_shown,,,,
+WMLC,,navigate_browser(SiteA),check_app_not_in_list,navigate_browser(SiteA),check_app_not_in_list,,,,,
+WMLC,,navigate_browser(SiteA),check_create_shortcut_shown,navigate_browser(SiteA),check_create_shortcut_shown,,,,,
+WMLC,,navigate_browser(SiteA),check_platform_shortcut_not_exists,navigate_browser(SiteA),check_platform_shortcut_not_exists,,,,,
 WMLC,install_by_user_windowed(SiteAFoo) & manifest_update_scope_site_a_foo_to(SiteA),navigate_browser(SiteABar),check_install_icon_not_shown,install_by_user_windowed(SiteAFoo),close_pwa,manifest_update_scope_site_a_foo_to(SiteA),navigate_browser(SiteABar),check_install_icon_not_shown,,
 WMLC,install_by_user_windowed(SiteAFoo) & manifest_update_scope_site_a_foo_to(SiteA),navigate_browser(SiteABar),check_launch_icon_shown,install_by_user_windowed(SiteAFoo),close_pwa,manifest_update_scope_site_a_foo_to(SiteA),navigate_browser(SiteABar),check_launch_icon_shown,,
 WMLC,install_windowed(SiteAFoo),navigate_browser(SiteABar),check_install_icon_shown,install_windowed(SiteAFoo),navigate_browser(SiteABar),check_install_icon_shown,,,,
@@ -80,10 +89,6 @@
 WMLC,install_windowed,navigate_browser(SiteAFoo),check_install_icon_not_shown,install_windowed,navigate_browser(SiteAFoo),check_install_icon_not_shown,,,,
 WMLC,install_windowed,navigate_browser(SiteAFoo),check_launch_icon_shown,install_windowed,navigate_browser(SiteAFoo),check_launch_icon_shown,,,,
 WMLC,,navigate_browser(SiteAFoo),check_install_icon_shown,navigate_browser(SiteAFoo),check_install_icon_shown,,,,,
-WMLC,switch_incognito_profile,navigate_browser(SiteA),check_create_shortcut_not_shown,switch_incognito_profile,navigate_browser(SiteA),check_create_shortcut_not_shown,,,,
-WMLC,,navigate_browser(SiteA),check_app_not_in_list,navigate_browser(SiteA),check_app_not_in_list,,,,,
-WMLC,,navigate_browser(SiteA),check_create_shortcut_shown,navigate_browser(SiteA),check_create_shortcut_shown,,,,,
-WMLC,,navigate_browser(SiteA),check_platform_shortcut_not_exists,navigate_browser(SiteA),check_platform_shortcut_not_exists,,,,,
 WMLC,install_by_user_windowed,navigate_browser(SiteB),check_install_icon_shown,install_by_user_windowed,navigate_browser(SiteB),check_install_icon_shown,,,,
 WMLC,install_by_user_windowed,navigate_browser(SiteB),check_launch_icon_not_shown,install_by_user_windowed,navigate_browser(SiteB),check_launch_icon_not_shown,,,,
 WMLC,switch_incognito_profile,navigate_browser(SiteC),check_create_shortcut_not_shown,switch_incognito_profile,navigate_browser(SiteC),check_create_shortcut_not_shown,,,,
@@ -97,19 +102,9 @@
 WMLC,,navigate_notfound_url,check_install_icon_not_shown,navigate_notfound_url,check_install_icon_not_shown,,,,,
 WMLC,install_by_user_windowed(SiteAFoo) & manifest_update_scope_site_a_foo_to(SiteA),navigate_pwa_site_a_foo_to(SiteABar),check_no_toolbar,install_by_user_windowed(SiteAFoo),close_pwa,manifest_update_scope_site_a_foo_to(SiteA),launch(SiteAFoo),navigate_pwa_site_a_foo_to(SiteABar),check_no_toolbar,
 WMLC,install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_custom_toolbar,install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_custom_toolbar,,,,
-WMLC,install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_window_title_is(SiteA),install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_window_title_is(SiteA),,,,
+WMLC,install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_window_title_site_a_is(SiteA),install_by_user_windowed,navigate_pwa_site_a_to(SiteB),check_window_title_site_a_is(SiteA),,,,
 WMLC,install_by_user_windowed,open_in_chrome,check_tab_created,install_by_user_windowed,open_in_chrome,check_tab_created,,,,
 WMLC,install_by_user_windowed & navigate_pwa_site_a_to(SiteB),open_in_chrome,check_tab_created,install_by_user_windowed,navigate_pwa_site_a_to(SiteB),open_in_chrome,check_tab_created,,,
-WMLC,install_by_user_tabbed & install_policy_app,uninstall_policy_app,check_app_in_list_tabbed,install_by_user_tabbed,install_policy_app,uninstall_policy_app,check_app_in_list_tabbed,,,
-WMLC,install_by_user_tabbed & install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,install_by_user_tabbed,install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,,,
-WMLC,install_by_user_windowed & install_policy_app,uninstall_policy_app,check_app_in_list_windowed,install_by_user_windowed,install_policy_app,uninstall_policy_app,check_app_in_list_windowed,,,
-WMLC,install_by_user_windowed & install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,install_by_user_windowed,install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,,,
-WMLC,install_policy_app,uninstall_policy_app,check_app_not_in_list,install_policy_app,uninstall_policy_app,check_app_not_in_list,,,,
-WMLC,install_policy_app,uninstall_policy_app,check_install_icon_shown,install_policy_app_tabbed_shortcut,uninstall_policy_app,navigate_browser(SiteA),check_install_icon_shown,,,
-WMLC,install_policy_app,uninstall_policy_app,check_launch_icon_not_shown,install_policy_app_tabbed_shortcut,uninstall_policy_app,navigate_browser(SiteA),check_launch_icon_not_shown,,,
-WMLC,install_policy_app,uninstall_policy_app,check_platform_shortcut_not_exists,install_policy_app,uninstall_policy_app,check_platform_shortcut_not_exists,check_app_not_in_list,,,
-WMLC,install_policy_app_tabbed & install_by_user_windowed,uninstall_policy_app,check_app_in_list_windowed,install_policy_app_tabbed,install_by_user_windowed,uninstall_policy_app,check_app_in_list_windowed,,,
-WMLC,install_policy_app_tabbed & install_by_user_windowed,uninstall_policy_app,check_platform_shortcut_and_icon,install_policy_app_tabbed,install_by_user_windowed,uninstall_policy_app,check_platform_shortcut_and_icon,,,
 WMLC,install_by_user_windowed,set_app_badge,check_app_badge_has_value,install_by_user_windowed,set_app_badge,check_app_badge_has_value,,,,
 WMLC,,set_app_badge,check_platform_shortcut_not_exists,navigate_browser(SiteA),set_app_badge,check_platform_shortcut_not_exists,,,,
 WMLC,install_by_user_windowed,set_open_in_tab,check_app_in_list_tabbed,install_by_user_windowed,set_open_in_tab,check_app_in_list_tabbed,,,,
@@ -119,42 +114,52 @@
 WMLC,install_by_user_tabbed,set_open_in_window,check_launch_icon_shown,install_by_user_tabbed,set_open_in_window,navigate_browser(SiteA),check_launch_icon_shown,,,
 WMLC,install_by_user_windowed,switch_incognito_profile,check_launch_icon_not_shown,install_by_user_windowed,switch_incognito_profile,navigate_browser(SiteA),check_launch_icon_not_shown,,,
 WMLC,,switch_incognito_profile,check_install_icon_not_shown,switch_incognito_profile,navigate_browser(SiteA),check_install_icon_not_shown,,,,
-C,install_by_user_windowed,switch_profile_clients,check_app_in_list_windowed,install_by_user_windowed,switch_profile_clients,check_app_in_list_windowed,,,,
-C,install_by_user_tabbed,switch_profile_clients,check_app_in_list_tabbed,install_by_user_tabbed,switch_profile_clients,check_app_in_list_tabbed,,,,
-C,install_by_user,switch_profile_clients,check_platform_shortcut_and_icon(SiteA),install_by_user,switch_profile_clients,check_platform_shortcut_and_icon(SiteA),,,,
-C,install_by_user_windowed,switch_profile_clients,check_install_icon_not_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_install_icon_not_shown,,,
-C,install_by_user_windowed,switch_profile_clients,check_launch_icon_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_launch_icon_shown,,,
 WML,install_by_user,switch_profile_clients,check_app_in_list_not_locally_installed,install_by_user,switch_profile_clients,check_app_in_list_not_locally_installed,,,,
+C,install_by_user,switch_profile_clients,check_platform_shortcut_and_icon(SiteA),install_by_user,switch_profile_clients,check_platform_shortcut_and_icon(SiteA),,,,
 WML,install_by_user,switch_profile_clients,check_platform_shortcut_not_exists(SiteA),install_by_user,switch_profile_clients,check_platform_shortcut_not_exists,,,,
+C,install_by_user_tabbed,switch_profile_clients,check_app_in_list_tabbed,install_by_user_tabbed,switch_profile_clients,check_app_in_list_tabbed,,,,
+C,install_by_user_windowed,switch_profile_clients,check_app_in_list_windowed,install_by_user_windowed,switch_profile_clients,check_app_in_list_windowed,,,,
+C,install_by_user_windowed,switch_profile_clients,check_install_icon_not_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_install_icon_not_shown,,,
 WML,install_by_user_windowed,switch_profile_clients,check_install_icon_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_install_icon_shown,,,
 WML,install_by_user_windowed,switch_profile_clients,check_launch_icon_not_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_launch_icon_not_shown,,,
+C,install_by_user_windowed,switch_profile_clients,check_launch_icon_shown,install_by_user_windowed,switch_profile_clients,navigate_browser(SiteA),check_launch_icon_shown,,,
 WML,install_by_user(SiteC),switch_profile_clients,check_app_in_list_not_locally_installed(SiteC),install_by_user(SiteC),switch_profile_clients,check_app_in_list_not_locally_installed(SiteC),,,,
 WML,install_by_user(SiteC),switch_profile_clients,check_platform_shortcut_not_exists(SiteC),install_by_user(SiteC),switch_profile_clients,check_platform_shortcut_not_exists(SiteC),,,,
 WML,sync_turn_off & install_by_user & sync_turn_on,switch_profile_clients,check_app_in_list_not_locally_installed,sync_turn_off,install_by_user,sync_turn_on,switch_profile_clients,check_app_in_list_not_locally_installed,,
 WML,sync_turn_off & install_by_user(SiteC) & sync_turn_on,switch_profile_clients,check_app_in_list_not_locally_installed(SiteC),sync_turn_off,install_by_user(SiteC),sync_turn_on,switch_profile_clients,check_app_in_list_not_locally_installed(SiteC),,
-WML,install_by_user & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_app_in_list_not_locally_installed,install_by_user,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_app_in_list_not_locally_installed,
-WML,install_by_user & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_platform_shortcut_not_exists,install_by_user,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_platform_shortcut_not_exists,
+WML,install_by_user & switch_profile_clients & sync_turn_off & uninstall_not_locally_installed,sync_turn_on,check_app_in_list_not_locally_installed,install_by_user,switch_profile_clients(Client2),sync_turn_off,uninstall_not_locally_installed,sync_turn_on,check_app_in_list_not_locally_installed,
+WML,install_by_user & switch_profile_clients & sync_turn_off & uninstall_not_locally_installed,sync_turn_on,check_platform_shortcut_not_exists,install_by_user,switch_profile_clients(Client2),sync_turn_off,uninstall_not_locally_installed,sync_turn_on,check_platform_shortcut_not_exists,
 C,install_by_user_tabbed & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_app_in_list_tabbed,install_by_user_tabbed,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_app_in_list_tabbed,
 C,install_by_user_tabbed & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_platform_shortcut_and_icon,install_by_user_tabbed,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_platform_shortcut_and_icon,
 C,install_by_user_windowed & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_app_in_list_windowed,install_by_user_windowed,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_app_in_list_windowed,
 C,install_by_user_windowed & switch_profile_clients & sync_turn_off & uninstall_by_user,sync_turn_on,check_platform_shortcut_and_icon,install_by_user_windowed,switch_profile_clients(Client2),sync_turn_off,uninstall_by_user,sync_turn_on,check_platform_shortcut_and_icon,
-WMLC,install_by_user_tabbed,uninstall_from_list,check_app_not_in_list,install_by_user_tabbed,uninstall_from_list,check_app_not_in_list,,,,
-WMLC,install_by_user_tabbed,uninstall_from_list,check_install_icon_shown,install_by_user_tabbed,uninstall_from_list,navigate_browser(SiteA),check_install_icon_shown,,,
-WMLC,install_by_user_tabbed,uninstall_from_list,check_launch_icon_not_shown,install_by_user_tabbed,uninstall_from_list,navigate_browser(SiteA),check_launch_icon_not_shown,,,
-WMLC,install_by_user_tabbed,uninstall_from_list,check_platform_shortcut_not_exists,install_by_user_tabbed,uninstall_from_list,check_platform_shortcut_not_exists,,,,
 WML,install_by_user_windowed,uninstall_by_user,check_app_not_in_list,install_by_user_windowed,uninstall_by_user,check_app_not_in_list,,,,
 WML,install_by_user_windowed,uninstall_by_user,check_install_icon_shown,install_by_user_windowed,uninstall_by_user,navigate_browser(SiteA),check_install_icon_shown,,,
 WML,install_by_user_windowed,uninstall_by_user,check_launch_icon_not_shown,install_by_user_windowed,uninstall_by_user,navigate_browser(SiteA),check_launch_icon_not_shown,,,
 WML,install_by_user_windowed,uninstall_by_user,check_platform_shortcut_not_exists,install_by_user_windowed,uninstall_by_user,check_platform_shortcut_not_exists,,,,
+WML,install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_app_not_in_list(SiteC),install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_app_not_in_list,,,,
+WML,install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_platform_shortcut_not_exists(SiteC),install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_platform_shortcut_not_exists(SiteC),,,,
+WMLC,install_by_user & switch_profile_clients,uninstall_from_list,check_app_not_in_list,install_by_user,switch_profile_clients,uninstall_from_list,check_app_not_in_list,,,
+WMLC,install_by_user & switch_profile_clients & uninstall_from_list & switch_profile_clients(Client1),uninstall_from_list,check_app_not_in_list,install_by_user,switch_profile_clients,uninstall_from_list,switch_profile_clients(Client1),check_app_not_in_list,,
+WMLC,install_by_user_tabbed,uninstall_from_list,check_app_not_in_list,install_by_user_tabbed,uninstall_from_list,check_app_not_in_list,,,,
+WMLC,install_by_user_tabbed,uninstall_from_list,check_install_icon_shown,install_by_user_tabbed,uninstall_from_list,navigate_browser(SiteA),check_install_icon_shown,,,
+WMLC,install_by_user_tabbed,uninstall_from_list,check_launch_icon_not_shown,install_by_user_tabbed,uninstall_from_list,navigate_browser(SiteA),check_launch_icon_not_shown,,,
+WMLC,install_by_user_tabbed,uninstall_from_list,check_platform_shortcut_not_exists,install_by_user_tabbed,uninstall_from_list,check_platform_shortcut_not_exists,,,,
 C,install_by_user_windowed,uninstall_from_list,check_app_not_in_list,install_by_user_windowed,uninstall_from_list,check_app_not_in_list,,,,
 C,install_by_user_windowed,uninstall_from_list,check_install_icon_shown,install_by_user_windowed,uninstall_from_list,navigate_browser(SiteA),check_install_icon_shown,,,
 C,install_by_user_windowed,uninstall_from_list,check_launch_icon_not_shown,install_by_user_windowed,uninstall_from_list,navigate_browser(SiteA),check_launch_icon_not_shown,,,
 C,install_by_user_windowed,uninstall_from_list,check_platform_shortcut_not_exists,install_by_user_windowed,uninstall_from_list,check_platform_shortcut_not_exists,,,,
 WMLC,install_by_user_tabbed(SiteC),uninstall_from_list(SiteC),check_app_not_in_list(SiteC),install_by_user_tabbed(SiteC),uninstall_from_list(SiteC),check_app_not_in_list,,,,
 WMLC,install_by_user_tabbed(SiteC),uninstall_from_list(SiteC),check_platform_shortcut_not_exists(SiteC),install_by_user_tabbed(SiteC),uninstall_from_list(SiteC),check_platform_shortcut_not_exists(SiteC),,,,
-WML,install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_app_not_in_list(SiteC),install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_app_not_in_list,,,,
-WML,install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_platform_shortcut_not_exists(SiteC),install_by_user_windowed(SiteC),uninstall_by_user(SiteC),check_platform_shortcut_not_exists(SiteC),,,,
 C,install_by_user_windowed(SiteC),uninstall_from_list(SiteC),check_app_not_in_list(SiteC),install_by_user_windowed(SiteC),uninstall_from_list(SiteC),check_app_not_in_list,,,,
 C,install_by_user_windowed(SiteC),uninstall_from_list(SiteC),check_platform_shortcut_not_exists(SiteC),install_by_user_windowed(SiteC),uninstall_from_list(SiteC),check_platform_shortcut_not_exists(SiteC),,,,
-WMLC,install_by_user & switch_profile_clients,uninstall_from_list,check_app_not_in_list,install_by_user,switch_profile_clients,uninstall_from_list,check_app_not_in_list,,,
-WMLC,install_by_user & switch_profile_clients & uninstall_from_list & switch_profile_clients(Client1),uninstall_from_list,check_app_not_in_list,install_by_user,switch_profile_clients,uninstall_from_list,switch_profile_clients(Client1),check_app_not_in_list,,
\ No newline at end of file
+WMLC,install_by_user_tabbed & install_policy_app,uninstall_policy_app,check_app_in_list_tabbed,install_by_user_tabbed,install_policy_app,uninstall_policy_app,check_app_in_list_tabbed,,,
+WMLC,install_by_user_tabbed & install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,install_by_user_tabbed,install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,,,
+WMLC,install_by_user_windowed & install_policy_app,uninstall_policy_app,check_app_in_list_windowed,install_by_user_windowed,install_policy_app,uninstall_policy_app,check_app_in_list_windowed,,,
+WMLC,install_by_user_windowed & install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,install_by_user_windowed,install_policy_app,uninstall_policy_app,check_platform_shortcut_and_icon,,,
+WMLC,install_policy_app,uninstall_policy_app,check_app_not_in_list,install_policy_app,uninstall_policy_app,check_app_not_in_list,,,,
+WMLC,install_policy_app,uninstall_policy_app,check_install_icon_shown,install_policy_app_tabbed_shortcut,uninstall_policy_app,navigate_browser(SiteA),check_install_icon_shown,,,
+WMLC,install_policy_app,uninstall_policy_app,check_launch_icon_not_shown,install_policy_app_tabbed_shortcut,uninstall_policy_app,navigate_browser(SiteA),check_launch_icon_not_shown,,,
+WMLC,install_policy_app,uninstall_policy_app,check_platform_shortcut_not_exists,install_policy_app,uninstall_policy_app,check_platform_shortcut_not_exists,check_app_not_in_list,,,
+WMLC,install_policy_app_tabbed & install_by_user_windowed,uninstall_policy_app,check_app_in_list_windowed,install_policy_app_tabbed,install_by_user_windowed,uninstall_policy_app,check_app_in_list_windowed,,,
+WMLC,install_policy_app_tabbed & install_by_user_windowed,uninstall_policy_app,check_platform_shortcut_and_icon,install_policy_app_tabbed,install_by_user_windowed,uninstall_policy_app,check_platform_shortcut_and_icon,,,
\ No newline at end of file
diff --git a/chrome/test/webapps/data/framework_supported_actions.csv b/chrome/test/webapps/data/framework_supported_actions.csv
index e22dd95..ea3ca953 100644
--- a/chrome/test/webapps/data/framework_supported_actions.csv
+++ b/chrome/test/webapps/data/framework_supported_actions.csv
@@ -41,4 +41,5 @@
 uninstall_from_list,                                   🌕, 🌕,  🌕,   🌕,
 uninstall_from_menu,                                   🌕, 🌕,  🌕,   🌑,
 uninstall_from_os,                                     🌑, 🌕,  🌑,   🌑,
-uninstall_policy_app,                                  🌕, 🌕,  🌕,   🌕,
\ No newline at end of file
+uninstall_policy_app,                                  🌕, 🌕,  🌕,   🌕,
+uninstall_from_app_settings,                           🌕, 🌕,  🌕,   🌑,
diff --git a/chrome/test/webapps/test_analysis.py b/chrome/test/webapps/test_analysis.py
index 84d5811..659d1ad8 100755
--- a/chrome/test/webapps/test_analysis.py
+++ b/chrome/test/webapps/test_analysis.py
@@ -74,7 +74,7 @@
                 tests_added_to_partition.add(test.id)
             filename = partition.generate_browsertest_filepath(platforms)
             print(f"\n\nAdd this following tests to {filename}:\n")
-            for test in tests_to_add:
+            for test in tests_to_add_partition:
                 print(test.generate_browsertest(partition) + "\n")
 
         # All remaining tests go into the default partition
diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
index c0dbb55..4f43b6d 100644
--- a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
+++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp
@@ -46,7 +46,6 @@
 #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/strings/string_number_conversions.h"
@@ -842,7 +841,7 @@
     if (point->reasons.len) {
       rv += ' ';
       comma = false;
-      for (size_t i = 0; i < base::size(reason_string_map); ++i) {
+      for (size_t i = 0; i < std::size(reason_string_map); ++i) {
         if (point->reasons.data[0] & reason_string_map[i].reason) {
           if (comma)
             rv += ',';
@@ -970,7 +969,7 @@
     {NS_CERT_TYPE_OBJECT_SIGNING_CA, IDS_CERT_USAGE_OBJECT_SIGNER},
   };
   return ProcessBitStringExtension(extension_data, usage_string_map,
-                                   base::size(usage_string_map), '\n');
+                                   std::size(usage_string_map), '\n');
 }
 
 static const MaskIdPair key_usage_string_map[] = {
@@ -988,12 +987,12 @@
 
 std::string ProcessKeyUsageBitString(SECItem* bitstring, char sep) {
   return ProcessBitField(bitstring, key_usage_string_map,
-                         base::size(key_usage_string_map), sep);
+                         std::size(key_usage_string_map), sep);
 }
 
 std::string ProcessKeyUsageExtension(SECItem* extension_data) {
   return ProcessBitStringExtension(extension_data, key_usage_string_map,
-                                   base::size(key_usage_string_map), '\n');
+                                   std::size(key_usage_string_map), '\n');
 }
 
 std::string ProcessExtKeyUsage(SECItem* extension_data) {
diff --git a/chrome/tools/convert_dict/convert_dict_unittest.cc b/chrome/tools/convert_dict/convert_dict_unittest.cc
index f1249e8a..8d84ceca 100644
--- a/chrome/tools/convert_dict/convert_dict_unittest.cc
+++ b/chrome/tools/convert_dict/convert_dict_unittest.cc
@@ -7,7 +7,6 @@
 #include <map>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/format_macros.h"
 #include "base/i18n/icu_string_conversions.h"
@@ -146,9 +145,8 @@
   };
 
   std::map<std::u16string, bool> word_list;
-  for (size_t i = 0; i < base::size(kWords); ++i) {
-    word_list.insert(std::make_pair<std::u16string, bool>(
-        base::WideToUTF16(kWords[i]), true));
+  for (size_t i = 0; i < std::size(kWords); ++i) {
+    word_list.insert({base::WideToUTF16(kWords[i]), true});
   }
 
   RunDictionaryTest(kCodepage, word_list);
@@ -169,9 +167,8 @@
   };
 
   std::map<std::u16string, bool> word_list;
-  for (size_t i = 0; i < base::size(kWords); ++i) {
-    word_list.insert(std::make_pair<std::u16string, bool>(
-        base::WideToUTF16(kWords[i]), true));
+  for (size_t i = 0; i < std::size(kWords); ++i) {
+    word_list.insert({base::WideToUTF16(kWords[i]), true});
   }
 
   RunDictionaryTest(kCodepage, word_list);
@@ -194,9 +191,8 @@
   };
 
   std::map<std::u16string, bool> word_list;
-  for (size_t i = 0; i < base::size(kWords); ++i) {
-    word_list.insert(std::make_pair<std::u16string, bool>(
-        base::WideToUTF16(kWords[i]), true));
+  for (size_t i = 0; i < std::size(kWords); ++i) {
+    word_list.insert({base::WideToUTF16(kWords[i]), true});
   }
 
   RunDictionaryTest(kCodepage, word_list);
diff --git a/chrome/updater/device_management/cloud_policy_util.cc b/chrome/updater/device_management/cloud_policy_util.cc
index 45e9760..fb7ba7d 100644
--- a/chrome/updater/device_management/cloud_policy_util.cc
+++ b/chrome/updater/device_management/cloud_policy_util.cc
@@ -146,7 +146,7 @@
   return std::string();
 #elif BUILDFLAG(IS_WIN)
   wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {0};
-  DWORD size = base::size(computer_name);
+  DWORD size = std::size(computer_name);
   if (::GetComputerNameW(computer_name, &size)) {
     std::string result;
     bool conversion_successful = base::WideToUTF8(computer_name, size, &result);
diff --git a/chrome/updater/tools/main.cc b/chrome/updater/tools/main.cc
index f524075..300dac4a 100644
--- a/chrome/updater/tools/main.cc
+++ b/chrome/updater/tools/main.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -150,7 +149,7 @@
     if (base::StartsWith(args.set_superfluous_cert_tag, kPrefix,
                          base::CompareCase::INSENSITIVE_ASCII)) {
       const auto hex_chars = base::MakeStringPiece(
-          std::begin(args.set_superfluous_cert_tag) + base::size(kPrefix) - 1,
+          std::begin(args.set_superfluous_cert_tag) + std::size(kPrefix) - 1,
           std::end(args.set_superfluous_cert_tag));
       if (!base::HexStringToBytes(hex_chars, &tag_contents)) {
         std::cerr << "Failed to parse tag contents from command line."
diff --git a/chrome/updater/win/setup/uninstall.cc b/chrome/updater/win/setup/uninstall.cc
index 5d1e362..56b746d 100644
--- a/chrome/updater/win/setup/uninstall.cc
+++ b/chrome/updater/win/setup/uninstall.cc
@@ -6,13 +6,13 @@
 
 #include <shlobj.h>
 #include <windows.h>
+
 #include <memory>
 #include <string>
 #include <vector>
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -106,7 +106,7 @@
 
   wchar_t cmd_path[MAX_PATH] = {0};
   DWORD size = ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\cmd.exe",
-                                        cmd_path, base::size(cmd_path));
+                                        cmd_path, std::size(cmd_path));
   if (!size || size >= MAX_PATH)
     return kErrorPathTooLong;
 
diff --git a/chrome/updater/win/ui/progress_wnd.cc b/chrome/updater/win/ui/progress_wnd.cc
index 6784a66b..35e58ee 100644
--- a/chrome/updater/win/ui/progress_wnd.cc
+++ b/chrome/updater/win/ui/progress_wnd.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/message_formatter.h"
 #include "base/notreached.h"
 #include "base/process/launch.h"
@@ -53,13 +52,13 @@
 // CompletionCodes. The enumeration value starts from 1 so the array size
 // should match the last value in the enumeration.
 static_assert(
-    base::size(kCompletionCodesActionPriority) ==
+    std::size(kCompletionCodesActionPriority) ==
         static_cast<size_t>(
             CompletionCodes::COMPLETION_CODE_INSTALL_FINISHED_BEFORE_CANCEL),
     "completion code is missing");
 
 int GetPriority(CompletionCodes code) {
-  for (size_t i = 0; i < base::size(kCompletionCodesActionPriority); ++i) {
+  for (size_t i = 0; i < std::size(kCompletionCodesActionPriority); ++i) {
     if (kCompletionCodesActionPriority[i] == code)
       return i;
   }
diff --git a/chrome/updater/win/ui/splash_screen.cc b/chrome/updater/win/ui/splash_screen.cc
index fe146d0a..8c1d1be 100644
--- a/chrome/updater/win/ui/splash_screen.cc
+++ b/chrome/updater/win/ui/splash_screen.cc
@@ -7,7 +7,6 @@
 #include <cstdint>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "chrome/updater/win/ui/ui.h"
 #include "chrome/updater/win/ui/ui_constants.h"
@@ -208,7 +207,7 @@
     case WindowState::STATE_INITIALIZED:
       break;
     case WindowState::STATE_SHOW_NORMAL:
-      alpha_index_ = base::size(kAlphaScales) - 1;
+      alpha_index_ = std::size(kAlphaScales) - 1;
       break;
     case WindowState::STATE_FADING:
       DCHECK(IsWindow());
diff --git a/chrome/updater/win/win_util.cc b/chrome/updater/win/win_util.cc
index 01ee3d0..cd02dc4 100644
--- a/chrome/updater/win/win_util.cc
+++ b/chrome/updater/win/win_util.cc
@@ -235,8 +235,8 @@
                                       SECURITY_DESCRIPTOR_REVISION))
     return false;
 
-  DCHECK_EQ(kSidCount, base::size(sids));
-  DCHECK_EQ(kSidCount, base::size(sid_types));
+  DCHECK_EQ(kSidCount, std::size(sids));
+  DCHECK_EQ(kSidCount, std::size(sid_types));
   for (size_t i = 0; i < kSidCount; ++i) {
     DWORD sid_bytes = sizeof(sids[i]);
     if (!::CreateWellKnownSid(sid_types[i], nullptr, sids[i], &sid_bytes))
@@ -247,8 +247,8 @@
   // the access permissions for your application. COM_RIGHTS_EXECUTE and
   // COM_RIGHTS_EXECUTE_LOCAL are the minimum access rights required.
   EXPLICIT_ACCESS explicit_access[kSidCount] = {};
-  DCHECK_EQ(kSidCount, base::size(sids));
-  DCHECK_EQ(kSidCount, base::size(explicit_access));
+  DCHECK_EQ(kSidCount, std::size(sids));
+  DCHECK_EQ(kSidCount, std::size(explicit_access));
   for (size_t i = 0; i < kSidCount; ++i) {
     explicit_access[i].grfAccessPermissions =
         COM_RIGHTS_EXECUTE | COM_RIGHTS_EXECUTE_LOCAL;
@@ -264,7 +264,7 @@
   // Create an access control list (ACL) using this ACE list, if this succeeds
   // make sure to ::LocalFree(acl).
   ACL* acl = nullptr;
-  DWORD acl_result = ::SetEntriesInAcl(base::size(explicit_access),
+  DWORD acl_result = ::SetEntriesInAcl(std::size(explicit_access),
                                        explicit_access, nullptr, &acl);
   if (acl_result != ERROR_SUCCESS || acl == nullptr)
     return false;
@@ -329,7 +329,7 @@
 
   wchar_t event_name[MAX_PATH] = {0};
   if (!::GetEnvironmentVariable(var_name.c_str(), event_name,
-                                base::size(event_name))) {
+                                std::size(event_name))) {
     return HRESULTFromLastError();
   }
 
diff --git a/chrome/utility/importer/bookmark_html_reader.cc b/chrome/utility/importer/bookmark_html_reader.cc
index 829ca42..276c09a 100644
--- a/chrome/utility/importer/bookmark_html_reader.cc
+++ b/chrome/utility/importer/bookmark_html_reader.cc
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/i18n/icu_string_conversions.h"
 #include "base/strings/string_number_conversions.h"
@@ -99,7 +98,7 @@
   static const char kDtTag[] = "<DT>";
   if (base::StartsWith(line, kDtTag,
                        base::CompareCase::INSENSITIVE_ASCII)) {
-    line.erase(0, base::size(kDtTag) - 1);
+    line.erase(0, std::size(kDtTag) - 1);
     base::TrimString(line, " ", &line);
   }
   return line;
@@ -140,7 +139,7 @@
     static const char kHrTag[] = "<HR>";
     while (base::StartsWith(line, kHrTag,
                             base::CompareCase::INSENSITIVE_ASCII)) {
-      line.erase(0, base::size(kHrTag) - 1);
+      line.erase(0, std::size(kHrTag) - 1);
       base::TrimString(line, " ", &line);
     }
 
@@ -340,15 +339,15 @@
   size_t end = line.find(kFolderClose);
   size_t tag_end = line.rfind('>', end) + 1;
   // If no end tag or start tag is broken, we skip to find the folder name.
-  if (end == std::string::npos || tag_end < base::size(kFolderOpen))
+  if (end == std::string::npos || tag_end < std::size(kFolderOpen))
     return false;
 
   base::CodepageToUTF16(line.substr(tag_end, end - tag_end), charset.c_str(),
                         base::OnStringConversionError::SKIP, folder_name);
   *folder_name = net::UnescapeForHTML(*folder_name);
 
-  std::string attribute_list = line.substr(
-      base::size(kFolderOpen), tag_end - base::size(kFolderOpen) - 1);
+  std::string attribute_list =
+      line.substr(std::size(kFolderOpen), tag_end - std::size(kFolderOpen) - 1);
   std::string value;
 
   // Add date
@@ -399,11 +398,11 @@
 
   size_t end = line.find(kItemClose);
   size_t tag_end = line.rfind('>', end) + 1;
-  if (end == std::string::npos || tag_end < base::size(kItemOpen))
+  if (end == std::string::npos || tag_end < std::size(kItemOpen))
     return false;  // No end tag or start tag is broken.
 
   std::string attribute_list =
-      line.substr(base::size(kItemOpen), tag_end - base::size(kItemOpen) - 1);
+      line.substr(std::size(kItemOpen), tag_end - std::size(kItemOpen) - 1);
 
   // We don't import Live Bookmark folders, which is Firefox's RSS reading
   // feature, since the user never necessarily bookmarked them and we don't
@@ -477,11 +476,11 @@
   // Find any close tag.
   size_t end = line.find(kItemClose);
   size_t tag_end = line.rfind('>', end) + 1;
-  if (end == std::string::npos || tag_end < base::size(kItemOpen))
+  if (end == std::string::npos || tag_end < std::size(kItemOpen))
     return false;  // No end tag or start tag is broken.
 
   std::string attribute_list =
-      line.substr(base::size(kItemOpen), tag_end - base::size(kItemOpen) - 1);
+      line.substr(std::size(kItemOpen), tag_end - std::size(kItemOpen) - 1);
 
   // Title
   base::CodepageToUTF16(line.substr(tag_end, end - tag_end), charset.c_str(),
diff --git a/chrome/utility/importer/bookmark_html_reader_unittest.cc b/chrome/utility/importer/bookmark_html_reader_unittest.cc
index 03e6b27..57087e1 100644
--- a/chrome/utility/importer/bookmark_html_reader_unittest.cc
+++ b/chrome/utility/importer/bookmark_html_reader_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/strings/string_util.h"
@@ -193,7 +192,7 @@
   };
 
   std::string search_engine_url;
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     EXPECT_EQ(test_cases[i].can_be_imported_as_search_engine,
         CanImportURLAsSearchEngine(GURL(test_cases[i].url),
                                    &search_engine_url));
diff --git a/chrome/utility/importer/bookmarks_file_importer.cc b/chrome/utility/importer/bookmarks_file_importer.cc
index 4110da3..1be8b6b 100644
--- a/chrome/utility/importer/bookmarks_file_importer.cc
+++ b/chrome/utility/importer/bookmarks_file_importer.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "chrome/common/importer/imported_bookmark_entry.h"
 #include "chrome/common/importer/importer_bridge.h"
 #include "chrome/common/importer/importer_data_types.h"
@@ -38,7 +37,7 @@
 
   // Filter out the URLs with unsupported schemes.
   const char* const kInvalidSchemes[] = {"wyciwyg", "place"};
-  for (size_t i = 0; i < base::size(kInvalidSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kInvalidSchemes); ++i) {
     if (url.SchemeIs(kInvalidSchemes[i]))
       return false;
   }
diff --git a/chrome/utility/importer/bookmarks_file_importer_unittest.cc b/chrome/utility/importer/bookmarks_file_importer_unittest.cc
index c5414db..a2009d6 100644
--- a/chrome/utility/importer/bookmarks_file_importer_unittest.cc
+++ b/chrome/utility/importer/bookmarks_file_importer_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -38,7 +37,7 @@
     { "about:moon", false },
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     EXPECT_EQ(test_cases[i].can_be_imported,
               internal::CanImportURL(GURL(test_cases[i].url)));
   }
diff --git a/chrome/utility/importer/edge_database_reader_unittest_win.cc b/chrome/utility/importer/edge_database_reader_unittest_win.cc
index c8ba62a29..2b1e29d 100644
--- a/chrome/utility/importer/edge_database_reader_unittest_win.cc
+++ b/chrome/utility/importer/edge_database_reader_unittest_win.cc
@@ -2,14 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/utility/importer/edge_database_reader_win.h"
-
 #include <windows.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
@@ -17,6 +14,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/common/chrome_paths.h"
+#include "chrome/utility/importer/edge_database_reader_win.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/zlib/google/compression_utils.h"
 
@@ -281,7 +279,7 @@
   std::unique_ptr<EdgeDatabaseTableEnumerator> table_enum =
       reader.OpenTableEnumerator(L"UnicodeTable");
   EXPECT_NE(nullptr, table_enum);
-  size_t utf8_strings_count = base::size(utf8_strings);
+  size_t utf8_strings_count = std::size(utf8_strings);
   for (size_t row_count = 0; row_count < utf8_strings_count; ++row_count) {
     std::u16string row_string = base::UTF8ToUTF16(utf8_strings[row_count]);
     std::u16string str_col_value;
diff --git a/chrome/utility/importer/safari_importer_unittest.mm b/chrome/utility/importer/safari_importer_unittest.mm
index 6ca2bed..d81c7b71 100644
--- a/chrome/utility/importer/safari_importer_unittest.mm
+++ b/chrome/utility/importer/safari_importer_unittest.mm
@@ -9,7 +9,6 @@
 
 #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"
@@ -80,7 +79,7 @@
   std::vector<ImportedBookmarkEntry> bookmarks;
   importer->ParseBookmarks(u"Toolbar", &bookmarks);
   size_t num_bookmarks = bookmarks.size();
-  ASSERT_EQ(base::size(kImportedBookmarksData), num_bookmarks);
+  ASSERT_EQ(std::size(kImportedBookmarksData), num_bookmarks);
 
   for (size_t i = 0; i < num_bookmarks; ++i) {
     ImportedBookmarkEntry& entry = bookmarks[i];
@@ -122,7 +121,7 @@
   std::vector<ImportedBookmarkEntry> bookmarks;
   importer->ParseBookmarks(u"Toolbar", &bookmarks);
   size_t num_bookmarks = bookmarks.size();
-  ASSERT_EQ(base::size(kImportedBookmarksData), num_bookmarks);
+  ASSERT_EQ(std::size(kImportedBookmarksData), num_bookmarks);
 
   for (size_t i = 0; i < num_bookmarks; ++i) {
     ImportedBookmarkEntry& entry = bookmarks[i];
diff --git a/chrome/utility/safe_browsing/mac/dmg_analyzer.cc b/chrome/utility/safe_browsing/mac/dmg_analyzer.cc
index abd54b1..788f8e4 100644
--- a/chrome/utility/safe_browsing/mac/dmg_analyzer.cc
+++ b/chrome/utility/safe_browsing/mac/dmg_analyzer.cc
@@ -10,7 +10,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -171,11 +170,11 @@
       if (!ReadEntireStream(stream.get(), &signature_contents))
         continue;
 
-      if (signature_contents.size() < base::size(kDERPKCS7SignedData))
+      if (signature_contents.size() < std::size(kDERPKCS7SignedData))
         continue;
 
       if (memcmp(kDERPKCS7SignedData, signature_contents.data(),
-                 base::size(kDERPKCS7SignedData)) != 0) {
+                 std::size(kDERPKCS7SignedData)) != 0) {
         continue;
       }
 
diff --git a/chrome/utility/safe_browsing/mac/hfs.cc b/chrome/utility/safe_browsing/mac/hfs.cc
index 6384f65..8098e8c 100644
--- a/chrome/utility/safe_browsing/mac/hfs.cc
+++ b/chrome/utility/safe_browsing/mac/hfs.cc
@@ -13,7 +13,6 @@
 #include <set>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/numerics/safe_math.h"
 #include "base/strings/utf_string_conversions.h"
@@ -30,7 +29,7 @@
   ConvertBigEndian(&fork->logicalSize);
   ConvertBigEndian(&fork->clumpSize);
   ConvertBigEndian(&fork->totalBlocks);
-  for (size_t i = 0; i < base::size(fork->extents); ++i) {
+  for (size_t i = 0; i < std::size(fork->extents); ++i) {
     ConvertBigEndian(&fork->extents[i].startBlock);
     ConvertBigEndian(&fork->extents[i].blockCount);
   }
@@ -357,7 +356,7 @@
   if (fork_logical_offset_ == fork_.logicalSize)
     return true;
 
-  for (; current_extent_ < base::size(fork_.extents); ++current_extent_) {
+  for (; current_extent_ < std::size(fork_.extents); ++current_extent_) {
     // If the buffer is out of space, do not attempt any reads. Check this
     // here, so that current_extent_ is advanced by the loop if the last
     // extent was fully read.
@@ -430,7 +429,7 @@
   DCHECK(offset == 0 || static_cast<uint64_t>(offset) < fork_.logicalSize);
   size_t target_block = offset / hfs_->block_size();
   size_t block_count = 0;
-  for (size_t i = 0; i < base::size(fork_.extents); ++i) {
+  for (size_t i = 0; i < std::size(fork_.extents); ++i) {
     const HFSPlusExtentDescriptor* extent = &fork_.extents[i];
 
     // An empty extent indicates end-of-fork.
diff --git a/chrome/utility/safe_browsing/mac/hfs_unittest.cc b/chrome/utility/safe_browsing/mac/hfs_unittest.cc
index 3ceee25..d7d7e92b 100644
--- a/chrome/utility/safe_browsing/mac/hfs_unittest.cc
+++ b/chrome/utility/safe_browsing/mac/hfs_unittest.cc
@@ -9,7 +9,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
@@ -49,13 +48,13 @@
 
     const std::u16string dmg_name = u"SafeBrowsingDMG/";
 
-    for (size_t i = 0; i < base::size(kBaseFiles); ++i)
+    for (size_t i = 0; i < std::size(kBaseFiles); ++i)
       files->insert(dmg_name + kBaseFiles[i]);
 
     files->insert(dmg_name + u"first/second/" + u"Tĕsẗ 🐐 ");
 
     dirs->insert(dmg_name.substr(0, dmg_name.size() - 1));
-    for (size_t i = 0; i < base::size(kBaseDirs); ++i)
+    for (size_t i = 0; i < std::size(kBaseDirs); ++i)
       dirs->insert(dmg_name + kBaseDirs[i]);
 
     if (case_sensitive) {
diff --git a/chrome/utility/safe_browsing/mac/udif.cc b/chrome/utility/safe_browsing/mac/udif.cc
index 028bdaa0..72eed10 100644
--- a/chrome/utility/safe_browsing/mac/udif.cc
+++ b/chrome/utility/safe_browsing/mac/udif.cc
@@ -13,7 +13,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
@@ -44,7 +43,7 @@
 static void ConvertBigEndian(UDIFChecksum* checksum) {
   ConvertBigEndian(&checksum->type);
   ConvertBigEndian(&checksum->size);
-  for (size_t i = 0; i < base::size(checksum->data); ++i) {
+  for (size_t i = 0; i < std::size(checksum->data); ++i) {
     ConvertBigEndian(&checksum->data[i]);
   }
 }
diff --git a/chromecast/base/metrics/grouped_histogram.cc b/chromecast/base/metrics/grouped_histogram.cc
index 59222f7..174ee45 100644
--- a/chromecast/base/metrics/grouped_histogram.cc
+++ b/chromecast/base/metrics/grouped_histogram.cc
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/no_destructor.h"
@@ -171,7 +170,7 @@
 } // namespace
 
 void PreregisterAllGroupedHistograms() {
-  for (size_t i = 0; i < base::size(kHistogramsToGroup); ++i) {
+  for (size_t i = 0; i < std::size(kHistogramsToGroup); ++i) {
     PreregisterHistogram(
         kHistogramsToGroup[i].name,
         kHistogramsToGroup[i].minimum,
diff --git a/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
index df1e080c..4658c0e 100644
--- a/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
+++ b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
@@ -1311,7 +1311,7 @@
   // detector test, since it seems to be about the right amount to get a swipe.
   const int kSteps = 15;
 
-  for (size_t i = 0; i < base::size(gestures_to_test); ++i) {
+  for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
     const float distance = 2 * gesture_detector_config_.touch_slop + 1;
     int move_x = gestures_to_test[i].move_x * distance;
     int move_y = gestures_to_test[i].move_y * distance;
@@ -1372,7 +1372,7 @@
   // detector test, since it seems to be about the right amount to get a swipe.
   const int kSteps = 15;
 
-  for (size_t i = 0; i < base::size(gestures_to_test); ++i) {
+  for (size_t i = 0; i < std::size(gestures_to_test); ++i) {
     const float distance = 2 * gesture_detector_config_.touch_slop + 1;
     int move_x = gestures_to_test[i].move_x * distance;
     int move_y = gestures_to_test[i].move_y * distance;
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index 751eb9f69..d2092f2 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -14,7 +14,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/memory_pressure_monitor.h"
@@ -189,7 +188,7 @@
 void RegisterClosureOnSignal(base::OnceClosure closure) {
   DCHECK(!g_signal_closure);
   DCHECK(closure);
-  DCHECK_GT(base::size(kSignalsToRunClosure), 0U);
+  DCHECK_GT(std::size(kSignalsToRunClosure), 0U);
 
   // Memory leak on purpose, since |g_signal_closure| should live until
   // process exit.
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 2f60dc22..d01dd5b 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -11,7 +11,6 @@
 #include "base/base_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/files/scoped_file.h"
 #include "base/i18n/rtl.h"
@@ -404,7 +403,7 @@
   };
 
   const std::string& scheme = url.scheme();
-  for (size_t i = 0; i < base::size(kProtocolList); ++i) {
+  for (size_t i = 0; i < std::size(kProtocolList); ++i) {
     if (scheme == kProtocolList[i])
       return true;
   }
@@ -468,7 +467,7 @@
         switches::kForceMediaResolutionWidth,
         network::switches::kUnsafelyTreatInsecureOriginAsSecure};
     command_line->CopySwitchesFrom(*browser_command_line, kForwardSwitches,
-                                   base::size(kForwardSwitches));
+                                   std::size(kForwardSwitches));
   } else if (process_type == switches::kUtilityProcess) {
     if (browser_command_line->HasSwitch(switches::kAudioOutputChannels)) {
       command_line->AppendSwitchASCII(switches::kAudioOutputChannels,
@@ -490,7 +489,7 @@
         switches::kVSyncInterval,
     };
     command_line->CopySwitchesFrom(*browser_command_line, kForwardSwitches,
-                                   base::size(kForwardSwitches));
+                                   std::size(kForwardSwitches));
 
     auto display = display::Screen::GetScreen()->GetPrimaryDisplay();
     gfx::Size res = display.GetSizeInPixel();
diff --git a/chromecast/browser/cast_extension_message_filter.cc b/chromecast/browser/cast_extension_message_filter.cc
index e2388b75..c0af27a0 100644
--- a/chromecast/browser/cast_extension_message_filter.cc
+++ b/chromecast/browser/cast_extension_message_filter.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/memory/ptr_util.h"
 #include "base/notreached.h"
@@ -42,7 +41,7 @@
     int render_process_id,
     content::BrowserContext* context)
     : BrowserMessageFilter(kExtensionFilteredMessageClasses,
-                           base::size(kExtensionFilteredMessageClasses)),
+                           std::size(kExtensionFilteredMessageClasses)),
       render_process_id_(render_process_id),
       context_(context),
       extension_info_map_(
diff --git a/chromecast/common/cors_exempt_headers.cc b/chromecast/common/cors_exempt_headers.cc
index 990ac78..02c05fc 100644
--- a/chromecast/common/cors_exempt_headers.cc
+++ b/chromecast/common/cors_exempt_headers.cc
@@ -46,7 +46,7 @@
 bool IsCorsExemptHeader(base::StringPiece header) {
   static const base::NoDestructor<base::flat_set<std::string>>
       exempt_header_set(kExemptHeaders,
-                        kExemptHeaders + base::size(kExemptHeaders));
+                        kExemptHeaders + std::size(kExemptHeaders));
   return exempt_header_set->find(header) != exempt_header_set->end();
 }
 
diff --git a/chromecast/media/audio/cast_audio_manager_alsa.cc b/chromecast/media/audio/cast_audio_manager_alsa.cc
index 0b404e0a..1ef1688 100644
--- a/chromecast/media/audio/cast_audio_manager_alsa.cc
+++ b/chromecast/media/audio/cast_audio_manager_alsa.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/free_deleter.h"
 #include "base/strings/string_piece.h"
@@ -56,7 +55,7 @@
   // it or not.
   if (type == CastAudioManagerAlsa::kStreamCapture) {
     // Check if the device is in the list of invalid devices.
-    for (size_t i = 0; i < base::size(kInvalidAudioInputDevices); ++i) {
+    for (size_t i = 0; i < std::size(kInvalidAudioInputDevices); ++i) {
       if (kInvalidAudioInputDevices[i] == device_name)
         return false;
     }
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index c77fe66..604302c 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -10,7 +10,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
@@ -581,7 +580,7 @@
   ::media::AudioParameters::Format format[] = {
       ::media::AudioParameters::AUDIO_PCM_LINEAR,
       ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY};
-  for (size_t i = 0; i < base::size(format); ++i) {
+  for (size_t i = 0; i < std::size(format); ++i) {
     format_ = format[i];
     ::media::AudioOutputStream* stream = CreateStream();
     ASSERT_TRUE(stream);
@@ -602,7 +601,7 @@
 TEST_F(CastAudioOutputStreamTest, ChannelLayout) {
   ::media::ChannelLayout layout[] = {::media::CHANNEL_LAYOUT_MONO,
                                      ::media::CHANNEL_LAYOUT_STEREO};
-  for (size_t i = 0; i < base::size(layout); ++i) {
+  for (size_t i = 0; i < std::size(layout); ++i) {
     channel_layout_ = layout[i];
     ::media::AudioOutputStream* stream = CreateStream();
     ASSERT_TRUE(stream);
diff --git a/chromecast/media/cdm/playready_drm_delegate_android.cc b/chromecast/media/cdm/playready_drm_delegate_android.cc
index 260fdc1..5c44bb0 100644
--- a/chromecast/media/cdm/playready_drm_delegate_android.cc
+++ b/chromecast/media/cdm/playready_drm_delegate_android.cc
@@ -4,7 +4,6 @@
 
 #include "chromecast/media/cdm/playready_drm_delegate_android.h"
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "chromecast/media/cdm/chromecast_init_data.h"
 
@@ -23,7 +22,7 @@
 
 const ::media::UUID PlayreadyDrmDelegateAndroid::GetUUID() const {
   return ::media::UUID(kPlayreadyUuid,
-                       kPlayreadyUuid + base::size(kPlayreadyUuid));
+                       kPlayreadyUuid + std::size(kPlayreadyUuid));
 }
 
 bool PlayreadyDrmDelegateAndroid::OnCreateSession(
diff --git a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
index 6d427f7..ec116a6 100644
--- a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
+++ b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
@@ -9,7 +9,6 @@
 #include <string>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/threading/platform_thread.h"
@@ -466,7 +465,7 @@
   // doesn't always choose a rate that's actually near the given input sample
   // rate when the input sample rate is not supported.
   const int* kSupportedSampleRatesEnd =
-      kSupportedSampleRates + base::size(kSupportedSampleRates);
+      kSupportedSampleRates + std::size(kSupportedSampleRates);
   auto* nearest_sample_rate =
       std::min_element(kSupportedSampleRates, kSupportedSampleRatesEnd,
                        [requested_sample_rate](int r1, int r2) -> bool {
diff --git a/chromecast/media/cma/backend/multizone_backend_unittest.cc b/chromecast/media/cma/backend/multizone_backend_unittest.cc
index a017593..cd27536 100644
--- a/chromecast/media/cma/backend/multizone_backend_unittest.cc
+++ b/chromecast/media/cma/backend/multizone_backend_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/callback_helpers.h"
 #include "base/check.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
@@ -392,7 +391,7 @@
   const TestParams& params = GetParam();
   int sample_rate = testing::get<0>(params);
   double* sequence = testing::get<1>(params);
-  Initialize(sample_rate, sequence, base::size(kTestRateSequence1));
+  Initialize(sample_rate, sequence, std::size(kTestRateSequence1));
   AddEffectsStreams();
   Start();
 }
diff --git a/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
index ba7e93bf..00cc4ff 100644
--- a/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
+++ b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
@@ -220,7 +219,7 @@
   int timestamps0_ms[] = {0, 10, 20, 30, 40, 30, 50, 60, 20, 30, 70};
   std::vector<std::vector<int> > timestamps_ms(1);
   timestamps_ms[0] = std::vector<int>(
-      timestamps0_ms, timestamps0_ms + base::size(timestamps0_ms));
+      timestamps0_ms, timestamps0_ms + std::size(timestamps0_ms));
 
   // Scheduling pattern.
   std::vector<size_t> scheduling_pattern(1);
@@ -230,7 +229,7 @@
   int expected_timestamps[] = {0, 10, 20, 30, 40, 50, 60, 70};
   std::vector<int> expected_timestamps_ms(
       std::vector<int>(expected_timestamps,
-                       expected_timestamps + base::size(expected_timestamps)));
+                       expected_timestamps + std::size(expected_timestamps)));
 
   SetupTest(base::Milliseconds(30), timestamps_ms, scheduling_pattern,
             expected_timestamps_ms);
@@ -247,21 +246,21 @@
   int timestamps1_ms[] = {5, 15, 25, 35, 45, 35, 55, 65, 25, 35, 75};
   std::vector<std::vector<int> > timestamps_ms(2);
   timestamps_ms[0] = std::vector<int>(
-      timestamps0_ms, timestamps0_ms + base::size(timestamps0_ms));
+      timestamps0_ms, timestamps0_ms + std::size(timestamps0_ms));
   timestamps_ms[1] = std::vector<int>(
-      timestamps1_ms, timestamps1_ms + base::size(timestamps1_ms));
+      timestamps1_ms, timestamps1_ms + std::size(timestamps1_ms));
 
   // Scheduling pattern.
   size_t pattern[] = {1, 0, 0, 0, 0};
   std::vector<size_t> scheduling_pattern =
-      std::vector<size_t>(pattern, pattern + base::size(pattern));
+      std::vector<size_t>(pattern, pattern + std::size(pattern));
 
   // Expected results.
   int expected_timestamps[] = {
     5, 0, 10, 20, 30, 15, 40, 25, 50, 35, 60, 45, 70, 55, 65, 75 };
   std::vector<int> expected_timestamps_ms(
       std::vector<int>(expected_timestamps,
-                       expected_timestamps + base::size(expected_timestamps)));
+                       expected_timestamps + std::size(expected_timestamps)));
 
   SetupTest(base::Milliseconds(30), timestamps_ms, scheduling_pattern,
             expected_timestamps_ms);
diff --git a/chromecast/media/cma/base/buffering_frame_provider_unittest.cc b/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
index 5c11035..fd8b94ee 100644
--- a/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
+++ b/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/task/current_thread.h"
@@ -125,12 +124,12 @@
 
   const size_t frame_count = 100u;
   Configure(frame_count,
-            std::vector<bool>(provider_delayed_pattern,
-                              provider_delayed_pattern +
-                                  base::size(provider_delayed_pattern)),
+            std::vector<bool>(
+                provider_delayed_pattern,
+                provider_delayed_pattern + std::size(provider_delayed_pattern)),
             std::vector<bool>(consumer_delayed_pattern,
                               consumer_delayed_pattern +
-                                  base::size(consumer_delayed_pattern)));
+                                  std::size(consumer_delayed_pattern)));
 
   base::test::SingleThreadTaskEnvironment task_environment;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -145,12 +144,12 @@
 
   const size_t frame_count = 100u;
   Configure(frame_count,
-            std::vector<bool>(provider_delayed_pattern,
-                              provider_delayed_pattern +
-                                  base::size(provider_delayed_pattern)),
+            std::vector<bool>(
+                provider_delayed_pattern,
+                provider_delayed_pattern + std::size(provider_delayed_pattern)),
             std::vector<bool>(consumer_delayed_pattern,
                               consumer_delayed_pattern +
-                                  base::size(consumer_delayed_pattern)));
+                                  std::size(consumer_delayed_pattern)));
 
   base::test::SingleThreadTaskEnvironment task_environment;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -172,12 +171,12 @@
 
   const size_t frame_count = 100u;
   Configure(frame_count,
-            std::vector<bool>(provider_delayed_pattern,
-                              provider_delayed_pattern +
-                                  base::size(provider_delayed_pattern)),
+            std::vector<bool>(
+                provider_delayed_pattern,
+                provider_delayed_pattern + std::size(provider_delayed_pattern)),
             std::vector<bool>(consumer_delayed_pattern,
                               consumer_delayed_pattern +
-                                  base::size(consumer_delayed_pattern)));
+                                  std::size(consumer_delayed_pattern)));
 
   base::test::SingleThreadTaskEnvironment task_environment;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromecast/media/cma/base/decoder_buffer_adapter_unittest.cc b/chromecast/media/cma/base/decoder_buffer_adapter_unittest.cc
index 3888728..578ed61 100644
--- a/chromecast/media/cma/base/decoder_buffer_adapter_unittest.cc
+++ b/chromecast/media/cma/base/decoder_buffer_adapter_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chromecast/media/cma/base/decoder_buffer_adapter.h"
 
-#include "base/cxx17_backports.h"
 #include "chromecast/public/media/cast_decrypt_config.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/decrypt_config.h"
@@ -12,7 +11,7 @@
 
 namespace {
 static const uint8_t kBufferData[] = "hello";
-static const size_t kBufferDataSize = base::size(kBufferData);
+static const size_t kBufferDataSize = std::size(kBufferData);
 static const int64_t kBufferTimestampUs = 31;
 
 scoped_refptr<media::DecoderBuffer> MakeDecoderBuffer() {
@@ -62,7 +61,7 @@
   EXPECT_EQ(kBufferDataSize, buffer_adapter->data_size());
 
   const uint8_t kTestBufferData[] = "world";
-  const size_t kTestBufferDataSize = base::size(kTestBufferData);
+  const size_t kTestBufferDataSize = std::size(kTestBufferData);
   memcpy(buffer_adapter->writable_data(), kTestBufferData, kTestBufferDataSize);
   EXPECT_EQ(
       0, memcmp(buffer_adapter->data(), kTestBufferData, kTestBufferDataSize));
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
index b741d65..56c69f3 100644
--- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
+++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -251,7 +250,7 @@
     frame_provider->Configure(
         std::vector<bool>(
             provider_delayed_pattern,
-            provider_delayed_pattern + base::size(provider_delayed_pattern)),
+            provider_delayed_pattern + std::size(provider_delayed_pattern)),
         std::move(frame_generator));
     frame_provider->SetDelayFlush(true);
     return std::move(frame_provider);
diff --git a/chromecast/media/cma/test/frame_generator_for_test.cc b/chromecast/media/cma/test/frame_generator_for_test.cc
index ee54674..f1839e1e 100644
--- a/chromecast/media/cma/test/frame_generator_for_test.cc
+++ b/chromecast/media/cma/test/frame_generator_for_test.cc
@@ -5,9 +5,9 @@
 #include "chromecast/media/cma/test/frame_generator_for_test.h"
 
 #include <stdint.h>
+
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "chromecast/media/api/decoder_buffer_base.h"
 #include "chromecast/media/cma/base/decoder_buffer_adapter.h"
 #include "media/base/decoder_buffer.h"
@@ -99,8 +99,8 @@
 
     std::unique_ptr<::media::DecryptConfig> decrypt_config =
         ::media::DecryptConfig::CreateCencConfig(
-            std::string(key_id, base::size(key_id)),
-            std::string(iv, base::size(iv)), subsamples);
+            std::string(key_id, std::size(key_id)),
+            std::string(iv, std::size(iv)), subsamples);
     buffer->set_decrypt_config(std::move(decrypt_config));
   }
 
diff --git a/chromecast/renderer/assistant_bindings.cc b/chromecast/renderer/assistant_bindings.cc
index 3b0f9c5..a233291 100644
--- a/chromecast/renderer/assistant_bindings.cc
+++ b/chromecast/renderer/assistant_bindings.cc
@@ -64,7 +64,7 @@
 
   v8::Local<v8::Value> argv[] = {message_val};
   web_frame->CallFunctionEvenIfScriptDisabled(handler, context->Global(),
-                                              base::size(argv), argv);
+                                              std::size(argv), argv);
 
   assistant_message_handler_ =
       v8::UniquePersistent<v8::Function>(isolate, handler);
diff --git a/chromecast/tracing/ftrace.cc b/chromecast/tracing/ftrace.cc
index 14c2a5e..d617e1d 100644
--- a/chromecast/tracing/ftrace.cc
+++ b/chromecast/tracing/ftrace.cc
@@ -8,7 +8,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/strings/string_piece.h"
@@ -70,32 +69,32 @@
 void AddCategoryEvents(const std::string& category,
                        std::vector<std::string>* events) {
   if (category == "gfx") {
-    std::copy(kGfxEvents, kGfxEvents + base::size(kGfxEvents),
+    std::copy(kGfxEvents, kGfxEvents + std::size(kGfxEvents),
               std::back_inserter(*events));
     return;
   }
   if (category == "input") {
-    std::copy(kInputEvents, kInputEvents + base::size(kInputEvents),
+    std::copy(kInputEvents, kInputEvents + std::size(kInputEvents),
               std::back_inserter(*events));
     return;
   }
   if (category == TRACE_DISABLED_BY_DEFAULT("irq")) {
-    std::copy(kIrqEvents, kIrqEvents + base::size(kIrqEvents),
+    std::copy(kIrqEvents, kIrqEvents + std::size(kIrqEvents),
               std::back_inserter(*events));
     return;
   }
   if (category == "power") {
-    std::copy(kPowerEvents, kPowerEvents + base::size(kPowerEvents),
+    std::copy(kPowerEvents, kPowerEvents + std::size(kPowerEvents),
               std::back_inserter(*events));
     return;
   }
   if (category == "sched") {
-    std::copy(kSchedEvents, kSchedEvents + base::size(kSchedEvents),
+    std::copy(kSchedEvents, kSchedEvents + std::size(kSchedEvents),
               std::back_inserter(*events));
     return;
   }
   if (category == "workq") {
-    std::copy(kWorkqEvents, kWorkqEvents + base::size(kWorkqEvents),
+    std::copy(kWorkqEvents, kWorkqEvents + std::size(kWorkqEvents),
               std::back_inserter(*events));
     return;
   }
diff --git a/chromecast/tracing/system_tracing_common.cc b/chromecast/tracing/system_tracing_common.cc
index b4d94b3f..2ef9cf49 100644
--- a/chromecast/tracing/system_tracing_common.cc
+++ b/chromecast/tracing/system_tracing_common.cc
@@ -6,7 +6,8 @@
 
 #include <string.h>
 
-#include "base/cxx17_backports.h"
+#include <iterator>
+
 #include "base/trace_event/common/trace_event_common.h"
 
 namespace chromecast {
@@ -21,7 +22,7 @@
     "gfx",   "input", TRACE_DISABLED_BY_DEFAULT("irq"),
     "power", "sched", "workq"};
 
-const size_t kCategoryCount = base::size(kCategories);
+const size_t kCategoryCount = std::size(kCategories);
 
 sockaddr_un GetSystemTracingSocketAddress() {
   struct sockaddr_un addr;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 894bed8..6b1f8ba9 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-14531.0.0
\ No newline at end of file
+14534.0.0
\ No newline at end of file
diff --git a/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc b/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc
index d102b9c..697d858d 100644
--- a/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc
+++ b/chromeos/components/cdm_factory_daemon/output_protection_impl_unittest.cc
@@ -75,7 +75,7 @@
         display::DISPLAY_CONNECTION_TYPE_HDMI,
         display::DISPLAY_CONNECTION_TYPE_DISPLAYPORT,
         display::DISPLAY_CONNECTION_TYPE_VGA};
-    for (size_t i = 0; i < base::size(kDisplayIds); ++i) {
+    for (size_t i = 0; i < std::size(kDisplayIds); ++i) {
       displays_[i] = display::FakeDisplaySnapshot::Builder()
                          .SetId(kDisplayIds[i])
                          .SetType(conn_types[i])
@@ -90,7 +90,7 @@
   }
 
   void UpdateDisplays(size_t count) {
-    ASSERT_LE(count, base::size(displays_));
+    ASSERT_LE(count, std::size(displays_));
 
     cached_displays_.clear();
     for (size_t i = 0; i < count; ++i)
@@ -133,7 +133,7 @@
 
   mojo::Remote<OutputProtection> output_protection_mojo_;
   MockDisplaySystemDelegate* delegate_;  // Not owned.
-  std::unique_ptr<display::DisplaySnapshot> displays_[base::size(kDisplayIds)];
+  std::unique_ptr<display::DisplaySnapshot> displays_[std::size(kDisplayIds)];
   std::vector<display::DisplaySnapshot*> cached_displays_;
 
  private:
@@ -198,7 +198,7 @@
       display::CONTENT_PROTECTION_METHOD_HDCP_TYPE_1,
       display::CONTENT_PROTECTION_METHOD_NONE};
 
-  for (size_t i = 0; i < base::size(applied_types); ++i) {
+  for (size_t i = 0; i < std::size(applied_types); ++i) {
     ExpectProtectionCall(kDisplayIds[0], expected_types[i], true);
 
     base::MockCallback<OutputProtection::EnableProtectionCallback>
diff --git a/chromeos/components/string_matching/tokenized_string_match_unittest.cc b/chromeos/components/string_matching/tokenized_string_match_unittest.cc
index a19e8f1..1525879 100644
--- a/chromeos/components/string_matching/tokenized_string_match_unittest.cc
+++ b/chromeos/components/string_matching/tokenized_string_match_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -47,7 +46,7 @@
   };
 
   TokenizedStringMatch match;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const std::u16string text(base::UTF8ToUTF16(kTestCases[i].text));
     EXPECT_FALSE(match.Calculate(base::UTF8ToUTF16(kTestCases[i].query), text))
         << "Test case " << i << " : text=" << kTestCases[i].text
@@ -74,7 +73,7 @@
   };
 
   TokenizedStringMatch match;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const std::u16string text(base::UTF8ToUTF16(kTestCases[i].text));
     EXPECT_TRUE(match.Calculate(base::UTF8ToUTF16(kTestCases[i].query), text));
     EXPECT_EQ(kTestCases[i].expect, MatchHit(text, match));
@@ -106,7 +105,7 @@
 
   TokenizedStringMatch match_low;
   TokenizedStringMatch match_high;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const std::u16string text(base::UTF8ToUTF16(kTestCases[i].text));
     EXPECT_TRUE(
         match_low.Calculate(base::UTF8ToUTF16(kTestCases[i].query_low), text));
@@ -140,7 +139,7 @@
   };
 
   TokenizedStringMatch match;
-  for (size_t i = 0; i < base::size(kTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kTestCases); ++i) {
     const std::u16string text(base::UTF8ToUTF16(kTestCases[i].text));
     EXPECT_TRUE(match.Calculate(base::UTF8ToUTF16(kTestCases[i].query), text));
     EXPECT_NEAR(match.relevance(), kTestCases[i].expected_score, kEpsilon)
diff --git a/chromeos/crosapi/cpp/gurl_os_handler_utils.cc b/chromeos/crosapi/cpp/gurl_os_handler_utils.cc
index 782f25aa..ba14fca 100644
--- a/chromeos/crosapi/cpp/gurl_os_handler_utils.cc
+++ b/chromeos/crosapi/cpp/gurl_os_handler_utils.cc
@@ -63,7 +63,7 @@
     return GURL(gurl);
   }
 
-  url::Replacements<char> replacements;
+  GURL::Replacements replacements;
   if (!include_path)
     replacements.ClearPath();
   replacements.ClearRef();
diff --git a/chromeos/dbus/attestation/attestation_client.h b/chromeos/dbus/attestation/attestation_client.h
index 5f63e64..212e6596 100644
--- a/chromeos/dbus/attestation/attestation_client.h
+++ b/chromeos/dbus/attestation/attestation_client.h
@@ -139,6 +139,9 @@
     virtual void AllowlistSignSimpleChallengeKey(const std::string& username,
                                                  const std::string& label) = 0;
 
+    // Sets the status code returned by `Sign()`.
+    virtual void set_sign_status(::attestation::AttestationStatus status) = 0;
+
     // Sets the status code returned by `RegisterKeyWithChapsToken()`.
     virtual void set_register_key_status(
         ::attestation::AttestationStatus status) = 0;
diff --git a/chromeos/dbus/attestation/fake_attestation_client.cc b/chromeos/dbus/attestation/fake_attestation_client.cc
index e35e052..03578aa 100644
--- a/chromeos/dbus/attestation/fake_attestation_client.cc
+++ b/chromeos/dbus/attestation/fake_attestation_client.cc
@@ -123,7 +123,12 @@
 
 void FakeAttestationClient::Sign(const ::attestation::SignRequest& request,
                                  SignCallback callback) {
-  NOTIMPLEMENTED();
+  ::attestation::SignReply reply;
+  reply.set_status(sign_status_);
+  if (reply.status() == ::attestation::STATUS_SUCCESS) {
+    reply.set_signature(kSignatureSuffix);
+  }
+  PostProtoResponse(std::move(callback), reply);
 }
 
 void FakeAttestationClient::RegisterKeyWithChapsToken(
@@ -459,6 +464,11 @@
   sign_simple_challenge_status_ = status;
 }
 
+void FakeAttestationClient::set_sign_status(
+    ::attestation::AttestationStatus status) {
+  sign_status_ = status;
+}
+
 void FakeAttestationClient::AllowlistSignSimpleChallengeKey(
     const std::string& username,
     const std::string& label) {
diff --git a/chromeos/dbus/attestation/fake_attestation_client.h b/chromeos/dbus/attestation/fake_attestation_client.h
index e2244075..12846070 100644
--- a/chromeos/dbus/attestation/fake_attestation_client.h
+++ b/chromeos/dbus/attestation/fake_attestation_client.h
@@ -123,6 +123,7 @@
       ::attestation::AttestationStatus status) override;
   void AllowlistSignSimpleChallengeKey(const std::string& username,
                                        const std::string& label) override;
+  void set_sign_status(::attestation::AttestationStatus status) override;
   void set_register_key_status(
       ::attestation::AttestationStatus status) override;
   void AllowlistRegisterKey(const std::string& username,
@@ -202,6 +203,8 @@
   // The status returned by `SignSimpleChallenge()`.
   ::attestation::AttestationStatus sign_simple_challenge_status_ =
       ::attestation::STATUS_SUCCESS;
+  // The status returned by `Sign()`.
+  ::attestation::AttestationStatus sign_status_ = ::attestation::STATUS_SUCCESS;
   // The table of username-label pairs of which keys can perform simple sign
   // challenge.
   std::set<std::pair<std::string, std::string>>
diff --git a/chromeos/dbus/shill/shill_third_party_vpn_driver_client.cc b/chromeos/dbus/shill/shill_third_party_vpn_driver_client.cc
index 154d562..f2b1a68 100644
--- a/chromeos/dbus/shill/shill_third_party_vpn_driver_client.cc
+++ b/chromeos/dbus/shill/shill_third_party_vpn_driver_client.cc
@@ -12,7 +12,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/values.h"
 #include "chromeos/dbus/shill/fake_shill_third_party_vpn_driver_client.h"
@@ -136,7 +135,7 @@
 ShillThirdPartyVpnDriverClientImpl::ShillThirdPartyVpnDriverClientImpl(
     dbus::Bus* bus)
     : bus_(bus) {
-  for (uint32_t i = 0; i < base::size(kSetParametersKeyList); ++i) {
+  for (uint32_t i = 0; i < std::size(kSetParametersKeyList); ++i) {
     valid_keys_.insert(kSetParametersKeyList[i]);
   }
 }
diff --git a/chromeos/dbus/update_engine/update_engine_client.cc b/chromeos/dbus/update_engine/update_engine_client.cc
index 28e09d7..0f79ed13 100644
--- a/chromeos/dbus/update_engine/update_engine_client.cc
+++ b/chromeos/dbus/update_engine/update_engine_client.cc
@@ -13,7 +13,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/observer_list.h"
@@ -762,10 +761,10 @@
     const std::string& target_channel) {
   const char** cix = std::find(
       kReleaseChannelsList,
-      kReleaseChannelsList + base::size(kReleaseChannelsList), current_channel);
+      kReleaseChannelsList + std::size(kReleaseChannelsList), current_channel);
   const char** tix = std::find(
       kReleaseChannelsList,
-      kReleaseChannelsList + base::size(kReleaseChannelsList), target_channel);
+      kReleaseChannelsList + std::size(kReleaseChannelsList), target_channel);
   return tix > cix;
 }
 
diff --git a/chromeos/dbus/userdataauth/fake_cryptohome_misc_client.cc b/chromeos/dbus/userdataauth/fake_cryptohome_misc_client.cc
index 11c9110..72724fc 100644
--- a/chromeos/dbus/userdataauth/fake_cryptohome_misc_client.cc
+++ b/chromeos/dbus/userdataauth/fake_cryptohome_misc_client.cc
@@ -4,7 +4,6 @@
 
 #include "chromeos/dbus/userdataauth/fake_cryptohome_misc_client.h"
 
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/notreached.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -151,8 +150,8 @@
 // static
 std::vector<uint8_t> FakeCryptohomeMiscClient::GetStubSystemSalt() {
   const char kStubSystemSalt[] = "stub_system_salt";
-  return std::vector<uint8_t>(
-      kStubSystemSalt, kStubSystemSalt + base::size(kStubSystemSalt) - 1);
+  return std::vector<uint8_t>(kStubSystemSalt,
+                              kStubSystemSalt + std::size(kStubSystemSalt) - 1);
 }
 
 }  // namespace chromeos
diff --git a/chromeos/network/network_device_handler_impl.cc b/chromeos/network/network_device_handler_impl.cc
index 5ef5163..e5a4e0a8 100644
--- a/chromeos/network/network_device_handler_impl.cc
+++ b/chromeos/network/network_device_handler_impl.cc
@@ -14,7 +14,6 @@
 #include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/location.h"
 #include "base/strings/string_util.h"
@@ -140,7 +139,7 @@
       // NetworkConfigurationUpdater.
       shill::kCellularPolicyAllowRoamingProperty};
 
-  for (size_t i = 0; i < base::size(blocked_properties); ++i) {
+  for (size_t i = 0; i < std::size(blocked_properties); ++i) {
     if (property_name == blocked_properties[i]) {
       InvokeErrorCallback(
           device_path, std::move(error_callback),
diff --git a/chromeos/network/network_type_pattern.cc b/chromeos/network/network_type_pattern.cc
index 414b956..d81a73b 100644
--- a/chromeos/network/network_type_pattern.cc
+++ b/chromeos/network/network_type_pattern.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "chromeos/network/network_event_log.h"
 #include "chromeos/network/tether_constants.h"
@@ -43,7 +42,7 @@
                           {kTypeTether, kNetworkTypeTether}};
 
 NetworkTypeBitFlag ShillNetworkTypeToFlag(const std::string& shill_type) {
-  for (size_t i = 0; i < base::size(shill_type_to_flag); ++i) {
+  for (size_t i = 0; i < std::size(shill_type_to_flag); ++i) {
     if (shill_type_to_flag[i].shill_network_type == shill_type)
       return shill_type_to_flag[i].bit_flag;
   }
@@ -157,7 +156,7 @@
 
   // Note: shill_type_to_flag includes kTypeTether.
   std::string str;
-  for (size_t i = 0; i < base::size(shill_type_to_flag); ++i) {
+  for (size_t i = 0; i < std::size(shill_type_to_flag); ++i) {
     if (!(pattern_ & shill_type_to_flag[i].bit_flag))
       continue;
     if (!str.empty())
diff --git a/chromeos/process_proxy/process_output_watcher.cc b/chromeos/process_proxy/process_output_watcher.cc
index 410085d..06be11d 100644
--- a/chromeos/process_proxy/process_output_watcher.cc
+++ b/chromeos/process_proxy/process_output_watcher.cc
@@ -10,8 +10,8 @@
 #include <algorithm>
 #include <cstdio>
 #include <cstring>
+
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
@@ -58,7 +58,7 @@
       on_read_callback_(callback) {
   CHECK_GE(out_fd, 0);
   // We want to be sure we will be able to add 0 at the end of the input, so -1.
-  read_buffer_capacity_ = base::size(read_buffer_) - 1;
+  read_buffer_capacity_ = std::size(read_buffer_) - 1;
 }
 
 ProcessOutputWatcher::~ProcessOutputWatcher() = default;
diff --git a/chromeos/process_proxy/process_proxy_unittest.cc b/chromeos/process_proxy/process_proxy_unittest.cc
index 178bdf98..5d3aa28 100644
--- a/chromeos/process_proxy/process_proxy_unittest.cc
+++ b/chromeos/process_proxy/process_proxy_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/at_exit.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/process/kill.h"
 #include "base/process/process.h"
@@ -117,7 +116,7 @@
 
  private:
   bool ProcessReceivedCharacter(char received, size_t stream) {
-    if (stream >= base::size(left_to_check_index_))
+    if (stream >= std::size(left_to_check_index_))
       return false;
     bool success = left_to_check_index_[stream] < expected_line_.length() &&
         expected_line_[left_to_check_index_[stream]] == received;
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 60e752a6..4b54ef9 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-100-4880.0-1645442860-benchmark-100.0.4896.13-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-100-4880.0-1645442860-benchmark-100.0.4896.14-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index e5ccefc..d392b26 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-100-4880.0-1645439876-benchmark-100.0.4896.13-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-100-4880.0-1645439876-benchmark-100.0.4896.14-r1-redacted.afdo.xz
diff --git a/chromeos/services/device_sync/cryptauth_feature_type.cc b/chromeos/services/device_sync/cryptauth_feature_type.cc
index ad6348bd..d219e3e 100644
--- a/chromeos/services/device_sync/cryptauth_feature_type.cc
+++ b/chromeos/services/device_sync/cryptauth_feature_type.cc
@@ -342,7 +342,7 @@
 std::string CryptAuthFeatureTypeToGcmHash(CryptAuthFeatureType feature_type) {
   std::string hash_8_bytes(8, 0);
   crypto::SHA256HashString(CryptAuthFeatureTypeToString(feature_type),
-                           base::data(hash_8_bytes), 8u);
+                           std::data(hash_8_bytes), 8u);
 
   std::string hash_base64url;
   base::Base64UrlEncode(hash_8_bytes, base::Base64UrlEncodePolicy::OMIT_PADDING,
diff --git a/chromeos/system/name_value_pairs_parser_unittest.cc b/chromeos/system/name_value_pairs_parser_unittest.cc
index 20a5b50..3620f8cf 100644
--- a/chromeos/system/name_value_pairs_parser_unittest.cc
+++ b/chromeos/system/name_value_pairs_parser_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "chromeos/system/name_value_pairs_parser.h"
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -157,7 +156,7 @@
 
   NameValuePairsParser::NameValueMap map;
   NameValuePairsParser parser(&map);
-  parser.ParseNameValuePairsFromTool(base::size(command), command,
+  parser.ParseNameValuePairsFromTool(std::size(command), command,
                                      NameValuePairsFormat::kCrossystem);
   EXPECT_EQ(7u, map.size());
   EXPECT_EQ("x86", map["arch"]);
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc
index 3c8c5b4..2dde521 100644
--- a/chromeos/system/statistics_provider.cc
+++ b/chromeos/system/statistics_provider.cc
@@ -12,7 +12,6 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
@@ -508,7 +507,7 @@
   if (base::SysInfo::IsRunningOnChromeOS()) {
     // Parse all of the key/value pairs from the crossystem tool.
     if (!parser.ParseNameValuePairsFromTool(
-            base::size(kCrosSystemTool), kCrosSystemTool,
+            std::size(kCrosSystemTool), kCrosSystemTool,
             NameValuePairsFormat::kCrossystem)) {
       LOG(ERROR) << "Errors parsing output from: " << kCrosSystemTool;
     }
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index 4f296f2..81f7e99 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -60,9 +60,6 @@
   # crbug.com/1257474
   "shelf.OpenCloseSwitchApps",
 
-  # crbug.com/1239838
-  "graphics.FPS",
-
   # crbug.com/1186991
   "launcher.SearchBuiltInApps",
 
diff --git a/chromeos/tools/onc_validator/onc_validator.cc b/chromeos/tools/onc_validator/onc_validator.cc
index 3a400d09..91454b6 100644
--- a/chromeos/tools/onc_validator/onc_validator.cc
+++ b/chromeos/tools/onc_validator/onc_validator.cc
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 #include <stddef.h>
+
 #include <cstdio>
 #include <iostream>
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/json/json_reader.h"
@@ -63,13 +63,13 @@
           "  onc_validator [OPTION]... [TYPE] onc_file\n"
           "\n"
           "Valid TYPEs are:\n");
-  for (size_t i = 0; i < base::size(kTypes); ++i)
+  for (size_t i = 0; i < std::size(kTypes); ++i)
     fprintf(stderr, "  %s\n", kTypes[i]);
 
   fprintf(stderr,
           "\n"
           "Valid OPTIONs are:\n");
-  for (size_t i = 0; i < base::size(kSwitches); ++i)
+  for (size_t i = 0; i < std::size(kSwitches); ++i)
     fprintf(stderr, "  --%s\n", kSwitches[i]);
 
   fprintf(stderr,
diff --git a/chromeos/tpm/install_attributes.cc b/chromeos/tpm/install_attributes.cc
index 6a6dadc..63985d741 100644
--- a/chromeos/tpm/install_attributes.cc
+++ b/chromeos/tpm/install_attributes.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -209,7 +208,7 @@
         kAttrConsumerKioskEnabled,
     };
     std::map<std::string, std::string> attr_map;
-    for (size_t i = 0; i < base::size(kEnterpriseAttributes); ++i) {
+    for (size_t i = 0; i < std::size(kEnterpriseAttributes); ++i) {
       std::string value;
       if (install_attributes_util::InstallAttributesGet(
               kEnterpriseAttributes[i], &value))
diff --git a/chromeos/tpm/tpm_token_info_getter_unittest.cc b/chromeos/tpm/tpm_token_info_getter_unittest.cc
index b584176..167611c 100644
--- a/chromeos/tpm/tpm_token_info_getter_unittest.cc
+++ b/chromeos/tpm/tpm_token_info_getter_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chromeos/tpm/tpm_token_info_getter.h"
+
 #include <stdint.h>
 
 #include <memory>
@@ -11,7 +13,6 @@
 
 #include "ash/components/cryptohome/cryptohome_parameters.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_runner.h"
@@ -21,7 +22,6 @@
 #include "chromeos/dbus/tpm_manager/tpm_manager_client.h"
 #include "chromeos/dbus/userdataauth/cryptohome_pkcs11_client.h"
 #include "chromeos/dbus/userdataauth/fake_cryptohome_pkcs11_client.h"
-#include "chromeos/tpm/tpm_token_info_getter.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -398,7 +398,7 @@
 
   const int64_t kExpectedDelays[] = {100};
   EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -426,7 +426,7 @@
 
   const int64_t kExpectedDelays[] = {100};
   EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -454,7 +454,7 @@
 
   const int64_t kExpectedDelays[] = {100};
   EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -486,7 +486,7 @@
 
   int64_t kExpectedDelays[] = {100, 200, 400, 800, 1600, 3200};
   ASSERT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -521,7 +521,7 @@
                                3200,   6400,   12800,  25600,  51200,
                                102400, 204800, 300000, 300000, 300000};
   ASSERT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -574,7 +574,7 @@
 
   const int64_t kExpectedDelays[] = {100};
   EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
@@ -603,7 +603,7 @@
 
   const int64_t kExpectedDelays[] = {100};
   EXPECT_EQ(std::vector<int64_t>(kExpectedDelays,
-                                 kExpectedDelays + base::size(kExpectedDelays)),
+                                 kExpectedDelays + std::size(kExpectedDelays)),
             delays_);
 }
 
diff --git a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc
index 9c76b62..26707af6 100644
--- a/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc
+++ b/chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.cc
@@ -218,7 +218,7 @@
 
   views::FrameCaptionButton* buttons[] = {menu_button_, minimize_button_,
                                           size_button_, close_button_};
-  for (size_t i = 0; i < base::size(buttons); ++i) {
+  for (size_t i = 0; i < std::size(buttons); ++i) {
     if (buttons[i]->GetIcon() == icon)
       buttons[i]->SetImage(icon, views::FrameCaptionButton::Animate::kNo,
                            icon_definition);
@@ -533,7 +533,7 @@
                                           close_button_};
   int min_squared_distance = INT_MAX;
   views::FrameCaptionButton* closest_button = nullptr;
-  for (size_t i = 0; i < base::size(buttons); ++i) {
+  for (size_t i = 0; i < std::size(buttons); ++i) {
     views::FrameCaptionButton* button = buttons[i];
     if (!button || !button->GetVisible())
       continue;
@@ -557,7 +557,7 @@
   views::FrameCaptionButton* buttons[] = {custom_button_, menu_button_,
                                           minimize_button_, size_button_,
                                           close_button_};
-  for (size_t i = 0; i < base::size(buttons); ++i) {
+  for (size_t i = 0; i < std::size(buttons); ++i) {
     views::FrameCaptionButton* button = buttons[i];
     if (!button)
       continue;
diff --git a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/AssistantTextUtils.java b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/AssistantTextUtils.java
index 92793a6..a24cb83e 100644
--- a/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/AssistantTextUtils.java
+++ b/components/autofill_assistant/android/java/src/org/chromium/components/autofill_assistant/AssistantTextUtils.java
@@ -64,7 +64,7 @@
 
         for (Integer linkId : linkIds) {
             spans.add(new SpanApplier.SpanInfo("<link" + linkId + ">", "</link" + linkId + ">",
-                    new NoUnderlineClickableSpan(view.getContext().getResources(), (unusedView) -> {
+                    new NoUnderlineClickableSpan(view.getContext(), (unusedView) -> {
                         if (linkCallback != null) {
                             linkCallback.onResult(linkId);
                         }
diff --git a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
index 9d34079..cbf88658 100644
--- a/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
+++ b/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java
@@ -12,6 +12,7 @@
  */
 public abstract class BackgroundTaskSchedulerExternalUma {
     // BackgroundTaskId defined in tools/metrics/histograms/enums.xml
+    public static final int BACKGROUND_TASK_NOT_FOUND = -1;
     public static final int BACKGROUND_TASK_TEST = 0;
     public static final int BACKGROUND_TASK_OMAHA = 1;
     public static final int BACKGROUND_TASK_GCM = 2;
@@ -140,10 +141,8 @@
                 return BACKGROUND_TASK_WEBVIEW_COMPONENT_UPDATE;
             case TaskIds.ATTRIBUTION_PROVIDER_FLUSH_JOB_ID:
                 return BACKGROUND_TASK_ATTRIBUTION_PROVIDER_FLUSH;
-            default:
-                assert false;
         }
         // Returning a value that is not expected to ever be reported.
-        return BACKGROUND_TASK_TEST;
+        return BACKGROUND_TASK_NOT_FOUND;
     }
 }
diff --git a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
index 0d5fd481..8fcbca5 100644
--- a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
+++ b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUmaTest.java
@@ -54,6 +54,10 @@
     @Test
     @Feature({"BackgroundTaskScheduler"})
     public void testToUmaEnumValueFromTaskId() {
+        // Special case - using Integer.MAX_VALUE as a "not found" task id.
+        assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_NOT_FOUND,
+                BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(Integer.MAX_VALUE));
+
         assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_TEST,
                 BackgroundTaskSchedulerUma.toUmaEnumValueFromTaskId(TaskIds.TEST));
         assertEquals(BackgroundTaskSchedulerUma.BACKGROUND_TASK_OMAHA,
diff --git a/components/cronet/PRESUBMIT.py b/components/cronet/PRESUBMIT.py
index 73be027c..62f1fc47 100644
--- a/components/cronet/PRESUBMIT.py
+++ b/components/cronet/PRESUBMIT.py
@@ -15,8 +15,7 @@
 
 def _PyLintChecks(input_api, output_api):
   pylint_checks = input_api.canned_checks.GetPylint(input_api, output_api,
-          extra_paths_list=_GetPathsToPrepend(input_api), pylintrc='pylintrc',
-          version='2.6')
+          extra_paths_list=_GetPathsToPrepend(input_api), pylintrc='pylintrc')
   return input_api.RunTests(pylint_checks)
 
 
@@ -73,7 +72,8 @@
         'API classes must be in org.chromium.net package, and implementation\n'
         'classes must not be in org.chromium.net package.',
         problems)]
-  return []
+  else:
+    return []
 
 
 def _RunToolsUnittests(input_api, output_api):
@@ -81,8 +81,7 @@
       input_api, output_api,
       '.',
       [ r'^tools_unittest\.py$'],
-      run_on_python3=True,
-      skip_shebang_check = True)
+      run_on_python3=True)
 
 
 def _ChangeAffectsCronetTools(change):
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 07a46d5..2bf6afd8 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -95,10 +95,11 @@
   }
 }
 
-_generated_api_version_java = "$_templates_dir/org/chromium/net/ApiVersion.java"
-_api_level = read_file("api_version.txt", "value")
+_generated_interface_api_version_java =
+    "$_templates_dir/org/chromium/net/ApiVersion.java"
+_interface_api_level = read_file("interface_api_version.txt", "value")
 
-process_version("api_version") {
+process_version("interface_api_version") {
   process_only = true
   template_file = "api/src/org/chromium/net/ApiVersion.template"
   sources = [
@@ -107,15 +108,16 @@
   ]
   extra_args = [
     "-e",
-    "API_LEVEL=$_api_level",
+    "API_LEVEL=$_interface_api_level",
   ]
-  output = _generated_api_version_java
+  output = _generated_interface_api_version_java
 }
 
-_generated_impl_version_java =
+_generated_implementation_api_version_java =
     "$_templates_dir/org/chromium/net/impl/ImplVersion.java"
+_implementation_api_level = read_file("implementation_api_version.txt", "value")
 
-process_version("impl_version") {
+process_version("implementation_api_version") {
   process_only = true
   template_file = "java/src/org/chromium/net/impl/ImplVersion.template"
   sources = [
@@ -124,9 +126,9 @@
   ]
   extra_args = [
     "-e",
-    "API_LEVEL=$_api_level",
+    "API_LEVEL=$_implementation_api_level",
   ]
-  output = _generated_impl_version_java
+  output = _generated_implementation_api_version_java
 }
 
 _cronet_version_header_include_dir = "$target_gen_dir/cronet_version_header"
@@ -244,11 +246,11 @@
     "api/src/org/chromium/net/UploadDataSink.java",
     "api/src/org/chromium/net/UrlRequest.java",
     "api/src/org/chromium/net/UrlResponseInfo.java",
-    _generated_api_version_java,
+    _generated_interface_api_version_java,
   ]
 
   deps = [
-    ":api_version",
+    ":interface_api_version",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
 }
@@ -281,14 +283,14 @@
     "java/src/org/chromium/net/impl/UrlResponseInfoImpl.java",
     "java/src/org/chromium/net/impl/UserAgent.java",
     "java/src/org/chromium/net/impl/VersionSafeCallbacks.java",
-    _generated_impl_version_java,
+    _generated_implementation_api_version_java,
   ]
 
   # Adding deps here won't include those deps in the cronet_impl_common_java.jar.
   # Please add to cronet_impl_common_java_deps_to_package instead.
   deps = [
     ":cronet_api_java",
-    ":impl_version",
+    ":implementation_api_version",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
   deps += cronet_impl_common_java_deps_to_package
@@ -1363,10 +1365,11 @@
       "$target_gen_dir/cronet_impl_native_proguard.cfg",
       "//AUTHORS",
       "//chrome/VERSION",
-      "api_version.txt",
       "cronet_impl_common_proguard.cfg",
       "cronet_impl_fake_proguard.cfg",
       "cronet_impl_platform_proguard.cfg",
+      "implementation_api_version.txt",
+      "interface_api_version.txt",
     ]
     outputs = [ "$_package_dir/{{source_file_part}}" ]
 
@@ -1522,7 +1525,7 @@
     ]
     sources = [
       "//components/cronet/android/api.txt",
-      "//components/cronet/android/api_version.txt",
+      "//components/cronet/android/interface_api_version.txt",
     ]
   }
 
diff --git a/components/cronet/android/api_version.txt b/components/cronet/android/implementation_api_version.txt
similarity index 100%
copy from components/cronet/android/api_version.txt
copy to components/cronet/android/implementation_api_version.txt
diff --git a/components/cronet/android/api_version.txt b/components/cronet/android/interface_api_version.txt
similarity index 100%
rename from components/cronet/android/api_version.txt
rename to components/cronet/android/interface_api_version.txt
diff --git a/components/cronet/android/test/javaperftests/run.py b/components/cronet/android/test/javaperftests/run.py
index 2e5959ea..bbbace4 100755
--- a/components/cronet/android/test/javaperftests/run.py
+++ b/components/cronet/android/test/javaperftests/run.py
@@ -41,7 +41,7 @@
 """
 
 import json
-import argparse
+import optparse
 import os
 import shutil
 import sys
@@ -98,14 +98,14 @@
         data=self.url,
         extras=None,
         category=None)
-    super().__init__(
+    super(CronetPerfTestAndroidStory, self).__init__(
         start_intent, name='CronetPerfTest',
         # No reason to wait for app; Run() will wait for results.  By default
         # StartActivity will timeout waiting for CronetPerfTest, so override
         # |is_app_ready_predicate| to not wait.
         is_app_ready_predicate=lambda app: True)
 
-  def Run(self, shared_state):
+  def Run(self, shared_user_story_state):
     while not self._device.FileExists(
         perf_test_utils.GetConfig(self._device)['DONE_FILE']):
       time.sleep(1.0)
@@ -114,7 +114,7 @@
 class CronetPerfTestStorySet(story_module.StorySet):
 
   def __init__(self, device):
-    super().__init__()
+    super(CronetPerfTestStorySet, self).__init__()
     # Create and add Cronet perf test AndroidStory.
     self.AddStory(CronetPerfTestAndroidStory(device))
 
@@ -126,7 +126,7 @@
   # Cronet perf test app.
 
   def __init__(self, device, options):
-    super().__init__(options)
+    super(CronetPerfTestMeasurement, self).__init__(options)
     self._device = device
 
   def WillRunStory(self, platform, story=None):
@@ -153,7 +153,7 @@
   SUPPORTED_PLATFORMS = [story_module.expectations.ALL_ANDROID]
 
   def __init__(self, max_failures=None):
-    super().__init__(max_failures)
+    super(CronetPerfTestBenchmark, self).__init__(max_failures)
     self._device = GetDevice()
 
   def CreatePageTest(self, options):
@@ -164,13 +164,13 @@
 
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--output-format', default='html',
+  parser = optparse.OptionParser()
+  parser.add_option('--output-format', default='html',
                    help='The output format of the results file.')
-  parser.add_argument('--output-dir', default=None,
+  parser.add_option('--output-dir', default=None,
                    help='The directory for the output file. Default value is '
                         'the base directory of this script.')
-  args, _ = parser.parse_known_args()
+  options, _ = parser.parse_args()
   constants.SetBuildType(perf_test_utils.BUILD_TYPE)
   # Install APK
   device = GetDevice()
@@ -206,9 +206,9 @@
   sys.argv.insert(1, 'run')
   sys.argv.insert(2, 'run.CronetPerfTestBenchmark')
   sys.argv.insert(3, '--browser=android-system-chrome')
-  sys.argv.insert(4, '--output-format=' + args.output_format)
-  if args.output_dir:
-    sys.argv.insert(5, '--output-dir=' + args.output_dir)
+  sys.argv.insert(4, '--output-format=' + options.output_format)
+  if options.output_dir:
+    sys.argv.insert(5, '--output-dir=' + options.output_dir)
   benchmark_runner.main(runner_config)
   # Shutdown.
   quic_server.ShutdownQuicServer()
diff --git a/components/cronet/tools/android_rndis_forwarder.py b/components/cronet/tools/android_rndis_forwarder.py
index 2d3d0b3..4eff5da 100644
--- a/components/cronet/tools/android_rndis_forwarder.py
+++ b/components/cronet/tools/android_rndis_forwarder.py
@@ -11,13 +11,13 @@
 import subprocess
 import sys
 
-# pylint: disable=wrong-import-position
 REPOSITORY_ROOT = os.path.abspath(os.path.join(
     os.path.dirname(__file__), '..', '..', '..'))
 sys.path.append(os.path.join(REPOSITORY_ROOT, 'tools', 'perf'))
-from core import path_util
+from core import path_util  # pylint: disable=wrong-import-position
 sys.path.append(path_util.GetTelemetryDir())
 
+# pylint: disable=wrong-import-position
 from telemetry.core import platform
 from telemetry.internal.platform import android_device
 from telemetry.internal.util import binary_manager
@@ -29,7 +29,7 @@
 # pylint: enable=wrong-import-position
 
 
-class AndroidRndisForwarder():
+class AndroidRndisForwarder(object):
   """Forwards traffic using RNDIS. Assumes the device has root access."""
 
   def __init__(self, device, rndis_configurator):
@@ -129,7 +129,7 @@
         ['netcfg', self._device_iface, 'down'], check_return=True)
 
 
-class AndroidRndisConfigurator():
+class AndroidRndisConfigurator(object):
   """Configures a linux host to connect to an android device via RNDIS.
 
   Note that we intentionally leave RNDIS running on the device. This is
@@ -171,7 +171,6 @@
     """Checks that the device has RNDIS support in the kernel."""
     return self._device.FileExists('%s/f_rndis/device' % self._RNDIS_DEVICE)
 
-  # pylint: disable=inconsistent-return-statements
   def _FindDeviceRndisInterface(self):
     """Returns the name of the RNDIS network interface if present."""
     config = self._device.RunShellCommand(
@@ -185,7 +184,6 @@
         return candidates[0]
       assert len(candidates) == 1, 'Found more than one rndis device!'
       return candidates[0]
-  # pylint: enable=inconsistent-return-statements
 
   def _FindDeviceRndisMacAddress(self, interface):
     """Returns the MAC address of the RNDIS network interface if present."""
@@ -201,7 +199,6 @@
       return subprocess.check_output(['ifconfig']).splitlines()
     raise NotImplementedError('Platform %s not supported!' % host_platform)
 
-  # pylint: disable=inconsistent-return-statements
   def _FindHostRndisInterface(self, device_mac_address):
     """Returns the name of the host-side network interface."""
     interface_list = self._EnumerateHostInterfaces()
@@ -227,7 +224,6 @@
       # but just going by the host interface name seems safe enough.
       elif interface_name == 'usb0':
         return interface_name
-  # pylint: enable=inconsistent-return-statements
 
   def _WriteProtectedFile(self, file_path, contents):
     subprocess.check_call(
@@ -407,14 +403,12 @@
     def _IsNetworkUnique(network, addresses):
       return all((addr & mask != network & mask) for addr, mask in addresses)
 
-    # pylint: disable=inconsistent-return-statements
     def _NextUnusedAddress(network, netmask, used_addresses):
       # Excludes '0' and broadcast.
       for suffix in range(1, 0xFFFFFFFF & ~netmask):
         candidate = network | suffix
         if candidate not in used_addresses:
           return candidate
-    # pylint: enable=inconsistent-return-statements
 
     def HasHostAddress():
       _, host_address = self._GetHostAddresses(host_iface)
diff --git a/components/cronet/tools/api_static_checks.py b/components/cronet/tools/api_static_checks.py
index 5c8bc77..06fc30c 100755
--- a/components/cronet/tools/api_static_checks.py
+++ b/components/cronet/tools/api_static_checks.py
@@ -79,6 +79,14 @@
     'org/chromium/net/NetworkException/getMessage:()Ljava/lang/String;',
 ]
 
+# Filename of file containing the interface API version number.
+INTERFACE_API_VERSION_FILENAME = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '..', 'android', 'interface_api_version.txt'))
+# Filename of file containing the implementation API version number.
+IMPLEMENTATION_API_VERSION_FILENAME = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '..', 'android',
+    'implementation_api_version.txt'))
+
 
 def find_api_calls(dump, api_classes, bad_calls):
   # Given a dump of an implementation class, find calls through API classes.
@@ -175,12 +183,30 @@
 
 
 def check_api_version(opts):
-  if update_api.check_up_to_date(opts.api_jar):
-    return True
-  print('ERROR: API file out of date.  Please run this command:')
-  print('       components/cronet/tools/update_api.py --api_jar %s' % (
-      os.path.abspath(opts.api_jar)))
-  return False
+  if not update_api.check_up_to_date(opts.api_jar):
+    print('ERROR: API file out of date.  Please run this command:')
+    print('       components/cronet/tools/update_api.py --api_jar %s' % (
+        os.path.abspath(opts.api_jar)))
+    return False
+  interface_api_version = None
+  implementation_api_version = None
+  with open(INTERFACE_API_VERSION_FILENAME, 'r') \
+       as interface_api_version_file:
+    interface_api_version = int(interface_api_version_file.read())
+  with open(IMPLEMENTATION_API_VERSION_FILENAME, 'r') \
+       as implementation_api_version_file:
+    implementation_api_version = int(implementation_api_version_file.read())
+  if interface_api_version > implementation_api_version:
+    print('ERROR: Interface API version cannot be higher than the current '
+          'implementation API version.')
+    return False
+  if (implementation_api_version != interface_api_version + 1
+      and implementation_api_version != interface_api_version):
+    print('ERROR: Implementation API version can be preemptively bumped up '
+          'at most once. Land the interface part of the API which is already '
+          'being released before adding a new one.')
+    return False
+  return True
 
 
 def main(args):
diff --git a/components/cronet/tools/api_static_checks_unittest.py b/components/cronet/tools/api_static_checks_unittest.py
index 4f44e39..f714fbc 100755
--- a/components/cronet/tools/api_static_checks_unittest.py
+++ b/components/cronet/tools/api_static_checks_unittest.py
@@ -49,7 +49,7 @@
 
 
 API_FILENAME = './android/api.txt'
-API_VERSION_FILENAME = './android/api_version.txt'
+INTERFACE_API_VERSION_FILENAME = './android/interface_api_version.txt'
 
 
 @contextlib.contextmanager
@@ -72,8 +72,9 @@
     self.temp_dir = tempfile.mkdtemp()
     os.chdir(self.temp_dir)
     os.mkdir('android')
-    with open(API_VERSION_FILENAME, 'w') as api_version_file:
-      api_version_file.write('0')
+    with open(INTERFACE_API_VERSION_FILENAME, 'w') \
+         as interface_api_version_file:
+      interface_api_version_file.write('0')
     with open(API_FILENAME, 'w') as api_file:
       api_file.write('}\nStamp: 7d9d25f71cb8a5aba86202540a20d405\n')
     shutil.copytree(os.path.dirname(__file__), 'tools')
@@ -102,7 +103,7 @@
 
   def run_check_api_calls(self, api_java, impl_java):
     test = self
-    class MockOpts():
+    class MockOpts(object):
       def __init__(self):
         self.api_jar = test.make_jar(api_java, 'Api')
         self.impl_jar = [test.make_jar(impl_java, 'Impl')]
@@ -138,8 +139,9 @@
         (self.make_jar(java, 'Api'), OUT_FILENAME))
     with open(API_FILENAME, 'r') as api_file:
       api = api_file.read()
-    with open(API_VERSION_FILENAME, 'r') as api_version_file:
-      api_version = api_version_file.read()
+    with open(INTERFACE_API_VERSION_FILENAME, 'r') \
+         as interface_api_version_file:
+      interface_api_version = interface_api_version_file.read()
     with open(OUT_FILENAME, 'r') as out_file:
       output = out_file.read()
 
@@ -148,10 +150,10 @@
     stamp_length = len('Stamp: 78418460c193047980ae9eabb79293f2\n')
     api = api[:-stamp_length]
     api_hash = hashlib.md5()
-    api_hash.update(api.encode())
+    api_hash.update(api)
     self.assertEqual(api_stamp, 'Stamp: %s' % api_hash.hexdigest())
 
-    return [return_code == 0, output, api, api_version]
+    return [return_code == 0, output, api, interface_api_version]
 
 
   def test_update_api_success(self):
diff --git a/components/cronet/tools/generate_accept_languages.py b/components/cronet/tools/generate_accept_languages.py
index beb4170..2db0a44 100644
--- a/components/cronet/tools/generate_accept_languages.py
+++ b/components/cronet/tools/generate_accept_languages.py
@@ -13,6 +13,7 @@
 #   * assumes that there is only one relevant element with the
 #     IDS_ACCEPT_LANGUAGES attribute
 
+from __future__ import print_function
 
 import os
 import re
@@ -21,13 +22,11 @@
 
 STRINGS_DIR = sys.argv[2] + 'components/strings/'
 
-# pylint: disable=inconsistent-return-statements
 def extract_accept_langs(filename):
   tree = ElementTree.parse(STRINGS_DIR + filename).getroot()
   for child in tree:
     if child.get('id') == 'IDS_ACCEPT_LANGUAGES':
       return tree.get('lang'), child.text
-# pylint: enable=inconsistent-return-statements
 
 def gen_accept_langs_table():
   accept_langs_list = [extract_accept_langs(filename)
diff --git a/components/cronet/tools/generate_idl_bindings.py b/components/cronet/tools/generate_idl_bindings.py
index fcaeec45..93599da2 100755
--- a/components/cronet/tools/generate_idl_bindings.py
+++ b/components/cronet/tools/generate_idl_bindings.py
@@ -4,7 +4,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import argparse
+import optparse
 import os
 import shutil
 import sys
@@ -36,12 +36,12 @@
 
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--output-path',
+  parser = optparse.OptionParser()
+  parser.add_option('--output-path',
         help='Output path for generated bindings')
 
-  args, input_files = parser.parse_known_args()
-  GenerateIdlBindings(args.output_path, input_files)
+  options, input_files = parser.parse_args()
+  GenerateIdlBindings(options.output_path, input_files)
 
 
 if __name__ == '__main__':
diff --git a/components/cronet/tools/generate_javadoc.py b/components/cronet/tools/generate_javadoc.py
index 0a6843f..cc878ca 100755
--- a/components/cronet/tools/generate_javadoc.py
+++ b/components/cronet/tools/generate_javadoc.py
@@ -4,7 +4,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import argparse
+import optparse
 import os
 import shutil
 import sys
@@ -45,11 +45,11 @@
                           CronetPostprocessor(md), '_end')
 
 
-def GenerateJavadoc(args, src_dir, output_dir):
-  working_dir = os.path.join(args.input_dir, 'android', 'api')
-  overview_file = os.path.abspath(args.overview_file)
+def GenerateJavadoc(options, src_dir, output_dir):
+  working_dir = os.path.join(options.input_dir, 'android', 'api')
+  overview_file = os.path.abspath(options.overview_file)
 
-  android_sdk_jar = args.android_sdk_jar
+  android_sdk_jar = options.android_sdk_jar
   if not android_sdk_jar:
     android_sdk_jar = os.path.join(
         SDK_DIR, 'platforms', 'android-27', 'android.jar')
@@ -70,7 +70,7 @@
     '-federationapi', 'Android', os.path.join(DOCLAVA_DIR, 'current.txt'),
     '-classpath',
     '%s:%s' % (os.path.abspath(android_sdk_jar),
-               os.path.abspath(args.support_annotations_jar)),
+               os.path.abspath(options.support_annotations_jar)),
   ]
   for subdir, _, files in os.walk(src_dir):
     for filename in files:
@@ -96,44 +96,44 @@
 
 
 def main():
-  parser = argparse.ArgumentParser()
+  parser = optparse.OptionParser()
   build_utils.AddDepfileOption(parser)
-  parser.add_argument('--output-dir', help='Directory to put javadoc')
-  parser.add_argument('--input-dir', help='Root of cronet source')
-  parser.add_argument('--input-src-jar', help='Cronet api source jar')
-  parser.add_argument('--overview-file', help='Path of the overview page')
-  parser.add_argument('--readme-file', help='Path of the README.md')
-  parser.add_argument('--zip-file', help='Path to ZIP archive of javadocs.')
-  parser.add_argument('--android-sdk-jar', help='Path to android.jar')
-  parser.add_argument('--support-annotations-jar',
+  parser.add_option('--output-dir', help='Directory to put javadoc')
+  parser.add_option('--input-dir', help='Root of cronet source')
+  parser.add_option('--input-src-jar', help='Cronet api source jar')
+  parser.add_option('--overview-file', help='Path of the overview page')
+  parser.add_option('--readme-file', help='Path of the README.md')
+  parser.add_option('--zip-file', help='Path to ZIP archive of javadocs.')
+  parser.add_option('--android-sdk-jar', help='Path to android.jar')
+  parser.add_option('--support-annotations-jar',
                     help='Path to support-annotations-$VERSION.jar')
 
-  args, _ = parser.parse_known_args()
+  options, _ = parser.parse_args()
   # A temporary directory to put the output of cronet api source jar files.
-  unzipped_jar_path = tempfile.mkdtemp(dir=args.output_dir)
-  if os.path.exists(args.input_src_jar):
-    jar_cmd = ['jar', 'xf', os.path.abspath(args.input_src_jar)]
+  unzipped_jar_path = tempfile.mkdtemp(dir=options.output_dir)
+  if os.path.exists(options.input_src_jar):
+    jar_cmd = ['jar', 'xf', os.path.abspath(options.input_src_jar)]
     build_utils.CheckOutput(jar_cmd, cwd=unzipped_jar_path)
   else:
-    raise Exception('Jar file does not exist: %s' % args.input_src_jar)
+    raise Exception('Jar file does not exist: %s' % options.input_src_jar)
 
-  net_docs.ProcessDocs([args.readme_file], args.input_dir,
-                       args.output_dir, extensions=[CronetExtension()])
+  net_docs.ProcessDocs([options.readme_file], options.input_dir,
+                       options.output_dir, extensions=[CronetExtension()])
 
-  output_dir = os.path.abspath(os.path.join(args.output_dir, 'javadoc'))
-  GenerateJavadoc(args, os.path.abspath(unzipped_jar_path), output_dir)
+  output_dir = os.path.abspath(os.path.join(options.output_dir, 'javadoc'))
+  GenerateJavadoc(options, os.path.abspath(unzipped_jar_path), output_dir)
 
-  if args.zip_file:
-    assert args.zip_file.endswith('.zip')
-    shutil.make_archive(args.zip_file[:-4], 'zip', output_dir)
-  if args.depfile:
-    assert args.zip_file
+  if options.zip_file:
+    assert options.zip_file.endswith('.zip')
+    shutil.make_archive(options.zip_file[:-4], 'zip', output_dir)
+  if options.depfile:
+    assert options.zip_file
     deps = []
-    for root, _, filenames in os.walk(args.input_dir):
+    for root, _, filenames in os.walk(options.input_dir):
       # Ignore .pyc files here, it might be re-generated during build.
       deps.extend(os.path.join(root, f) for f in filenames
                   if not f.endswith('.pyc'))
-    build_utils.WriteDepfile(args.depfile, args.zip_file, deps)
+    build_utils.WriteDepfile(options.depfile, options.zip_file, deps)
   # Clean up temporary output directory.
   build_utils.DeleteDirectory(unzipped_jar_path)
 
diff --git a/components/cronet/tools/generate_proguard_file.py b/components/cronet/tools/generate_proguard_file.py
index dcb8ad8..8ff42cf 100755
--- a/components/cronet/tools/generate_proguard_file.py
+++ b/components/cronet/tools/generate_proguard_file.py
@@ -10,7 +10,7 @@
 # The final output file is formed by concatenating all of the
 # input proguard files.
 
-import argparse
+import optparse
 import sys
 
 
@@ -20,14 +20,14 @@
 
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--output-file',
+  parser = optparse.OptionParser()
+  parser.add_option('--output-file',
           help='Output file for the generated proguard file')
 
-  args, input_files = parser.parse_known_args()
+  options, input_files = parser.parse_args()
 
   # Concatenate all the proguard files.
-  with open(args.output_file, 'wb') as target:
+  with open(options.output_file, 'wb') as target:
     for input_file in input_files:
       target.write(ReadFile(input_file))
 
diff --git a/components/cronet/tools/generators/cronet_bindings_generator.py b/components/cronet/tools/generators/cronet_bindings_generator.py
index e3af8a5d4..9e880c5 100755
--- a/components/cronet/tools/generators/cronet_bindings_generator.py
+++ b/components/cronet/tools/generators/cronet_bindings_generator.py
@@ -79,7 +79,7 @@
                     zip(imported_filename_stack[1:], imported_filename_stack)]))
 
 
-class RelativePath():
+class RelativePath(object):
   """Represents a path relative to the source tree."""
   def __init__(self, path, source_root):
     self.path = path
@@ -139,7 +139,7 @@
     return f.read()
 
 
-class MojomProcessor():
+class MojomProcessor(object):
   """Parses mojom files and creates ASTs for them.
 
   Attributes:
diff --git a/components/cronet/tools/generators/cronet_c_generator.py b/components/cronet/tools/generators/cronet_c_generator.py
index 01ce499..3c80f08 100644
--- a/components/cronet/tools/generators/cronet_c_generator.py
+++ b/components/cronet/tools/generators/cronet_c_generator.py
@@ -40,7 +40,7 @@
 
 ATTRIBUTE_ABSTRACT = "Abstract"
 
-class _NameFormatter():
+class _NameFormatter(object):
   """A formatter for the names of kinds or values."""
 
   def __init__(self, token, variant):
@@ -118,12 +118,9 @@
   def _ShouldIncludeNamespace(self, omit_namespace_for_module):
     return self._token.module
 
-
-  # pylint: disable=inconsistent-return-statements
   def _GetNamespace(self):
     if self._token.module:
       return NamespaceToArray(self._token.module.namespace)
-  # pylint: enable=inconsistent-return-statements
 
 
 def NamespaceToArray(namespace):
@@ -186,7 +183,7 @@
   return kind.attributes.get(ATTRIBUTE_ABSTRACT, False) \
       if kind.attributes else False
 
-class StructConstructor():
+class StructConstructor(object):
   """Represents a constructor for a generated struct.
 
   Fields:
@@ -209,6 +206,8 @@
 
 
 class Generator(generator.Generator):
+  def __init__(self, *args, **kwargs):
+    super(Generator, self).__init__(*args, **kwargs)
 
   def _GetExtraTraitsHeaders(self):
     extra_headers = set()
@@ -508,29 +507,30 @@
       checked.add(kind.spec)
       if mojom.IsNullableKind(kind):
         return False
-      if mojom.IsStructKind(kind):
+      elif mojom.IsStructKind(kind):
         if kind.native_only:
           return False
         if (self._IsTypemappedKind(kind) and
             not self.typemap[self._GetFullMojomNameForKind(kind)]["hashable"]):
           return False
         return all(Check(field.kind) for field in kind.fields)
-      if mojom.IsEnumKind(kind):
+      elif mojom.IsEnumKind(kind):
         return not self._IsTypemappedKind(kind) or self.typemap[
             self._GetFullMojomNameForKind(kind)]["hashable"]
-      if mojom.IsUnionKind(kind):
+      elif mojom.IsUnionKind(kind):
         return all(Check(field.kind) for field in kind.fields)
-      if mojom.IsAnyHandleKind(kind):
+      elif mojom.IsAnyHandleKind(kind):
         return False
-      if mojom.IsAnyInterfaceKind(kind):
+      elif mojom.IsAnyInterfaceKind(kind):
         return False
       # TODO(crbug.com/735301): Arrays and maps could be made hashable. We just
       # don't have a use case yet.
-      if mojom.IsArrayKind(kind):
+      elif mojom.IsArrayKind(kind):
         return False
-      if mojom.IsMapKind(kind):
+      elif mojom.IsMapKind(kind):
         return False
-      return True
+      else:
+        return True
     return Check(kind)
 
   def _GetNativeTypeName(self, typemapped_kind):
@@ -809,8 +809,10 @@
         return "%d, %s, %s" % (expected_num_elements,
                                "true" if element_is_nullable else "false",
                                element_validate_params)
-      return "%s, %s" % (key_validate_params, element_validate_params)
-    return "%d, %s" % (expected_num_elements, enum_validate_func)
+      else:
+        return "%s, %s" % (key_validate_params, element_validate_params)
+    else:
+      return "%d, %s" % (expected_num_elements, enum_validate_func)
 
   def _GetNewContainerValidateParams(self, kind):
     if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and
diff --git a/components/cronet/tools/hide_symbols.py b/components/cronet/tools/hide_symbols.py
index 8608dfe..8bc50c3 100755
--- a/components/cronet/tools/hide_symbols.py
+++ b/components/cronet/tools/hide_symbols.py
@@ -15,7 +15,7 @@
 
 
 import glob
-import argparse
+import optparse
 import os
 import subprocess
 import sys
@@ -34,32 +34,32 @@
 
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument(
+  parser = optparse.OptionParser()
+  parser.add_option(
       '--input_libs',
       help='Comma-separated paths to input .a files which contain symbols '
            'which must be always linked.')
-  parser.add_argument(
+  parser.add_option(
       '--deps_lib',
       help='The path to a complete static library (.a file) which contains all '
            'dependencies of --input_libs. .o files in this library are also '
            'added to the output library, but only if they are referred from '
            '--input_libs.')
-  parser.add_argument(
+  parser.add_option(
       '--output_obj',
       help='Outputs the generated .o file here. This is an intermediate file.')
-  parser.add_argument(
+  parser.add_option(
       '--output_lib',
       help='Outputs the generated .a file here.')
-  parser.add_argument(
+  parser.add_option(
       '--current_cpu',
       help='The current processor architecture in the format of the target_cpu '
            'attribute in GN.')
-  parser.add_argument(
+  parser.add_option(
       '--use_custom_libcxx', default=False, action='store_true',
       help='Confirm there is a custom libc++ linked in.')
-  args, unknownargs = parser.parse_known_args()
-  assert not unknownargs
+  (options, args) = parser.parse_args()
+  assert not args
 
   developer_dir = subprocess.check_output(
       ['xcode-select', '--print-path'], universal_newlines=True).strip()
@@ -73,49 +73,49 @@
   # while "hiding" symbols not marked as visible.
   command = [
     'xcrun', 'ld',
-    '-arch', GN_CPU_TO_LD_ARCH[args.current_cpu],
+    '-arch', GN_CPU_TO_LD_ARCH[options.current_cpu],
     '-r',
   ]
-  for input_lib in args.input_libs.split(','):
+  for input_lib in options.input_libs.split(','):
     # By default, ld only pulls .o files out of a static library if needed to
     # resolve some symbol reference. We apply -force_load option to input_lib
     # (but not to deps_lib) to force pulling all .o files.
     command += ['-force_load', input_lib]
   command += xctoolchain_libs
   command += [
-    args.deps_lib,
-    '-o', args.output_obj
+    options.deps_lib,
+    '-o', options.output_obj
   ]
   try:
     subprocess.check_call(command)
   except subprocess.CalledProcessError:
     # Work around LD failure for x86 Debug buiilds when it fails with error:
     # ld: scattered reloc r_address too large for architecture i386
-    if args.current_cpu == "x86":
+    if options.current_cpu == "x86":
       # Combmine input lib with dependencies into output lib.
       command = [
         'xcrun', 'libtool', '-static', '-no_warning_for_no_symbols',
-        '-o', args.output_lib,
-        args.input_libs, args.deps_lib,
+        '-o', options.output_lib,
+        options.input_libs, options.deps_lib,
       ]
       subprocess.check_call(command)
       # Strip debug info from output lib so its size doesn't exceed 512mb.
       command = [
-        'xcrun', 'strip', '-S', args.output_lib,
+        'xcrun', 'strip', '-S', options.output_lib,
       ]
       subprocess.check_call(command)
       return
+    else:
+      exit(1)
 
-    sys.exit(1)
-
-  if os.path.exists(args.output_lib):
-    os.remove(args.output_lib)
+  if os.path.exists(options.output_lib):
+    os.remove(options.output_lib)
 
   # Creates a .a file which contains a single .o file.
   command = [
     'xcrun', 'ar', '-r',
-    args.output_lib,
-    args.output_obj,
+    options.output_lib,
+    options.output_obj,
   ]
 
   # When compiling for 64bit targets, the symbols in call_with_eh_frame.o are
@@ -125,13 +125,13 @@
   # other parts of cronet. Instead, simply add a second .o file with the
   # personality routine. Note that this issue was not caught by Chrome tests,
   # it was only detected when apps tried to link the resulting .a file.
-  if args.current_cpu in ('x64', 'arm64'):
+  if options.current_cpu == 'x64' or options.current_cpu == 'arm64':
     command += [ 'obj/base/base/call_with_eh_frame.o' ]
 
   subprocess.check_call(command)
 
-  if args.use_custom_libcxx:
-    ret = os.system('xcrun nm -u "' + args.output_obj +
+  if options.use_custom_libcxx:
+    ret = os.system('xcrun nm -u "' + options.output_obj +
                     '" | grep ___cxa_pure_virtual')
     if ret == 0:
       print("ERROR: Found undefined libc++ symbols, "
diff --git a/components/cronet/tools/perf_test_utils.py b/components/cronet/tools/perf_test_utils.py
index 23b4a71..b1b5d9b 100755
--- a/components/cronet/tools/perf_test_utils.py
+++ b/components/cronet/tools/perf_test_utils.py
@@ -62,11 +62,11 @@
 # Add benchmark config to global state for easy access.
 globals().update(DEFAULT_BENCHMARK_CONFIG)
 # Pylint doesn't really interpret the file, so it won't find the definitions
-# added from DEFAULT_BENCHMARK_CONFIG, so suppress the undefined variable and
-# bad string format type warnings.
-#pylint: disable=undefined-variable,bad-string-format-type
+# added from DEFAULT_BENCHMARK_CONFIG, so suppress the undefined variable
+# warning.
+#pylint: disable=undefined-variable
 
-class NativeDevice():
+class NativeDevice(object):
   def GetExternalStoragePath(self):
     return '/tmp'
 
@@ -108,7 +108,7 @@
   return 'http://%s:%d/%s' % (GetServersHost(device), HTTP_PORT, resource)
 
 
-class QuicServer():
+class QuicServer(object):
 
   def __init__(self, quic_server_doc_root):
     self._process = None
@@ -122,7 +122,7 @@
            '--port=%d' % QUIC_PORT]
     logging.info("Starting Quic Server: %s", cmd)
     self._process = subprocess.Popen(cmd)
-    assert self._process is not None
+    assert self._process != None
     # Wait for quic_server to start serving.
     waited_s = 0
     while subprocess.call(['lsof', '-i', 'udp:%d' % QUIC_PORT, '-p',
diff --git a/components/cronet/tools/update_api.py b/components/cronet/tools/update_api.py
index 8dff75d..32cc18c 100755
--- a/components/cronet/tools/update_api.py
+++ b/components/cronet/tools/update_api.py
@@ -21,9 +21,9 @@
 # Filename of dump of current API.
 API_FILENAME = os.path.abspath(os.path.join(
     os.path.dirname(__file__), '..', 'android', 'api.txt'))
-# Filename of file containing API version number.
-API_VERSION_FILENAME = os.path.abspath(os.path.join(
-    os.path.dirname(__file__), '..', 'android', 'api_version.txt'))
+# Filename of file containing the interface API version number.
+INTERFACE_API_VERSION_FILENAME = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '..', 'android', 'interface_api_version.txt'))
 
 # Regular expression that catches the beginning of lines that declare classes.
 # The first group returned by a match is the class name.
@@ -155,7 +155,7 @@
   if (generate_api(opts.api_jar, temp_filename) and
       check_api_update(API_FILENAME, temp_filename)):
     # Update API version number to new version number
-    with open(API_VERSION_FILENAME,'r+') as f:
+    with open(INTERFACE_API_VERSION_FILENAME,'r+') as f:
       version = int(f.read())
       f.seek(0)
       f.write(str(version + 1))
diff --git a/components/favicon/core/favicon_database_unittest.cc b/components/favicon/core/favicon_database_unittest.cc
index 12a3b7f..81bfc3c 100644
--- a/components/favicon/core/favicon_database_unittest.cc
+++ b/components/favicon/core/favicon_database_unittest.cc
@@ -176,8 +176,8 @@
 
 class FaviconDatabaseTest : public testing::Test {
  public:
-  FaviconDatabaseTest() {}
-  ~FaviconDatabaseTest() override {}
+  FaviconDatabaseTest() = default;
+  ~FaviconDatabaseTest() override = default;
 
   // Initialize a favicon database instance from the SQL file at
   // |golden_path| in the "History/" subdirectory of test data.
@@ -1030,18 +1030,14 @@
                                  kLargeSize, sizeof(kBlob2), kBlob2));
   }
 
-  // Corrupt the |icon_mapping.page_url| index by deleting an element
-  // from the backing table but not the index.
+  // Corrupt the `icon_mapping.page_url` index by zeroing its root page.
   {
     sql::Database raw_db;
     EXPECT_TRUE(raw_db.Open(file_name_));
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
   static const char kIndexName[] = "icon_mapping_page_url_idx";
-  static const char kDeleteSql[] =
-      "DELETE FROM icon_mapping WHERE page_url = 'http://yahoo.com/'";
-  EXPECT_TRUE(
-      sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(file_name_, kIndexName));
 
   // Database should be corrupt at the SQLite level.
   {
@@ -1052,18 +1048,18 @@
 
   // Open the database and access the corrupt index.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     FaviconDatabase db;
     ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
 
-    // Data for kPageUrl2 was deleted, but the index entry remains,
-    // this will throw SQLITE_CORRUPT.  The corruption handler will
-    // recover the database and poison the handle, so the outer call
-    // fails.
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      // Accessing the index will throw SQLITE_CORRUPT. The corruption handler
+      // will recover the database and poison the handle, so the outer call
+      // fails.
+      EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
   }
 
   // Check that the database is recovered at the SQLite level.
@@ -1076,18 +1072,18 @@
     VerifyTablesAndColumns(&raw_db);
   }
 
-  // Database should also be recovered at higher levels.
+  // Database should also be recovered at higher levels. Recovery should have
+  // regenerated the index with no data loss.
   {
     FaviconDatabase db;
     ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
 
-    // Now this fails because there is no mapping.
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
-
-    // Other data was retained by recovery.
     EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl1,
                                  favicon_base::IconType::kFavicon, kIconUrl1,
                                  kLargeSize, sizeof(kBlob1), kBlob1));
+    EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl2,
+                                 favicon_base::IconType::kFavicon, kIconUrl2,
+                                 kLargeSize, sizeof(kBlob2), kBlob2));
   }
 
   // Corrupt the database again by adjusting the header.
@@ -1105,17 +1101,20 @@
 
   // Database should be recovered during open.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     FaviconDatabase db;
-    ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
 
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
     EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl1,
                                  favicon_base::IconType::kFavicon, kIconUrl1,
                                  kLargeSize, sizeof(kBlob1), kBlob1));
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
+    EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl2,
+                                 favicon_base::IconType::kFavicon, kIconUrl2,
+                                 kLargeSize, sizeof(kBlob2), kBlob2));
   }
 }
 
@@ -1124,18 +1123,14 @@
   // (which would upgrade it).
   EXPECT_TRUE(history::CreateDatabaseFromSQL(file_name_, "Favicons.v7.sql"));
 
-  // Corrupt the |icon_mapping.page_url| index by deleting an element
-  // from the backing table but not the index.
+  // Corrupt the `icon_mapping.page_url` index by zeroing its root page.
   {
     sql::Database raw_db;
     EXPECT_TRUE(raw_db.Open(file_name_));
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
   static const char kIndexName[] = "icon_mapping_page_url_idx";
-  static const char kDeleteSql[] =
-      "DELETE FROM icon_mapping WHERE page_url = 'http://yahoo.com/'";
-  EXPECT_TRUE(
-      sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(file_name_, kIndexName));
 
   // Database should be corrupt at the SQLite level.
   {
@@ -1147,18 +1142,17 @@
   // Open the database and access the corrupt index. Note that this upgrades
   // the database.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     FaviconDatabase db;
     ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
-
-    // Data for kPageUrl2 was deleted, but the index entry remains,
-    // this will throw SQLITE_CORRUPT.  The corruption handler will
-    // recover the database and poison the handle, so the outer call
-    // fails.
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      // Accessing the index will throw SQLITE_CORRUPT. The corruption handler
+      // will recover the database and poison the handle, so the outer call
+      // fails.
+      EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
   }
 
   // Check that the database is recovered at the SQLite level.
@@ -1171,18 +1165,18 @@
     VerifyTablesAndColumns(&raw_db);
   }
 
-  // Database should also be recovered at higher levels.
+  // Database should also be recovered at higher levels. Recovery should have
+  // regenerated the index with no data loss.
   {
     FaviconDatabase db;
     ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
 
-    // Now this fails because there is no mapping.
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
-
-    // Other data was retained by recovery.
     EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl1,
                                  favicon_base::IconType::kFavicon, kIconUrl1,
                                  kLargeSize, sizeof(kBlob1), kBlob1));
+    EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl2,
+                                 favicon_base::IconType::kFavicon, kIconUrl2,
+                                 kLargeSize, sizeof(kBlob2), kBlob2));
   }
 
   // Corrupt the database again by adjusting the header.
@@ -1200,17 +1194,20 @@
 
   // Database should be recovered during open.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     FaviconDatabase db;
-    ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      ASSERT_EQ(sql::INIT_OK, db.Init(file_name_));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
 
-    EXPECT_FALSE(db.GetIconMappingsForPageURL(kPageUrl2, nullptr));
     EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl1,
                                  favicon_base::IconType::kFavicon, kIconUrl1,
                                  kLargeSize, sizeof(kBlob1), kBlob1));
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
+    EXPECT_TRUE(CheckPageHasIcon(&db, kPageUrl2,
+                                 favicon_base::IconType::kFavicon, kIconUrl2,
+                                 kLargeSize, sizeof(kBlob2), kBlob2));
   }
 }
 
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css
index ecd392e5..5a3ad4d 100644
--- a/components/flags_ui/resources/flags.css
+++ b/components/flags_ui/resources/flags.css
@@ -505,7 +505,7 @@
 }
 
 button.primary {
-  background: var(--interactive-color);
+  background: var(--link-color);
   border: 0;
   border-radius: 3px;
   color: white;
@@ -519,9 +519,8 @@
   }
 }
 
-button.primary:-webkit-any(:active, :focus, :hover) {
-  background: var(--google-blue-400);
-  outline: 0;
+button.primary:-webkit-any(:active, :hover) {
+  background: var(--google-blue-600);
 }
 
 html.focus-outline-visible button.primary:focus {
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn
index 0ecdd68..453deded 100644
--- a/components/history/core/browser/BUILD.gn
+++ b/components/history/core/browser/BUILD.gn
@@ -180,8 +180,8 @@
     "//components/test/data/history/history.48.sql",
     "//components/test/data/history/history.49.sql",
     "//components/test/data/history/history.50.sql",
-    "//components/test/data/history/history.51.sql",
     "//components/test/data/history/history.52.sql",
+    "//components/test/data/history/history.53.sql",
     "//components/test/data/history/thumbnail_wild/Favicons.corrupt_meta.disable",
     "//components/test/data/history/thumbnail_wild/Favicons.v2.init.sql",
     "//components/test/data/history/thumbnail_wild/Favicons.v3.init.sql",
diff --git a/components/history/core/browser/history_backend_db_unittest.cc b/components/history/core/browser/history_backend_db_unittest.cc
index 5b7415f..ca8e13e1 100644
--- a/components/history/core/browser/history_backend_db_unittest.cc
+++ b/components/history/core/browser/history_backend_db_unittest.cc
@@ -2415,7 +2415,7 @@
   CreateBackendAndDatabase();
 
   // The version should have been updated.
-  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 46);
+  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 47);
 
   // After the migration, the entities should be empty.
   {
@@ -2427,7 +2427,7 @@
 
 TEST_F(HistoryBackendDBTest,
        MigrateContentAnnotationsAddRelatedSearchesColumn) {
-  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(46));
+  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(47));
 
   const VisitID visit_id1 = 1;
 
@@ -2457,7 +2457,7 @@
   CreateBackendAndDatabase();
 
   // The version should have been updated.
-  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 46);
+  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 48);
 
   // After the migration, the related searches should be empty.
   {
@@ -2469,7 +2469,7 @@
 
 TEST_F(HistoryBackendDBTest,
        MigrateVisitsWithoutOpenerVisitColumnAndDropPubliclyRoutableColumn) {
-  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(47));
+  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(48));
 
   const VisitID visit_id1 = 1;
 
@@ -2494,7 +2494,7 @@
   CreateBackendAndDatabase();
 
   // The version should have been updated.
-  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 48);
+  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 49);
 
   // After the migration, the opener visit should be 0.
   {
@@ -2506,7 +2506,7 @@
 
 TEST_F(HistoryBackendDBTest,
        MigrateContextAnnotationsAddTotalForegroundDurationColumn) {
-  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(49));
+  ASSERT_NO_FATAL_FAILURE(CreateDBVersion(50));
 
   const VisitID visit_id = 1;
 
@@ -2534,7 +2534,7 @@
   CreateBackendAndDatabase();
 
   // The version should have been updated.
-  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 50);
+  ASSERT_GE(HistoryDatabase::GetCurrentVersion(), 51);
 
   // After the migration, the total foreground duration should have a default of
   // -1.
diff --git a/components/history/core/browser/top_sites_database.h b/components/history/core/browser/top_sites_database.h
index 8066f06a..42d467b 100644
--- a/components/history/core/browser/top_sites_database.h
+++ b/components/history/core/browser/top_sites_database.h
@@ -49,8 +49,10 @@
   FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Version4);
   FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery1);
   FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery2);
-  FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery3);
-  FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery4);
+  FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery3to4_CorruptIndex);
+  FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest, Recovery4_CorruptIndex);
+  FRIEND_TEST_ALL_PREFIXES(TopSitesDatabaseTest,
+                           Recovery4_CorruptIndexAndLostRow);
 
   // Rank used to indicate that a URL is not stored in the database.
   static const int kRankOfNonExistingURL;
diff --git a/components/history/core/browser/top_sites_database_unittest.cc b/components/history/core/browser/top_sites_database_unittest.cc
index 0718ddab..fde3d29 100644
--- a/components/history/core/browser/top_sites_database_unittest.cc
+++ b/components/history/core/browser/top_sites_database_unittest.cc
@@ -210,7 +210,7 @@
   }
 }
 
-TEST_F(TopSitesDatabaseTest, Recovery3) {
+TEST_F(TopSitesDatabaseTest, Recovery3_CorruptHeader) {
   // Create an example database.
   EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v3.sql"));
 
@@ -219,28 +219,30 @@
 
   // Database is unusable at the SQLite level.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     sql::Database raw_db;
-    EXPECT_TRUE(raw_db.Open(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      EXPECT_TRUE(raw_db.Open(file_name_));
+      EXPECT_TRUE(expecter.SawExpectedErrors());
+    }
     EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
-    ASSERT_TRUE(expecter.SawExpectedErrors());
   }
 
   // Corruption should be detected and recovered during Init().
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
-
     TopSitesDatabase db;
-    ASSERT_TRUE(db.Init(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      ASSERT_TRUE(db.Init(file_name_));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
 
     MostVisitedURLList urls;
     db.GetSites(&urls);
     ASSERT_EQ(3u, urls.size());
     EXPECT_EQ(kUrl0, urls[0].url);  // [0] because of url_rank.
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
   }
 
   // Double-check database integrity.
@@ -249,17 +251,26 @@
     EXPECT_TRUE(raw_db.Open(file_name_));
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
+}
 
-  // Corrupt the thumnails.url auto-index by deleting an element from the table
-  // but leaving it in the index.
+TEST_F(TopSitesDatabaseTest, Recovery3to4_CorruptIndex) {
+  // Create an example database.
+  EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v3.sql"));
+
+  // Previously, this was part of a monolithic Recovery3 test that aimed to
+  // cover both header corruption and index corruption. However, while testing
+  // recovery from header corruption, the test also upgraded the database to v4.
+  // So, we never had coverage for recovery from v3 with a corrupted index, and
+  // it doesn't work. For now, reproduce the upgrade in the old Recovery3 test.
+  {
+    TopSitesDatabase db;
+    ASSERT_TRUE(db.Init(file_name_));
+  }
+
+  // Corrupt the thumbnails.url auto-index.
+  // Note: The v3 index name is "sqlite_autoindex_thumbnails_1".
   static const char kIndexName[] = "sqlite_autoindex_top_sites_1";
-  // TODO(shess): Refactor CorruptTableOrIndex() to make parameterized
-  // statements easy.
-  static const char kDeleteSql[] =
-      "DELETE FROM top_sites WHERE url = "
-      "'http://www.google.com/chrome/intl/en/welcome.html'";
-  EXPECT_TRUE(
-      sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
+  EXPECT_TRUE(sql::test::CorruptIndexRootPage(file_name_, kIndexName));
 
   // SQLite can operate on the database, but notices the corruption in integrity
   // check.
@@ -278,13 +289,13 @@
       sql::test::ScopedErrorExpecter expecter;
       expecter.ExpectError(SQLITE_CORRUPT);
 
-      // Data for kUrl1 was deleted, but the index entry remains, this will
-      // throw SQLITE_CORRUPT.  The corruption handler will recover the database
-      // and poison the handle, so the outer call fails.
+      // Accessing the index will throw SQLITE_CORRUPT. The corruption handler
+      // will recover the database and poison the handle, so the outer call
+      // fails.
       EXPECT_EQ(TopSitesDatabase::kRankOfNonExistingURL,
                 db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
 
-      ASSERT_TRUE(expecter.SawExpectedErrors());
+      EXPECT_TRUE(expecter.SawExpectedErrors());
     }
   }
 
@@ -295,25 +306,27 @@
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
 
-  // After recovery, the database accesses won't throw errors.  The top-ranked
-  // item is removed, but the ranking was revised in post-processing.
+  // After recovery, the database accesses won't throw errors. Recovery should
+  // have regenerated the index with no data loss.
   {
     TopSitesDatabase db;
     ASSERT_TRUE(db.Init(file_name_));
     VerifyTablesAndColumns(db.db_.get());
 
-    EXPECT_EQ(TopSitesDatabase::kRankOfNonExistingURL,
-              db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
+    EXPECT_EQ(0, db.GetURLRank(MostVisitedURL(kUrl0, std::u16string())));
+    EXPECT_EQ(1, db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
+    EXPECT_EQ(2, db.GetURLRank(MostVisitedURL(kUrl2, std::u16string())));
 
     MostVisitedURLList urls;
     db.GetSites(&urls);
-    ASSERT_EQ(2u, urls.size());
+    ASSERT_EQ(3u, urls.size());
     EXPECT_EQ(kUrl0, urls[0].url);  // [0] because of url_rank.
-    EXPECT_EQ(kUrl2, urls[1].url);  // [1] because of url_rank.
+    EXPECT_EQ(kUrl1, urls[1].url);  // [1] because of url_rank.
+    EXPECT_EQ(kUrl2, urls[2].url);  // [2] because of url_rank.
   }
 }
 
-TEST_F(TopSitesDatabaseTest, Recovery4) {
+TEST_F(TopSitesDatabaseTest, Recovery4_CorruptHeader) {
   // Create an example database.
   EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v4.sql"));
 
@@ -322,28 +335,30 @@
 
   // Database is unusable at the SQLite level.
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
     sql::Database raw_db;
-    EXPECT_TRUE(raw_db.Open(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      EXPECT_TRUE(raw_db.Open(file_name_));
+      EXPECT_TRUE(expecter.SawExpectedErrors());
+    }
     EXPECT_FALSE(raw_db.IsSQLValid("PRAGMA integrity_check"));
-    ASSERT_TRUE(expecter.SawExpectedErrors());
   }
 
   // Corruption should be detected and recovered during Init().
   {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
-
     TopSitesDatabase db;
-    ASSERT_TRUE(db.Init(file_name_));
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+      ASSERT_TRUE(db.Init(file_name_));
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
 
     MostVisitedURLList urls;
     db.GetSites(&urls);
     ASSERT_EQ(3u, urls.size());
     EXPECT_EQ(kUrl0, urls[0].url);  // [0] because of url_rank.
-
-    ASSERT_TRUE(expecter.SawExpectedErrors());
   }
 
   // Double-check database integrity.
@@ -352,17 +367,15 @@
     EXPECT_TRUE(raw_db.Open(file_name_));
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
+}
 
-  // Corrupt the tops_sites.url auto-index by deleting an element from the table
-  // but leaving it in the index.
+TEST_F(TopSitesDatabaseTest, Recovery4_CorruptIndex) {
+  // Create an example database.
+  EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v4.sql"));
+
+  // Corrupt the thumnails.url auto-index.
   static const char kIndexName[] = "sqlite_autoindex_top_sites_1";
-  // TODO(shess): Refactor CorruptTableOrIndex() to make parameterized
-  // statements easy.
-  static const char kDeleteSql[] =
-      "DELETE FROM top_sites WHERE url = "
-      "'http://www.google.com/chrome/intl/en/welcome.html'";
-  EXPECT_TRUE(
-      sql::test::CorruptTableOrIndex(file_name_, kIndexName, kDeleteSql));
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(file_name_, kIndexName));
 
   // SQLite can operate on the database, but notices the corruption in integrity
   // check.
@@ -381,9 +394,9 @@
       sql::test::ScopedErrorExpecter expecter;
       expecter.ExpectError(SQLITE_CORRUPT);
 
-      // Data for kUrl1 was deleted, but the index entry remains, this will
-      // throw SQLITE_CORRUPT.  The corruption handler will recover the database
-      // and poison the handle, so the outer call fails.
+      // Accessing the index will throw SQLITE_CORRUPT. The corruption handler
+      // will recover the database and poison the handle, so the outer call
+      // fails.
       EXPECT_EQ(TopSitesDatabase::kRankOfNonExistingURL,
                 db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
 
@@ -398,13 +411,85 @@
     ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
   }
 
-  // After recovery, the database accesses won't throw errors.  The top-ranked
-  // item is removed, but the ranking was revised in post-processing.
+  // After recovery, the database accesses won't throw errors. Recovery should
+  // have regenerated the index with no data loss.
   {
     TopSitesDatabase db;
     ASSERT_TRUE(db.Init(file_name_));
     VerifyTablesAndColumns(db.db_.get());
 
+    EXPECT_EQ(0, db.GetURLRank(MostVisitedURL(kUrl0, std::u16string())));
+    EXPECT_EQ(1, db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
+    EXPECT_EQ(2, db.GetURLRank(MostVisitedURL(kUrl2, std::u16string())));
+
+    MostVisitedURLList urls;
+    db.GetSites(&urls);
+    ASSERT_EQ(3u, urls.size());
+    EXPECT_EQ(kUrl0, urls[0].url);  // [0] because of url_rank.
+    EXPECT_EQ(kUrl1, urls[1].url);  // [1] because of url_rank.
+    EXPECT_EQ(kUrl2, urls[2].url);  // [2] because of url_rank.
+  }
+}
+
+TEST_F(TopSitesDatabaseTest, Recovery4_CorruptIndexAndLostRow) {
+  // Create an example database.
+  EXPECT_TRUE(CreateDatabaseFromSQL(file_name_, "TopSites.v4.sql"));
+
+  // Delete a row.
+  {
+    sql::Database raw_db;
+    EXPECT_TRUE(raw_db.Open(file_name_));
+    EXPECT_TRUE(
+        raw_db.Execute("DELETE FROM top_sites WHERE url = "
+                       "'http://www.google.com/chrome/intl/en/welcome.html'"));
+  }
+  // Corrupt the thumnails.url auto-index.
+  static const char kIndexName[] = "sqlite_autoindex_top_sites_1";
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(file_name_, kIndexName));
+
+  // SQLite can operate on the database, but notices the corruption in integrity
+  // check.
+  {
+    sql::Database raw_db;
+    EXPECT_TRUE(raw_db.Open(file_name_));
+    ASSERT_NE("ok", sql::test::IntegrityCheck(&raw_db));
+  }
+
+  // Open the database and access the corrupt index.
+  {
+    TopSitesDatabase db;
+    ASSERT_TRUE(db.Init(file_name_));
+
+    {
+      sql::test::ScopedErrorExpecter expecter;
+      expecter.ExpectError(SQLITE_CORRUPT);
+
+      // Accessing the index will throw SQLITE_CORRUPT. The corruption handler
+      // will recover the database and poison the handle, so the outer call
+      // fails.
+      EXPECT_EQ(TopSitesDatabase::kRankOfNonExistingURL,
+                db.GetURLRank(MostVisitedURL(kUrl0, std::u16string())));
+
+      ASSERT_TRUE(expecter.SawExpectedErrors());
+    }
+  }
+
+  // Check that the database is recovered at the SQLite level.
+  {
+    sql::Database raw_db;
+    EXPECT_TRUE(raw_db.Open(file_name_));
+    ASSERT_EQ("ok", sql::test::IntegrityCheck(&raw_db));
+  }
+
+  // After recovery, the database accesses won't throw errors. Recovery should
+  // have regenerated the index and adjusted the ranks.
+  {
+    TopSitesDatabase db;
+    ASSERT_TRUE(db.Init(file_name_));
+    VerifyTablesAndColumns(db.db_.get());
+
+    EXPECT_EQ(0, db.GetURLRank(MostVisitedURL(kUrl0, std::u16string())));
+    EXPECT_EQ(1, db.GetURLRank(MostVisitedURL(kUrl2, std::u16string())));
     EXPECT_EQ(TopSitesDatabase::kRankOfNonExistingURL,
               db.GetURLRank(MostVisitedURL(kUrl1, std::u16string())));
 
diff --git a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarCompactLayout.java b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarCompactLayout.java
index 821f61a..38e77dc 100644
--- a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarCompactLayout.java
+++ b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarCompactLayout.java
@@ -147,9 +147,9 @@
         public MessageBuilder withLink(CharSequence label, Callback<View> onTapCallback) {
             assert mLink == null;
 
-            final Resources resources = mLayout.getResources();
+            final Context context = mLayout.getContext();
             SpannableString link = new SpannableString(label);
-            link.setSpan(new NoUnderlineClickableSpan(resources, onTapCallback), 0, label.length(),
+            link.setSpan(new NoUnderlineClickableSpan(context, onTapCallback), 0, label.length(),
                     Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
             mLink = link;
 
diff --git a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java
index 0e780ed..31622b9 100644
--- a/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java
+++ b/components/infobars/android/java/src/org/chromium/components/infobars/InfoBarLayout.java
@@ -543,7 +543,7 @@
     }
 
     private NoUnderlineClickableSpan createClickableSpan() {
-        return new NoUnderlineClickableSpan(getResources(), (view) -> mInfoBar.onLinkClicked());
+        return new NoUnderlineClickableSpan(getContext(), (view) -> mInfoBar.onLinkClicked());
     }
 
     /**
diff --git a/components/metrics/call_stack_profile_builder_unittest.cc b/components/metrics/call_stack_profile_builder_unittest.cc
index fe564b78..7a3c33e 100644
--- a/components/metrics/call_stack_profile_builder_unittest.cc
+++ b/components/metrics/call_stack_profile_builder_unittest.cc
@@ -111,11 +111,11 @@
   std::vector<base::Frame> frames1 = {frame1, frame2};
   std::vector<base::Frame> frames2 = {frame3};
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames1, base::TimeTicks());
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames2, base::TimeTicks());
   profile_builder->OnProfileCompleted(base::Milliseconds(500),
                                       base::Milliseconds(100));
@@ -213,11 +213,11 @@
 
   // Two stacks are completed with the same frames therefore they are deduped
   // to one.
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames, base::TimeTicks());
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames, base::TimeTicks());
 
   profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
@@ -254,11 +254,11 @@
   std::vector<base::Frame> frames2 = {frame2};
 
   // Two stacks are completed with the different frames therefore not deduped.
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames1, base::TimeTicks());
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames2, base::TimeTicks());
 
   profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
@@ -303,8 +303,8 @@
 
   std::vector<base::Frame> frames = {frame1, frame2};
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames, base::TimeTicks());
   profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
 
@@ -357,8 +357,8 @@
 
   std::vector<base::Frame> frames = {frame1, frame2};
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(frames, base::TimeTicks());
   profile_builder->OnProfileCompleted(base::TimeDelta(), base::TimeDelta());
 
@@ -410,26 +410,26 @@
 
   // Id 0 means the message loop hasn't been started yet, so the sample should
   // not have continued_work set.
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
 
   // The second sample with the same id should have continued_work set.
   work_id_recorder.current_id = 1;
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
 
   // Ids are in general non-contiguous across multiple samples.
   work_id_recorder.current_id = 10;
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
 
   profile_builder->OnProfileCompleted(base::Milliseconds(500),
@@ -475,9 +475,9 @@
   base::TestModule module;
   base::Frame frame = {0x10, &module};
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, base::TimeTicks());
 
   profile_builder->OnProfileCompleted(base::Milliseconds(500),
@@ -513,22 +513,22 @@
   base::TimeTicks profile_start_time = base::TimeTicks::UnixEpoch();
   base::TimeDelta sample_time_delta = base::Seconds(1);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, profile_start_time);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame},
                                      profile_start_time + sample_time_delta);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(
       {frame}, profile_start_time + 2 * sample_time_delta);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(
       {frame}, profile_start_time + 3 * sample_time_delta);
 
@@ -536,7 +536,7 @@
   profile_builder->ApplyMetadataRetrospectively(
       profile_start_time + sample_time_delta,
       profile_start_time + sample_time_delta * 2,
-      base::MetadataRecorder::Item(3, 30, 300));
+      base::MetadataRecorder::Item(3, 30, absl::nullopt, 300));
 
   profile_builder->OnProfileCompleted(3 * sample_time_delta, sample_time_delta);
 
@@ -578,29 +578,29 @@
   base::TimeTicks profile_start_time = base::TimeTicks::UnixEpoch();
   base::TimeDelta sample_time_delta = base::Seconds(1);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame}, profile_start_time);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted({frame},
                                      profile_start_time + sample_time_delta);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(
       {frame}, profile_start_time + 2 * sample_time_delta);
 
-  profile_builder->RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  profile_builder->RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   profile_builder->OnSampleCompleted(
       {frame}, profile_start_time + 3 * sample_time_delta);
 
   profile_builder->ApplyMetadataRetrospectively(
       profile_start_time - base::Microseconds(1),
       profile_start_time + sample_time_delta,
-      base::MetadataRecorder::Item(3, 30, 300));
+      base::MetadataRecorder::Item(3, 30, absl::nullopt, 300));
 
   profile_builder->OnProfileCompleted(3 * sample_time_delta, sample_time_delta);
 
diff --git a/components/metrics/call_stack_profile_metadata_unittest.cc b/components/metrics/call_stack_profile_metadata_unittest.cc
index f1a0407..ccdab81 100644
--- a/components/metrics/call_stack_profile_metadata_unittest.cc
+++ b/components/metrics/call_stack_profile_metadata_unittest.cc
@@ -84,8 +84,8 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
 
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
@@ -99,9 +99,9 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -119,9 +119,9 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -135,18 +135,40 @@
   EXPECT_EQ(10, items[0].value());
 }
 
+TEST(CallStackProfileMetadataTest, MetadataRecorder_SetThreadItem) {
+  base::MetadataRecorder metadata_recorder;
+  CallStackProfileMetadata metadata;
+  google::protobuf::RepeatedField<uint64_t> name_hashes;
+
+  metadata_recorder.Set(100, absl::nullopt, base::PlatformThread::CurrentId(),
+                        10);
+  metadata_recorder.Set(100, absl::nullopt, base::kInvalidThreadId, 20);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
+  google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
+      metadata.CreateSampleMetadata(&name_hashes);
+
+  ASSERT_EQ(1, name_hashes.size());
+  EXPECT_EQ(100u, name_hashes[0]);
+
+  ASSERT_EQ(1, items.size());
+  EXPECT_EQ(0, items[0].name_hash_index());
+  EXPECT_FALSE(items[0].has_key());
+  EXPECT_EQ(10, items[0].value());
+}
+
 TEST(CallStackProfileMetadataTest, MetadataRecorder_RepeatItem) {
   base::MetadataRecorder metadata_recorder;
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -161,13 +183,13 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -182,14 +204,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Set(100, absl::nullopt, 11);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 11);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -206,14 +228,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Set(100, 50, 11);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 11);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -231,14 +253,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Set(101, absl::nullopt, 11);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(101, absl::nullopt, absl::nullopt, 11);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -256,14 +278,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Set(101, 50, 11);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(101, 50, absl::nullopt, 11);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -282,14 +304,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Remove(100, absl::nullopt);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Remove(100, absl::nullopt, absl::nullopt);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -306,14 +328,14 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Remove(100, 50);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Remove(100, 50, absl::nullopt);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -326,16 +348,42 @@
   EXPECT_FALSE(items[0].has_value());
 }
 
+TEST(CallStackProfileMetadataTest, MetadataRecorder_RemovedThreadItem) {
+  base::MetadataRecorder metadata_recorder;
+  CallStackProfileMetadata metadata;
+  google::protobuf::RepeatedField<uint64_t> name_hashes;
+
+  metadata_recorder.Set(100, absl::nullopt, base::PlatformThread::CurrentId(),
+                        10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
+  (void)metadata.CreateSampleMetadata(&name_hashes);
+
+  metadata_recorder.Remove(100, absl::nullopt,
+                           base::PlatformThread::CurrentId());
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
+  google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
+      metadata.CreateSampleMetadata(&name_hashes);
+
+  EXPECT_EQ(1, name_hashes.size());
+
+  ASSERT_EQ(1, items.size());
+  EXPECT_EQ(0, items[0].name_hash_index());
+  EXPECT_FALSE(items[0].has_key());
+  EXPECT_FALSE(items[0].has_value());
+}
+
 TEST(CallStackProfileMetadataTest,
      MetadataRecorder_SetMixedUnkeyedAndKeyedItems) {
   base::MetadataRecorder metadata_recorder;
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 20);
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 20);
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -357,15 +405,15 @@
   CallStackProfileMetadata metadata;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  metadata_recorder.Set(100, absl::nullopt, 20);
-  metadata_recorder.Set(100, 50, 10);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(100, absl::nullopt, absl::nullopt, 20);
+  metadata_recorder.Set(100, 50, absl::nullopt, 10);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   std::ignore = metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Remove(100, absl::nullopt);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Remove(100, absl::nullopt, absl::nullopt);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   google::protobuf::RepeatedPtrField<CallStackProfile::MetadataItem> items =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -386,7 +434,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
   metadata.ApplyMetadata(item, stack_samples.begin() + 1,
                          stack_samples.begin() + 4, &stack_samples,
                          &name_hashes);
@@ -419,8 +467,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(4, 30, 300);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(4, 30, absl::nullopt, 300);
   metadata.ApplyMetadata(item1, stack_samples.begin() + 1,
                          stack_samples.begin() + 4, &stack_samples,
                          &name_hashes);
@@ -456,9 +504,10 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 40, 300);
-  const base::MetadataRecorder::Item item3(3, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 40, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item3(3, absl::nullopt, absl::nullopt,
+                                           300);
   metadata.ApplyMetadata(item1, stack_samples.begin() + 1,
                          stack_samples.begin() + 4, &stack_samples,
                          &name_hashes);
@@ -498,7 +547,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
   metadata.ApplyMetadata(item, stack_samples.begin() + 1,
                          stack_samples.begin() + 1, &stack_samples,
                          &name_hashes);
@@ -520,7 +569,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
   metadata.ApplyMetadata(item, stack_samples.begin() + 1, stack_samples.end(),
                          &stack_samples, &name_hashes);
 
@@ -538,8 +587,8 @@
   EXPECT_EQ(0, stack_samples[4].metadata_size());
 
   base::MetadataRecorder metadata_recorder;
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -556,26 +605,27 @@
       stack_samples;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(5, 50, 500);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(5, 50, absl::nullopt, 500);
 
   stack_samples.Add();
 
   // Apply then remove item1.
-  metadata_recorder.Set(item1.name_hash, *item1.key, item1.value);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(item1.name_hash, *item1.key, item1.thread_id,
+                        item1.value);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata_recorder.Remove(item1.name_hash, *item1.key);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Remove(item1.name_hash, *item1.key, item1.thread_id);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -619,23 +669,24 @@
       stack_samples;
   google::protobuf::RepeatedField<uint64_t> name_hashes;
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
   // Record item1 on an ongoing basis via RecordMetadata.
-  metadata_recorder.Set(item1.name_hash, *item1.key, item1.value);
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata_recorder.Set(item1.name_hash, *item1.key, item1.thread_id,
+                        item1.value);
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -655,8 +706,8 @@
   EXPECT_EQ(0, stack_samples[2].metadata_size());
 
   // The next recorded sample should have item1 applied since it's still active.
-  metadata.RecordMetadata(
-      base::MetadataRecorder::MetadataProvider(&metadata_recorder));
+  metadata.RecordMetadata(base::MetadataRecorder::MetadataProvider(
+      &metadata_recorder, base::PlatformThread::CurrentId()));
   *stack_samples.Add()->mutable_metadata() =
       metadata.CreateSampleMetadata(&name_hashes);
 
@@ -674,7 +725,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over two non-overlapping ranges.
   metadata.ApplyMetadata(item, stack_samples.begin(), stack_samples.begin() + 2,
@@ -713,7 +764,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over two ranges where the second starts on the same sample
   // that the first ends. This should result in one range covering both.
@@ -750,8 +801,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   metadata.ApplyMetadata(item1, stack_samples.begin(),
                          stack_samples.begin() + 2, &stack_samples,
@@ -790,7 +841,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   metadata.ApplyMetadata(item, stack_samples.begin(), stack_samples.begin() + 4,
                          &stack_samples, &name_hashes);
@@ -826,8 +877,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   // Apply metadata over a range, then over a range fully enclosed within the
   // first one.
@@ -869,7 +920,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over a range, then over a range that fully encloses the
   // first one.
@@ -907,8 +958,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   // Apply metadata over a range, then over a range that fully encloses the
   // first one.
@@ -946,7 +997,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over a range, then over a range that overlaps the beginning
   // (but not the end) of first one.
@@ -985,8 +1036,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   // Apply metadata over a range, then over a range that overlaps the beginning
   // (but not the end) of first one.
@@ -1026,7 +1077,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over a range, then over a range that overlaps the beginning
   // (but not the end) of first one.
@@ -1064,8 +1115,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   // Apply metadata over a range, then over a range that overlaps the beginning
   // (but not the end) of first one.
@@ -1104,7 +1155,7 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item(3, 30, 300);
+  const base::MetadataRecorder::Item item(3, 30, absl::nullopt, 300);
 
   // Apply metadata over the same range with one value, then a different value.
   metadata.ApplyMetadata(item, stack_samples.begin() + 1,
@@ -1141,8 +1192,8 @@
   for (int i = 0; i < 5; i++)
     stack_samples.Add();
 
-  const base::MetadataRecorder::Item item1(3, 30, 300);
-  const base::MetadataRecorder::Item item2(3, 30, 400);
+  const base::MetadataRecorder::Item item1(3, 30, absl::nullopt, 300);
+  const base::MetadataRecorder::Item item2(3, 30, absl::nullopt, 400);
 
   // Apply metadata over the same range with one value, then a different value.
   metadata.ApplyMetadata(item1, stack_samples.begin() + 1,
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index 7995bce..e48c97fe 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -604,6 +604,7 @@
     "//components/dom_distiller/core:core",
     "//components/favicon/core/test:test_support",
     "//components/history/core/test",
+    "//components/ntp_tiles:ntp_tiles",
     "//components/omnibox/common",
     "//components/open_from_clipboard:test_support",
     "//components/prefs:test_support",
diff --git a/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java b/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
index 520c1e5..90e9c06 100644
--- a/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
+++ b/components/omnibox/browser/android/javatests/src/org/chromium/components/omnibox/AutocompleteMatchBuilder.java
@@ -269,4 +269,13 @@
         mOmniboxPedal = omniboxPedal;
         return this;
     }
+
+    /**
+     * @param isDeletable Whether the match should be made deletable.
+     * @return Omnibox suggestion builder.
+     */
+    public AutocompleteMatchBuilder setDeletable(boolean isDeletable) {
+        mIsDeletable = isDeletable;
+        return this;
+    }
 }
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index 5e3ae82..b06df27 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -129,6 +129,20 @@
   return top_match->rich_autocompletion_triggered;
 }
 
+void RecordMatchDeletion(const AutocompleteMatch& match) {
+  if (match.deletable) {
+    // This formula combines provider and result type into a single enum as
+    // defined in OmniboxProviderAndResultType in enums.xml.
+    auto combined_type = match.provider->AsOmniboxEventProviderType() * 100 +
+                         match.AsOmniboxEventResultType();
+    // This histogram is defined in the internal histograms.xml. This is because
+    // the vast majority of OmniboxProviderAndResultType histograms are
+    // generated by internal tools, and we wish to keep them together.
+    base::UmaHistogramSparse("Omnibox.SuggestionDeleted.ProviderAndResultType",
+                             combined_type);
+  }
+}
+
 }  // namespace
 
 // static
@@ -527,11 +541,6 @@
 void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) {
   DCHECK(match.SupportsDeletion());
 
-  // This formula combines provider and result type into a single enum as
-  // defined in OmniboxProviderAndResultType in enums.xml.
-  auto combined_type = match.provider->AsOmniboxEventProviderType() * 100 +
-                       match.AsOmniboxEventResultType();
-
   // Delete duplicate matches attached to the main match first.
   for (auto it(match.duplicate_matches.begin());
        it != match.duplicate_matches.end(); ++it) {
@@ -540,11 +549,7 @@
   }
 
   if (match.deletable) {
-    // This histogram is defined in the internal histograms.xml. This is because
-    // the vast majority of OmniboxProviderAndResultType histograms are
-    // generated by internal tools, and we wish to keep them together.
-    base::UmaHistogramSparse("Omnibox.SuggestionDeleted.ProviderAndResultType",
-                             combined_type);
+    RecordMatchDeletion(match);
     match.provider->DeleteMatch(match);
   }
 
@@ -555,6 +560,18 @@
   ExpireCopiedEntries();
 }
 
+void AutocompleteController::DeleteMatchElement(const AutocompleteMatch& match,
+                                                size_t element_index) {
+  DCHECK(match.SupportsDeletion());
+
+  if (match.deletable) {
+    RecordMatchDeletion(match);
+    match.provider->DeleteMatchElement(match, element_index);
+  }
+
+  OnProviderUpdate(true);
+}
+
 void AutocompleteController::ExpireCopiedEntries() {
   // The first true makes UpdateResult() clear out the results and
   // regenerate them, thus ensuring that no results from the previous
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h
index dad18b6..3944e37 100644
--- a/components/omnibox/browser/autocomplete_controller.h
+++ b/components/omnibox/browser/autocomplete_controller.h
@@ -139,6 +139,15 @@
   // no query is running.
   void DeleteMatch(const AutocompleteMatch& match);
 
+  // Asks the relevant provider to partially delete match, and ensures observers
+  // are notified of resulting changes immediately.  This should only be called
+  // when no query is running.
+  // Calling this method does not imply removal of the AutocompleteMatch.
+  // |element_index| parameter specifies which part of the match should be
+  // deleted. For cases where the entire AutocompleteMatch should be removed,
+  // please see |DeleteMatch| method.
+  void DeleteMatchElement(const AutocompleteMatch& match, size_t element_index);
+
   // Removes any entries that were copied from the last result. This is used by
   // the popup to ensure it's not showing an out-of-date query.
   void ExpireCopiedEntries();
diff --git a/components/omnibox/browser/autocomplete_match_type_unittest.cc b/components/omnibox/browser/autocomplete_match_type_unittest.cc
index 8835bc08..b3206e1 100644
--- a/components/omnibox/browser/autocomplete_match_type_unittest.cc
+++ b/components/omnibox/browser/autocomplete_match_type_unittest.cc
@@ -53,7 +53,7 @@
 
   // ParseAnswer previously did not change the default answer type of -1, so
   // here we keep the same behavior by explicitly supplying default value.
-  return SuggestionAnswer::ParseAnswer(*value, u"-1", answer);
+  return SuggestionAnswer::ParseAnswer(value->GetDict(), u"-1", answer);
 }
 
 }  // namespace
diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc
index 2f42ef3..44fb680 100644
--- a/components/omnibox/browser/autocomplete_provider.cc
+++ b/components/omnibox/browser/autocomplete_provider.cc
@@ -164,6 +164,12 @@
                 << "' has not implemented DeleteMatch.";
 }
 
+void AutocompleteProvider::DeleteMatchElement(const AutocompleteMatch& match,
+                                              size_t element_index) {
+  DLOG(WARNING) << "The AutocompleteProvider '" << GetName()
+                << "' has not implemented DeleteMatchElement.";
+}
+
 void AutocompleteProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
 }
 
diff --git a/components/omnibox/browser/autocomplete_provider.h b/components/omnibox/browser/autocomplete_provider.h
index ee3afeb..efdfbe9 100644
--- a/components/omnibox/browser/autocomplete_provider.h
+++ b/components/omnibox/browser/autocomplete_provider.h
@@ -236,6 +236,14 @@
   // responsibility of the caller to do so after calling us.
   virtual void DeleteMatch(const AutocompleteMatch& match);
 
+  // Called to delete an element of a match. This element should not appear
+  // again in this or future queries. Unlike DeleteMatch, this call does not
+  // delete the entire AutocompleteMatch, but focuses on just one part of it.
+  // NOTE: Do NOT call OnProviderUpdate() in this method, it is the
+  // responsibility of the caller to do so after calling us.
+  virtual void DeleteMatchElement(const AutocompleteMatch& match,
+                                  size_t element_index);
+
   // Called when an omnibox event log entry is generated.  This gives
   // a provider the opportunity to add diagnostic information to the
   // logs.  A provider is expected to append a single entry of whatever
diff --git a/components/omnibox/browser/fake_autocomplete_provider_client.cc b/components/omnibox/browser/fake_autocomplete_provider_client.cc
index d016671..2f4b982 100644
--- a/components/omnibox/browser/fake_autocomplete_provider_client.cc
+++ b/components/omnibox/browser/fake_autocomplete_provider_client.cc
@@ -107,3 +107,12 @@
 const TabMatcher& FakeAutocompleteProviderClient::GetTabMatcher() const {
   return fake_tab_matcher_;
 }
+
+scoped_refptr<history::TopSites> FakeAutocompleteProviderClient::GetTopSites() {
+  return top_sites_;
+}
+
+ntp_tiles::MostVisitedSites*
+FakeAutocompleteProviderClient::GetNtpMostVisitedSites() {
+  return ntp_most_visited_sites_;
+}
diff --git a/components/omnibox/browser/fake_autocomplete_provider_client.h b/components/omnibox/browser/fake_autocomplete_provider_client.h
index 553a69b4..072273c 100644
--- a/components/omnibox/browser/fake_autocomplete_provider_client.h
+++ b/components/omnibox/browser/fake_autocomplete_provider_client.h
@@ -57,11 +57,22 @@
   scoped_refptr<ShortcutsBackend> GetShortcutsBackendIfExists() override;
   query_tiles::TileService* GetQueryTileService() const override;
   const TabMatcher& GetTabMatcher() const override;
+  scoped_refptr<history::TopSites> GetTopSites() override;
+  ntp_tiles::MostVisitedSites* GetNtpMostVisitedSites() override;
 
+  // Test-only setters
   void set_in_memory_url_index(std::unique_ptr<InMemoryURLIndex> index) {
     in_memory_url_index_ = std::move(index);
   }
 
+  void set_top_sites(scoped_refptr<history::TopSites> top_sites) {
+    top_sites_ = std::move(top_sites);
+  }
+
+  void set_ntp_most_visited_sites(ntp_tiles::MostVisitedSites* ntp_mv_sites) {
+    ntp_most_visited_sites_ = ntp_mv_sites;
+  }
+
  private:
   base::ScopedTempDir history_dir_;
   std::unique_ptr<bookmarks::BookmarkModel> bookmark_model_;
@@ -73,6 +84,8 @@
   scoped_refptr<ShortcutsBackend> shortcuts_backend_;
   std::unique_ptr<query_tiles::TileService> tile_service_;
   FakeTabMatcher fake_tab_matcher_;
+  scoped_refptr<history::TopSites> top_sites_{};
+  ntp_tiles::MostVisitedSites* ntp_most_visited_sites_{};
 };
 
 #endif  // COMPONENTS_OMNIBOX_BROWSER_FAKE_AUTOCOMPLETE_PROVIDER_CLIENT_H_
diff --git a/components/omnibox/browser/most_visited_sites_provider.cc b/components/omnibox/browser/most_visited_sites_provider.cc
index 99654e5..5a26c3e85 100644
--- a/components/omnibox/browser/most_visited_sites_provider.cc
+++ b/components/omnibox/browser/most_visited_sites_provider.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/bind.h"
+#include "base/containers/cxx20_erase.h"
 #include "base/feature_list.h"
 #include "components/history/core/browser/top_sites.h"
 #include "components/ntp_tiles/most_visited_sites.h"
@@ -36,7 +37,7 @@
                              const GURL& url,
                              int relevance,
                              AutocompleteMatchType::Type type) {
-  AutocompleteMatch match(provider, relevance, false, type);
+  AutocompleteMatch match(provider, relevance, true, type);
   match.destination_url = url;
 
   match.fill_into_edit +=
@@ -219,3 +220,57 @@
 }
 
 void MostVisitedSitesProvider::OnIconMadeAvailable(const GURL& site_url) {}
+
+void MostVisitedSitesProvider::BlockURL(const GURL& site_url) {
+  scoped_refptr<history::TopSites> top_sites = client_->GetTopSites();
+  if (top_sites) {
+    top_sites->AddBlockedUrl(site_url);
+  }
+
+  if (most_visited_sites_) {
+    most_visited_sites_->DeleteCustomLink(site_url);
+    most_visited_sites_->AddOrRemoveBlockedUrl(site_url, /* add_url=*/true);
+  }
+}
+
+void MostVisitedSitesProvider::DeleteMatch(const AutocompleteMatch& match) {
+  DCHECK_EQ(match.type, AutocompleteMatchType::NAVSUGGEST);
+
+  BlockURL(match.destination_url);
+  for (auto i = matches_.begin(); i != matches_.end(); ++i) {
+    if (i->contents == match.contents) {
+      matches_.erase(i);
+      break;
+    }
+  }
+}
+void MostVisitedSitesProvider::DeleteMatchElement(
+    const AutocompleteMatch& source_match,
+    size_t element_index) {
+  DCHECK_EQ(source_match.type, AutocompleteMatchType::TILE_NAVSUGGEST);
+  DCHECK_GE(element_index, 0u);
+  DCHECK_LT((size_t)element_index, source_match.navsuggest_tiles.size());
+
+  // Attempt to modify the match in place.
+  DCHECK_EQ(matches_.size(), 1ul);
+  DCHECK_EQ(matches_[0].type, AutocompleteMatchType::TILE_NAVSUGGEST);
+
+  if (source_match.type != AutocompleteMatchType::TILE_NAVSUGGEST ||
+      element_index < 0u ||
+      element_index >= source_match.navsuggest_tiles.size() ||
+      matches_.size() != 1u ||
+      matches_[0].type != AutocompleteMatchType::TILE_NAVSUGGEST) {
+    return;
+  }
+
+  const auto& url_to_delete = source_match.navsuggest_tiles[element_index].url;
+  BlockURL(url_to_delete);
+  auto& tiles_to_update = matches_[0].navsuggest_tiles;
+  base::EraseIf(tiles_to_update, [&url_to_delete](const auto& tile) {
+    return tile.url == url_to_delete;
+  });
+
+  if (tiles_to_update.empty()) {
+    matches_.clear();
+  }
+}
diff --git a/components/omnibox/browser/most_visited_sites_provider.h b/components/omnibox/browser/most_visited_sites_provider.h
index 0fa9148..bf119da6 100644
--- a/components/omnibox/browser/most_visited_sites_provider.h
+++ b/components/omnibox/browser/most_visited_sites_provider.h
@@ -30,6 +30,9 @@
 
   void Start(const AutocompleteInput& input, bool minimal_changes) override;
   void Stop(bool clear_cached_results, bool due_to_user_inactivity) override;
+  void DeleteMatch(const AutocompleteMatch& match) override;
+  void DeleteMatchElement(const AutocompleteMatch& match,
+                          size_t element) override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(MostVisitedSitesProviderTest,
@@ -57,6 +60,7 @@
       const std::map<ntp_tiles::SectionType, ntp_tiles::NTPTilesVector>&
           sections) override;
   void OnIconMadeAvailable(const GURL& site_url) override;
+  void BlockURL(const GURL& site_url);
 
   raw_ptr<ntp_tiles::MostVisitedSites> most_visited_sites_{};
 
diff --git a/components/omnibox/browser/most_visited_sites_provider_unittest.cc b/components/omnibox/browser/most_visited_sites_provider_unittest.cc
index 6b035f8..c0f156a 100644
--- a/components/omnibox/browser/most_visited_sites_provider_unittest.cc
+++ b/components/omnibox/browser/most_visited_sites_provider_unittest.cc
@@ -9,29 +9,46 @@
 #include <memory>
 #include <string>
 
+#include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
 #include "build/build_config.h"
 #include "components/history/core/browser/top_sites.h"
+#include "components/ntp_tiles/icon_cacher.h"
+#include "components/ntp_tiles/most_visited_sites.h"
+#include "components/omnibox/browser/autocomplete_controller.h"
 #include "components/omnibox/browser/autocomplete_provider_listener.h"
-#include "components/omnibox/browser/mock_autocomplete_provider_client.h"
+#include "components/omnibox/browser/fake_autocomplete_provider_client.h"
 #include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/test_scheme_classifier.h"
 #include "components/omnibox/common/omnibox_features.h"
 #include "components/search_engines/omnibox_focus_type.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/metrics_proto/omnibox_event.pb.h"
 
 namespace {
-class FakeEmptyTopSites : public history::TopSites {
+class FakeTopSites : public history::TopSites {
  public:
+  FakeTopSites() = default;
+
   // history::TopSites:
-  void GetMostVisitedURLs(GetMostVisitedURLsCallback callback) override;
+  void GetMostVisitedURLs(GetMostVisitedURLsCallback callback) override {
+    callbacks_.push_back(std::move(callback));
+  }
   void SyncWithHistory() override {}
-  bool HasBlockedUrls() const override { return false; }
-  void AddBlockedUrl(const GURL& url) override {}
-  void RemoveBlockedUrl(const GURL& url) override {}
-  bool IsBlocked(const GURL& url) override { return false; }
-  void ClearBlockedUrls() override {}
+
+  bool HasBlockedUrls() const override { return !blocked_urls_.empty(); }
+  void AddBlockedUrl(const GURL& url) override {
+    blocked_urls_.insert(url.spec());
+  }
+  void RemoveBlockedUrl(const GURL& url) override {
+    blocked_urls_.erase(url.spec());
+  }
+  bool IsBlocked(const GURL& url) override {
+    return blocked_urls_.count(url.spec()) > 0;
+  }
+  void ClearBlockedUrls() override { blocked_urls_.clear(); }
   bool IsFull() override { return false; }
   bool loaded() const override { return false; }
   history::PrepopulatedPageList GetPrepopulatedPages() override {
@@ -44,240 +61,418 @@
 
   // Only runs a single callback, so that the test can specify a different
   // set per call.
-  void RunACallback(const history::MostVisitedURLList& urls) {
-    DCHECK(!callbacks.empty());
-    std::move(callbacks.front()).Run(urls);
-    callbacks.pop_front();
+  // Returns true if there was a recipient to receive the URLs and the list was
+  // emitted, otherwise returns false.
+  bool EmitURLs() {
+    if (callbacks_.empty())
+      return false;
+    std::move(callbacks_.front()).Run(std::move(urls_));
+    callbacks_.pop_front();
+    return true;
   }
 
+  history::MostVisitedURLList& urls() { return urls_; }
+  const std::set<std::string>& blocked_urls() const { return blocked_urls_; }
+
  protected:
   // A test-specific field for controlling when most visited callback is run
   // after top sites have been requested.
-  std::list<GetMostVisitedURLsCallback> callbacks;
+  std::list<GetMostVisitedURLsCallback> callbacks_;
+  history::MostVisitedURLList urls_;
+  std::set<std::string> blocked_urls_;
 
-  ~FakeEmptyTopSites() override = default;
+  ~FakeTopSites() override = default;
 };
 
-void FakeEmptyTopSites::GetMostVisitedURLs(
-    GetMostVisitedURLsCallback callback) {
-  callbacks.push_back(std::move(callback));
-}
-
-class FakeAutocompleteProviderClient : public MockAutocompleteProviderClient {
- public:
-  FakeAutocompleteProviderClient()
-      : template_url_service_(new TemplateURLService(nullptr, 0)),
-        top_sites_(new FakeEmptyTopSites()) {}
-  FakeAutocompleteProviderClient(const FakeAutocompleteProviderClient&) =
-      delete;
-  FakeAutocompleteProviderClient& operator=(
-      const FakeAutocompleteProviderClient&) = delete;
-
-  bool SearchSuggestEnabled() const override { return true; }
-
-  scoped_refptr<history::TopSites> GetTopSites() override { return top_sites_; }
-
-  TemplateURLService* GetTemplateURLService() override {
-    return template_url_service_.get();
-  }
-
-  TemplateURLService* GetTemplateURLService() const override {
-    return template_url_service_.get();
-  }
-
-  bool IsPersonalizedUrlDataCollectionActive() const override { return true; }
-
-  void Classify(
-      const std::u16string& text,
-      bool prefer_keyword,
-      bool allow_exact_keyword_match,
-      metrics::OmniboxEventProto::PageClassification page_classification,
-      AutocompleteMatch* match,
-      GURL* alternate_nav_url) override {
-    // Populate enough of |match| to keep the MostVisitedSitesProvider happy.
-    match->type = AutocompleteMatchType::URL_WHAT_YOU_TYPED;
-    match->destination_url = GURL(text);
-  }
-
-  const AutocompleteSchemeClassifier& GetSchemeClassifier() const override {
-    return scheme_classifier_;
-  }
-
- private:
-  std::unique_ptr<TemplateURLService> template_url_service_;
-  scoped_refptr<history::TopSites> top_sites_;
-  TestSchemeClassifier scheme_classifier_;
-};
-
+constexpr const auto* WEB_URL = u"https://example.com/";
+constexpr const auto* NTP_URL = u"chrome://newtab";
+constexpr const auto* SRP_URL = u"https://www.google.com/?q=flowers";
+constexpr const auto* FTP_URL = u"ftp://just.for.filtering.com";
 }  // namespace
 
 class MostVisitedSitesProviderTest : public testing::Test,
                                      public AutocompleteProviderListener {
  public:
-  MostVisitedSitesProviderTest() = default;
-  MostVisitedSitesProviderTest(const MostVisitedSitesProviderTest&) = delete;
-  MostVisitedSitesProviderTest& operator=(const MostVisitedSitesProviderTest&) =
-      delete;
-
   void SetUp() override;
 
  protected:
+  // Construct AutocompleteInput object a hypothetical Omnibox session context.
+  // Does not run any validation on the supplied values, allowing any
+  // combination (including invalid ones) to be used to create AutocompleteInput
+  // context object.
+  AutocompleteInput BuildAutocompleteInput(
+      const std::u16string& input_url,
+      const std::u16string& current_url,
+      metrics::OmniboxEventProto::PageClassification page_class,
+      OmniboxFocusType focus_type) {
+    AutocompleteInput input(input_url, page_class, TestSchemeClassifier());
+    input.set_focus_type(focus_type);
+    input.set_current_url(GURL(current_url));
+    return input;
+  }
+
+  // Helper method, constructing a valid AutocompleteInput object for a website
+  // visit.
+  AutocompleteInput BuildAutocompleteInputForWebOnFocus() {
+    return BuildAutocompleteInput(WEB_URL, WEB_URL,
+                                  metrics::OmniboxEventProto::OTHER,
+                                  OmniboxFocusType::ON_FOCUS);
+  }
+
+  // Iterate over all matches offered by the Provider and verify these against
+  // the supplied list of History URLs.
+  void CheckMatchesEquivalentTo(const history::MostVisitedURLList& urls,
+                                bool expect_tiles);
+
+  // Returns total number of all NAVSUGGEST and TILE_NAVSUGGEST elements.
+  size_t NumMostVisitedMatches();
+
+  // Returns the N-th match of a particular type, skipping over all matches of
+  // other types. If match of that type does not exist, or there are not enough
+  // elements of that type, this call returns null.
+  const AutocompleteMatch* GetMatch(AutocompleteMatchType::Type type,
+                                    size_t index);
+
   // AutocompleteProviderListener:
   void OnProviderUpdate(bool updated_matches) override;
 
-  std::unique_ptr<FakeAutocompleteProviderClient> client_;
+  base::test::TaskEnvironment task_environment_;
+  scoped_refptr<FakeTopSites> top_sites_;
+  scoped_refptr<FakeTopSites> top_sites_for_start_surface_;
   scoped_refptr<MostVisitedSitesProvider> provider_;
-
-  network::TestURLLoaderFactory* test_loader_factory() {
-    return client_->test_url_loader_factory();
-  }
-
-  GURL GetSuggestURL(
-      metrics::OmniboxEventProto::PageClassification page_classification) {
-    TemplateURLRef::SearchTermsArgs search_terms_args;
-    search_terms_args.page_classification = page_classification;
-    search_terms_args.focus_type = OmniboxFocusType::ON_FOCUS;
-    return RemoteSuggestionsService::EndpointUrl(
-        search_terms_args, client_->GetTemplateURLService());
-  }
-
-  AutocompleteInput CreateNTPOnFocusInputForRemoteNoUrl() {
-    // Use NTP as the page classification, since REMOTE_NO_URL is enabled by
-    // default for the NTP.
-    AutocompleteInput input(
-        std::u16string(),
-        metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS,
-        TestSchemeClassifier());
-    input.set_focus_type(OmniboxFocusType::ON_FOCUS);
-    return input;
-  }
+  base::test::ScopedFeatureList features_;
+  sync_preferences::TestingPrefServiceSyncable pref_service_;
+  std::unique_ptr<ntp_tiles::MostVisitedSites> ntp_top_sites_;
+  std::unique_ptr<AutocompleteController> controller_;
 };
 
+size_t MostVisitedSitesProviderTest::NumMostVisitedMatches() {
+  const auto& result = controller_->result();
+  size_t count = 0;
+  for (const auto& match : result) {
+    if ((match.type == AutocompleteMatchType::TILE_NAVSUGGEST) ||
+        (match.type == AutocompleteMatchType::NAVSUGGEST)) {
+      ++count;
+    }
+  }
+  return count;
+}
+
+const AutocompleteMatch* MostVisitedSitesProviderTest::GetMatch(
+    AutocompleteMatchType::Type type,
+    size_t index) {
+  const auto& result = controller_->result();
+  for (const auto& match : result) {
+    if (match.type == type) {
+      if (!index)
+        return &match;
+      --index;
+    }
+  }
+  return nullptr;
+}
+
+void MostVisitedSitesProviderTest::CheckMatchesEquivalentTo(
+    const history::MostVisitedURLList& urls,
+    bool expect_tiles) {
+  // Compare the AutocompleteResult against a set of URLs that we expect to see.
+  // Note that additional matches may be offered if other providers are also
+  // registered in the same category as MostVisitedSitesProvider.
+  // We ignore all matches that are not ours.
+  const auto& result = controller_->result();
+
+  size_t match_index = 0;
+
+  if (expect_tiles) {
+    ASSERT_EQ(1ul, NumMostVisitedMatches())
+        << "Expected only one TILE_NAVSUGGEST match";
+    for (const auto& match : result) {
+      if (match.type != AutocompleteMatchType::TILE_NAVSUGGEST)
+        continue;
+      const auto& tiles = match.navsuggest_tiles;
+      ASSERT_EQ(urls.size(), tiles.size()) << "Wrong number of tiles reported";
+      for (size_t index = 0u; index < urls.size(); index++) {
+        EXPECT_EQ(urls[index].url, tiles[index].url)
+            << "Invalid Tile URL at position " << index;
+        EXPECT_EQ(urls[index].title, tiles[index].title)
+            << "Invalid Tile Title at position " << index;
+      }
+      break;
+    }
+  } else {
+    ASSERT_EQ(urls.size(), NumMostVisitedMatches())
+        << "Unexpected number of NAVSUGGEST matches";
+    for (const auto& match : result) {
+      if (match.type != AutocompleteMatchType::NAVSUGGEST)
+        continue;
+
+      EXPECT_EQ(urls[match_index].url, match.destination_url)
+          << "Invalid Match URL at position " << match_index;
+      EXPECT_EQ(urls[match_index].title, match.description)
+          << "Invalid Match Title at position " << match_index;
+      ++match_index;
+    }
+  }
+}
+
 void MostVisitedSitesProviderTest::SetUp() {
-  client_ = std::make_unique<FakeAutocompleteProviderClient>();
-  provider_ = new MostVisitedSitesProvider(client_.get(), this);
+  ntp_tiles::MostVisitedSites::RegisterProfilePrefs(pref_service_.registry());
+  top_sites_ = new FakeTopSites();
+  top_sites_for_start_surface_ = new FakeTopSites();
+
+  // Note: std::make_unique<> fails here because it is unable to deduce argument
+  // types.
+  ntp_top_sites_.reset(new ntp_tiles::MostVisitedSites(
+      &pref_service_, top_sites_for_start_surface_, {}, {}, {}, {}, true));
+  auto client = std::make_unique<FakeAutocompleteProviderClient>();
+  client->set_top_sites(top_sites_);
+  client->set_ntp_most_visited_sites(ntp_top_sites_.get());
+
+  // For tests requiring direct interaction with the Provider.
+  provider_ = new MostVisitedSitesProvider(client.get(), this);
+
+  // For tests not requiring direct interaction with the Provider.
+  controller_ = std::make_unique<AutocompleteController>(
+      std::move(client), AutocompleteProvider::TYPE_MOST_VISITED_SITES);
+
+  // Inject a few URLs to
+  std::array<history::MostVisitedURL, 5> test_data{{
+      {GURL("http://www.a.art/"), u"A art"},
+      {GURL("http://www.b.biz/"), u"B biz"},
+      {GURL("http://www.c.com/"), u"C com"},
+      {GURL("http://www.d.de/"), u"D de"},
+      {GURL("http://www.e.edu/"), u"E edu"},
+  }};
+
+  top_sites_->urls().assign(test_data.begin(), test_data.end());
+  top_sites_for_start_surface_->urls().assign(test_data.rbegin(),
+                                              test_data.rend());
 }
 
 void MostVisitedSitesProviderTest::OnProviderUpdate(bool updated_matches) {}
 
 TEST_F(MostVisitedSitesProviderTest, AllowMostVisitedSitesSuggestions) {
-  std::string input_url = "https://example.com/";
-  std::string start_surface_url = "chrome://newtab";
-
-  AutocompleteInput prefix_input(base::ASCIIToUTF16(input_url),
-                                 metrics::OmniboxEventProto::OTHER,
-                                 TestSchemeClassifier());
-  prefix_input.set_focus_type(OmniboxFocusType::DEFAULT);
-
-  AutocompleteInput on_focus_input(base::ASCIIToUTF16(input_url),
-                                   metrics::OmniboxEventProto::OTHER,
-                                   TestSchemeClassifier());
-  on_focus_input.set_current_url(GURL(input_url));
-  on_focus_input.set_focus_type(OmniboxFocusType::ON_FOCUS);
-
-  AutocompleteInput on_clobber_input(std::u16string(),
-                                     metrics::OmniboxEventProto::OTHER,
-                                     TestSchemeClassifier());
-  on_clobber_input.set_current_url(GURL(input_url));
-  on_clobber_input.set_focus_type(OmniboxFocusType::DELETED_PERMANENT_TEXT);
-
-  AutocompleteInput start_surface_input(
-      std::u16string(), metrics::OmniboxEventProto::START_SURFACE_HOMEPAGE,
-      TestSchemeClassifier());
-  start_surface_input.set_current_url(GURL(start_surface_url));
-  start_surface_input.set_focus_type(OmniboxFocusType::ON_FOCUS);
-
-  AutocompleteInput start_surface_new_tab_input(
-      std::u16string(), metrics::OmniboxEventProto::START_SURFACE_NEW_TAB,
-      TestSchemeClassifier());
-  start_surface_new_tab_input.set_current_url(GURL());
-  start_surface_new_tab_input.set_focus_type(OmniboxFocusType::ON_FOCUS);
+  features_.InitAndDisableFeature(omnibox::kMostVisitedTiles);
+  using OEP = metrics::OmniboxEventProto;
+  using OFT = OmniboxFocusType;
 
   // MostVisited should never deal with prefix suggestions.
-  EXPECT_FALSE(provider_->AllowMostVisitedSitesSuggestions(prefix_input));
+  EXPECT_FALSE(provider_->AllowMostVisitedSitesSuggestions(
+      BuildAutocompleteInput(WEB_URL, WEB_URL, OEP::OTHER, OFT::DEFAULT)));
 
   // This should always be true, as otherwise we will break MostVisited.
-  EXPECT_TRUE(provider_->AllowMostVisitedSitesSuggestions(on_focus_input));
+  EXPECT_TRUE(provider_->AllowMostVisitedSitesSuggestions(
+      BuildAutocompleteInput(WEB_URL, WEB_URL, OEP::OTHER, OFT::ON_FOCUS)));
+
+  // Verifies that non-permitted schemes are rejected.
+  EXPECT_FALSE(provider_->AllowMostVisitedSitesSuggestions(
+      BuildAutocompleteInput(FTP_URL, FTP_URL, OEP::OTHER, OFT::ON_FOCUS)));
+
+  // Offer MV sites when the User is visiting a website and deletes text.
+  EXPECT_TRUE(
+      provider_->AllowMostVisitedSitesSuggestions(BuildAutocompleteInput(
+          WEB_URL, WEB_URL, OEP::OTHER, OFT::DELETED_PERMANENT_TEXT)));
 
   // Verifies that metrics::OmniboxEventProto::START_SURFACE_HOMEPAGE is allowed
   // for MostVisited.
-  EXPECT_TRUE(provider_->AllowMostVisitedSitesSuggestions(start_surface_input));
+  EXPECT_TRUE(
+      provider_->AllowMostVisitedSitesSuggestions(BuildAutocompleteInput(
+          {}, NTP_URL, OEP::START_SURFACE_HOMEPAGE, OFT::ON_FOCUS)));
 
   // Verifies that metrics::OmniboxEventProto::START_SURFACE_NEW_TAB is allowed
   // for MostVisited.
   EXPECT_TRUE(
-      provider_->AllowMostVisitedSitesSuggestions(start_surface_new_tab_input));
+      provider_->AllowMostVisitedSitesSuggestions(BuildAutocompleteInput(
+          {}, NTP_URL, OEP::START_SURFACE_NEW_TAB, OFT::ON_FOCUS)));
 }
 
 TEST_F(MostVisitedSitesProviderTest, TestMostVisitedCallback) {
-  std::string current_url("http://www.foxnews.com/");
-  std::string input_url("http://www.cnn.com/");
-  AutocompleteInput input(base::ASCIIToUTF16(input_url),
-                          metrics::OmniboxEventProto::OTHER,
-                          TestSchemeClassifier());
-  input.set_current_url(GURL(current_url));
-  input.set_focus_type(OmniboxFocusType::ON_FOCUS);
-  history::MostVisitedURLList urls;
-  history::MostVisitedURL url(GURL("http://foo.com/"), u"Foo");
-  urls.push_back(url);
+  features_.InitAndDisableFeature(omnibox::kMostVisitedTiles);
+  auto input = BuildAutocompleteInputForWebOnFocus();
+  controller_->Start(input);
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  CheckMatchesEquivalentTo(top_sites_->urls(), /* expect_tiles=*/false);
+  controller_->Stop(false);
 
-  provider_->Start(input, false);
-  EXPECT_TRUE(provider_->matches().empty());
-  scoped_refptr<history::TopSites> top_sites = client_->GetTopSites();
-  static_cast<FakeEmptyTopSites*>(top_sites.get())->RunACallback(urls);
-  EXPECT_EQ(1U, provider_->matches().size());
-  provider_->Stop(false, false);
+  controller_->Start(input);
+  controller_->Stop(false);
+  EXPECT_EQ(0u, NumMostVisitedMatches());
 
-  provider_->Start(input, false);
-  provider_->Stop(false, false);
-  EXPECT_TRUE(provider_->matches().empty());
   // Most visited results arriving after Stop() has been called, ensure they
   // are not displayed.
-  static_cast<FakeEmptyTopSites*>(top_sites.get())->RunACallback(urls);
-  EXPECT_TRUE(provider_->matches().empty());
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
 
-  history::MostVisitedURLList urls2;
-  urls2.push_back(history::MostVisitedURL(GURL("http://bar.com/"), u"Bar"));
-  urls2.push_back(history::MostVisitedURL(GURL("http://zinga.com/"), u"Zinga"));
-  provider_->Start(input, false);
-  provider_->Stop(false, false);
-  provider_->Start(input, false);
-  static_cast<FakeEmptyTopSites*>(top_sites.get())->RunACallback(urls);
+  controller_->Start(input);
+  controller_->Stop(false);
+  controller_->Start(input);
+
   // Stale results should get rejected.
-  EXPECT_TRUE(provider_->matches().empty());
-  static_cast<FakeEmptyTopSites*>(top_sites.get())->RunACallback(urls2);
-  EXPECT_FALSE(provider_->matches().empty());
-  provider_->Stop(false, false);
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+
+  // Results for the second Start() action should be recorded.
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  EXPECT_EQ(top_sites_->urls().size(), NumMostVisitedMatches());
+  controller_->Stop(false);
 }
 
 TEST_F(MostVisitedSitesProviderTest, TestMostVisitedNavigateToSearchPage) {
-  std::string current_url("http://www.foxnews.com/");
-  std::string input_url("http://www.cnn.com/");
-  AutocompleteInput input(base::ASCIIToUTF16(input_url),
-                          metrics::OmniboxEventProto::OTHER,
-                          TestSchemeClassifier());
-  input.set_current_url(GURL(current_url));
-  input.set_focus_type(OmniboxFocusType::ON_FOCUS);
-  history::MostVisitedURLList urls;
-  history::MostVisitedURL url(GURL("http://foo.com/"), u"Foo");
-  urls.push_back(url);
+  features_.InitAndDisableFeature(omnibox::kMostVisitedTiles);
 
-  provider_->Start(input, false);
-  EXPECT_TRUE(provider_->matches().empty());
+  controller_->Start(BuildAutocompleteInputForWebOnFocus());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
   // Stop() doesn't always get called.
 
-  std::string search_url("https://www.google.com/?q=flowers");
-  AutocompleteInput srp_input(
-      base::ASCIIToUTF16(search_url),
+  auto srp_input = BuildAutocompleteInput(
+      SRP_URL, SRP_URL,
       metrics::OmniboxEventProto::SEARCH_RESULT_PAGE_NO_SEARCH_TERM_REPLACEMENT,
-      TestSchemeClassifier());
-  srp_input.set_current_url(GURL(search_url));
-  srp_input.set_focus_type(OmniboxFocusType::ON_FOCUS);
+      OmniboxFocusType::ON_FOCUS);
 
-  provider_->Start(srp_input, false);
-  EXPECT_TRUE(provider_->matches().empty());
+  controller_->Start(srp_input);
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+
   // Most visited results arriving after a new request has been started.
-  scoped_refptr<history::TopSites> top_sites = client_->GetTopSites();
-  static_cast<FakeEmptyTopSites*>(top_sites.get())->RunACallback(urls);
-  EXPECT_TRUE(provider_->matches().empty());
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+}
+
+TEST_F(MostVisitedSitesProviderTest,
+       TestStartSurfaceSourcingTilesFromItsSource) {
+  controller_->Start(BuildAutocompleteInput(
+      {}, NTP_URL, metrics::OmniboxEventProto::START_SURFACE_HOMEPAGE,
+      OmniboxFocusType::ON_FOCUS));
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Start surface should not be waiting for old top_sites.
+  EXPECT_FALSE(top_sites_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Start surface should use its dedicated source instead.
+  EXPECT_TRUE(top_sites_for_start_surface_->EmitURLs());
+  CheckMatchesEquivalentTo(top_sites_for_start_surface_->urls(),
+                           /* expect_tiles=*/true);
+}
+
+TEST_F(MostVisitedSitesProviderTest,
+       TestDeleteMostVisitedElementForStartSurface) {
+  // Make a copy (intentional - we'll modify this later)
+  auto urls = top_sites_for_start_surface_->urls();
+  controller_->Start(BuildAutocompleteInput(
+      {}, NTP_URL, metrics::OmniboxEventProto::START_SURFACE_HOMEPAGE,
+      OmniboxFocusType::ON_FOCUS));
+
+  EXPECT_TRUE(top_sites_for_start_surface_->EmitURLs());
+  CheckMatchesEquivalentTo(urls, /* expect_tiles=*/true);
+
+  // Delete tile #3
+  auto* match = GetMatch(AutocompleteMatchType::TILE_NAVSUGGEST, 0);
+  ASSERT_NE(nullptr, match) << "No TILE_NAVSUGGEST Match found";
+  controller_->DeleteMatchElement(*match, 2);
+
+  // Observe that the URL is now blocked and removed from suggestion.
+  auto deleted_url = urls[2].url;
+  urls.erase(urls.begin() + 2);
+  CheckMatchesEquivalentTo(urls, /* expect_tiles=*/true);
+  // Note: when Start Surface is being used, we want to make sure we delete
+  // tiles from all sources.
+  EXPECT_TRUE(top_sites_->IsBlocked(deleted_url));
+  EXPECT_TRUE(top_sites_for_start_surface_->IsBlocked(deleted_url));
+}
+
+class ParameterizedMostVisitedSitesProviderTest
+    : public MostVisitedSitesProviderTest,
+      public ::testing::WithParamInterface<bool> {
+  void SetUp() override {
+    MostVisitedSitesProviderTest::SetUp();
+    features_.InitWithFeatureState(omnibox::kMostVisitedTiles, GetParam());
+  }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         ParameterizedMostVisitedSitesProviderTest,
+                         ::testing::Bool(),
+                         [](const auto& info) {
+                           return info.param ? "SingleMatchWithTiles"
+                                             : "IndividualMatches";
+                         });
+
+TEST_P(ParameterizedMostVisitedSitesProviderTest, TestCreateMostVisitedMatch) {
+  controller_->Start(BuildAutocompleteInputForWebOnFocus());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Confirm that the StartSurface source is rejected.
+  EXPECT_FALSE(top_sites_for_start_surface_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Accept only direct TopSites data.
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  CheckMatchesEquivalentTo(top_sites_->urls(), GetParam());
+}
+
+TEST_P(ParameterizedMostVisitedSitesProviderTest,
+       NoMatchesWhenNoMostVisitedSites) {
+  // Start with no URLs.
+  top_sites_->urls().clear();
+  controller_->Start(BuildAutocompleteInputForWebOnFocus());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Confirm that the StartSurface source is rejected.
+  EXPECT_FALSE(top_sites_for_start_surface_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Accept only direct TopSites data, confirm no matches are built.
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+}
+
+TEST_P(ParameterizedMostVisitedSitesProviderTest,
+       TestDeleteMostVisitedElement) {
+  // Make a copy (intentional - we'll modify this later)
+  auto urls = top_sites_->urls();
+  controller_->Start(BuildAutocompleteInputForWebOnFocus());
+  // Confirm that the StartSurface source is rejected.
+  EXPECT_FALSE(top_sites_for_start_surface_->EmitURLs());
+  EXPECT_EQ(0u, NumMostVisitedMatches());
+  // Accept only direct TopSites data.
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  CheckMatchesEquivalentTo(urls, GetParam());
+
+  // Commence delete.
+  if (GetParam()) {
+    auto* match = GetMatch(AutocompleteMatchType::TILE_NAVSUGGEST, 0);
+    ASSERT_NE(nullptr, match) << "No TILE_NAVSUGGEST Match found";
+    controller_->DeleteMatchElement(*match, 1);
+  } else {
+    auto* match = GetMatch(AutocompleteMatchType::NAVSUGGEST, 1);
+    ASSERT_NE(nullptr, match) << "No NAVSUGGEST Match found";
+    controller_->DeleteMatch(*match);
+  }
+
+  // Observe that the URL is now blocked and removed from suggestion.
+  auto deleted_url = urls[1].url;
+  urls.erase(urls.begin() + 1);
+  CheckMatchesEquivalentTo(urls, GetParam());
+  EXPECT_TRUE(top_sites_->IsBlocked(deleted_url));
+}
+
+TEST_P(ParameterizedMostVisitedSitesProviderTest,
+       NoMatchesWhenLastURLIsDeleted) {
+  // Start with just one URL.
+  auto& urls = top_sites_->urls();
+  urls.clear();
+  urls.emplace_back(GURL("http://www.a.art/"), u"A art");
+
+  controller_->Start(BuildAutocompleteInputForWebOnFocus());
+  EXPECT_TRUE(top_sites_->EmitURLs());
+  CheckMatchesEquivalentTo(urls, GetParam());
+
+  // Commence delete of the only item that we have.
+  if (GetParam()) {
+    auto* match = GetMatch(AutocompleteMatchType::TILE_NAVSUGGEST, 0);
+    ASSERT_NE(nullptr, match) << "No TILE_NAVSUGGEST Match found";
+    controller_->DeleteMatchElement(*match, 0);
+  } else {
+    auto* match = GetMatch(AutocompleteMatchType::NAVSUGGEST, 0);
+    ASSERT_NE(nullptr, match) << "No NAVSUGGEST Match found";
+    controller_->DeleteMatch(*match);
+  }
+
+  // Confirm no more NAVSUGGEST matches are offered.
+  EXPECT_EQ(0u, NumMostVisitedMatches());
 }
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc
index 0363848..e95e77a 100644
--- a/components/omnibox/browser/search_suggestion_parser.cc
+++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -699,8 +699,9 @@
         const std::string* answer_type =
             suggestion_detail.FindStringKey("ansb");
         if (answer_json && answer_type) {
-          if (SuggestionAnswer::ParseAnswer(
-                  *answer_json, base::UTF8ToUTF16(*answer_type), &answer)) {
+          if (SuggestionAnswer::ParseAnswer(answer_json->GetDict(),
+                                            base::UTF8ToUTF16(*answer_type),
+                                            &answer)) {
             base::UmaHistogramSparse("Omnibox.AnswerParseType", answer.type());
             answer_parsed_successfully = true;
           }
diff --git a/components/omnibox/browser/suggestion_answer.cc b/components/omnibox/browser/suggestion_answer.cc
index 18cab71..486533f5 100644
--- a/components/omnibox/browser/suggestion_answer.cc
+++ b/components/omnibox/browser/suggestion_answer.cc
@@ -15,7 +15,6 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
-#include "base/values.h"
 #include "build/build_config.h"
 #include "net/base/escape.h"
 #include "url/url_constants.h"
@@ -66,19 +65,17 @@
     TextField&&) noexcept = default;
 
 // static
-bool SuggestionAnswer::TextField::ParseTextField(const base::Value& field_json,
-                                                 TextField* text_field) {
-  if (!field_json.is_dict()) {
-    return false;
-  }
-  const std::string* text = field_json.FindStringKey(kAnswerJsonText);
-  absl::optional<int> type = field_json.FindIntKey(kAnswerJsonTextType);
+bool SuggestionAnswer::TextField::ParseTextField(
+    const base::Value::Dict& field_json,
+    TextField* text_field) {
+  const std::string* text = field_json.FindString(kAnswerJsonText);
+  absl::optional<int> type = field_json.FindInt(kAnswerJsonTextType);
   const bool parsed = text && !text->empty() && type;
   if (parsed) {
     text_field->type_ = *type;
     text_field->text_ = net::UnescapeForHTML(base::UTF8ToUTF16(*text));
 
-    absl::optional<int> num_lines = field_json.FindIntKey(kAnswerJsonNumLines);
+    absl::optional<int> num_lines = field_json.FindInt(kAnswerJsonNumLines);
     text_field->has_num_lines_ = num_lines.has_value();
     if (num_lines) {
       text_field->has_num_lines_ = true;
@@ -115,28 +112,25 @@
 SuggestionAnswer::ImageLine::~ImageLine() {}
 
 // static
-bool SuggestionAnswer::ImageLine::ParseImageLine(const base::Value& line_json,
-                                                 ImageLine* image_line) {
-  if (!line_json.is_dict()) {
-    return false;
-  }
-  const base::Value* inner_json = line_json.FindKeyOfType(
-      kAnswerJsonImageLine, base::Value::Type::DICTIONARY);
-  if (!inner_json || !inner_json->is_dict()) {
+bool SuggestionAnswer::ImageLine::ParseImageLine(
+    const base::Value::Dict& line_json,
+    ImageLine* image_line) {
+  const base::Value::Dict* inner_json =
+      line_json.FindDict(kAnswerJsonImageLine);
+  if (!inner_json) {
     return false;
   }
 
-  const base::Value* fields_json =
-      inner_json->FindKeyOfType(kAnswerJsonText, base::Value::Type::LIST);
-  if (!fields_json || fields_json->GetListDeprecated().empty()) {
+  const base::Value::List* fields_json = inner_json->FindList(kAnswerJsonText);
+  if (!fields_json || fields_json->empty()) {
     return false;
   }
 
   bool found_num_lines = false;
-  for (const base::Value& field_json : fields_json->GetListDeprecated()) {
+  for (const base::Value& field_json : *fields_json) {
     TextField text_field;
     if (!field_json.is_dict() ||
-        !TextField::ParseTextField(field_json, &text_field)) {
+        !TextField::ParseTextField(field_json.GetDict(), &text_field)) {
       return false;
     }
 
@@ -147,32 +141,30 @@
     }
   }
 
-  const base::Value* additional_text_json =
-      inner_json->FindKey(kAnswerJsonAdditionalText);
+  const base::Value::Dict* additional_text_json =
+      inner_json->FindDict(kAnswerJsonAdditionalText);
   if (additional_text_json) {
     image_line->additional_text_ = TextField();
-    if (!additional_text_json->is_dict() ||
-        !TextField::ParseTextField(*additional_text_json,
+    if (!TextField::ParseTextField(*additional_text_json,
                                    &image_line->additional_text_.value())) {
       return false;
     }
   }
 
-  const base::Value* status_text_json =
-      inner_json->FindKey(kAnswerJsonStatusText);
+  const base::Value::Dict* status_text_json =
+      inner_json->FindDict(kAnswerJsonStatusText);
   if (status_text_json) {
     image_line->status_text_ = TextField();
-    if (!status_text_json->is_dict() ||
-        !TextField::ParseTextField(*status_text_json,
+    if (!TextField::ParseTextField(*status_text_json,
                                    &image_line->status_text_.value())) {
       return false;
     }
   }
 
-  const base::Value* image_json = inner_json->FindKey(kAnswerJsonImage);
-  if (image_json && image_json->is_dict()) {
+  const base::Value::Dict* image_json = inner_json->FindDict(kAnswerJsonImage);
+  if (image_json) {
     const std::string* url_string =
-        image_json->FindStringKey(kAnswerJsonImageData);
+        image_json->FindString(kAnswerJsonImageData);
     if (!url_string || url_string->empty()) {
       return false;
     }
@@ -299,12 +291,9 @@
 SuggestionAnswer::~SuggestionAnswer() = default;
 
 // static
-bool SuggestionAnswer::ParseAnswer(const base::Value& answer_json,
+bool SuggestionAnswer::ParseAnswer(const base::Value::Dict& answer_json,
                                    const std::u16string& answer_type_str,
                                    SuggestionAnswer* result) {
-  if (!answer_json.is_dict()) {
-    return false;
-  }
   int answer_type = 0;
   if (!base::StringToInt(answer_type_str, &answer_type)) {
     return false;
@@ -312,29 +301,26 @@
 
   result->set_type(answer_type);
 
-  const base::Value* lines_json =
-      answer_json.FindKeyOfType(kAnswerJsonLines, base::Value::Type::LIST);
-  if (!lines_json || lines_json->GetListDeprecated().size() != 2) {
+  const base::Value::List* lines_json = answer_json.FindList(kAnswerJsonLines);
+  if (!lines_json || lines_json->size() != 2) {
     return false;
   }
 
-  const base::Value& first_line_json = lines_json->GetListDeprecated()[0];
-  if (!first_line_json.is_dict() ||
-      !ImageLine::ParseImageLine(first_line_json, &result->first_line_)) {
+  const base::Value::Dict* first_line_dict = (*lines_json)[0].GetIfDict();
+  if (!first_line_dict ||
+      !ImageLine::ParseImageLine(*first_line_dict, &result->first_line_)) {
     return false;
   }
 
-  const base::Value& second_line_json = lines_json->GetListDeprecated()[1];
-  if (!second_line_json.is_dict() ||
-      !ImageLine::ParseImageLine(second_line_json, &result->second_line_)) {
+  const base::Value::Dict* second_line_dict = (*lines_json)[1].GetIfDict();
+  if (!second_line_dict ||
+      !ImageLine::ParseImageLine(*second_line_dict, &result->second_line_)) {
     return false;
   }
 
   const std::string* image_url;
-  const base::Value* optional_image =
-      answer_json.FindKeyOfType("i", base::Value::Type::DICTIONARY);
-  if (optional_image && optional_image->is_dict() &&
-      (image_url = optional_image->FindStringKey("d"))) {
+  const base::Value::Dict* optional_image = answer_json.FindDict("i");
+  if (optional_image && (image_url = optional_image->FindString("d"))) {
     result->image_url_ = GURL(*image_url);
   } else {
     result->image_url_ = result->second_line_.image_url();
diff --git a/components/omnibox/browser/suggestion_answer.h b/components/omnibox/browser/suggestion_answer.h
index 92f86029..27fa624 100644
--- a/components/omnibox/browser/suggestion_answer.h
+++ b/components/omnibox/browser/suggestion_answer.h
@@ -11,6 +11,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/memory/ptr_util.h"
+#include "base/values.h"
 #include "build/build_config.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
@@ -19,10 +20,6 @@
 #include "base/android/scoped_java_ref.h"
 #endif
 
-namespace base {
-class Value;
-}
-
 // Structured representation of the JSON payload of a suggestion with an answer.
 // An answer has exactly two image lines, so called because they are a
 // combination of text and an optional image URL.  Each image line has 1 or more
@@ -133,7 +130,7 @@
     // Parses |field_json| dictionary and populates |text_field| with the
     // contents.  If any of the required elements is missing, returns false and
     // leaves text_field in a partially populated state.
-    static bool ParseTextField(const base::Value& field_json,
+    static bool ParseTextField(const base::Value::Dict& field_json,
                                TextField* text_field);
 
     const std::u16string& text() const { return text_; }
@@ -174,7 +171,7 @@
     // Parses dictionary |line_json| and populates |image_line| with the
     // contents.  If any of the required elements is missing, returns false and
     // leaves text_field in a partially populated state.
-    static bool ParseImageLine(const base::Value& line_json,
+    static bool ParseImageLine(const base::Value::Dict& line_json,
                                ImageLine* image_line);
 
     const TextFields& text_fields() const { return text_fields_; }
@@ -227,7 +224,7 @@
   // Parses dictionary |answer_json| and fills a SuggestionAnswer containing the
   // contents. Returns true on success. If the supplied data is not well formed
   // or is missing required elements, returns false instead.
-  static bool ParseAnswer(const base::Value& answer_json,
+  static bool ParseAnswer(const base::Value::Dict& answer_json,
                           const std::u16string& answer_type_str,
                           SuggestionAnswer* answer);
 
diff --git a/components/omnibox/browser/suggestion_answer_unittest.cc b/components/omnibox/browser/suggestion_answer_unittest.cc
index 19426ae9..fdfcd55 100644
--- a/components/omnibox/browser/suggestion_answer_unittest.cc
+++ b/components/omnibox/browser/suggestion_answer_unittest.cc
@@ -22,7 +22,7 @@
 
   // ParseAnswer previously did not change the default answer type of -1, so
   // here we keep the same behavior by explicitly supplying default value.
-  return SuggestionAnswer::ParseAnswer(*value, u"-1", answer);
+  return SuggestionAnswer::ParseAnswer(value->GetDict(), u"-1", answer);
 }
 
 }  // namespace
diff --git a/components/optimization_guide/core/model_handler.h b/components/optimization_guide/core/model_handler.h
index d18c87e2..b172d9e 100644
--- a/components/optimization_guide/core/model_handler.h
+++ b/components/optimization_guide/core/model_handler.h
@@ -48,6 +48,12 @@
     DCHECK_NE(optimization_target_,
               proto::OptimizationTarget::OPTIMIZATION_TARGET_UNKNOWN);
 
+    base::UmaHistogramBoolean(
+        "OptimizationGuide.ModelHandler.HandlerCreated." +
+            GetStringNameForOptimizationTarget(optimization_target_),
+        true);
+
+    handler_created_time_ = base::TimeTicks::Now();
     model_provider_->AddObserverForOptimizationTargetModel(
         optimization_target_, model_metadata, this);
     model_executor_->InitializeAndMoveToExecutionThread(
@@ -119,6 +125,14 @@
     if (optimization_target_ != optimization_target)
       return;
 
+    if (handler_created_time_) {
+      base::UmaHistogramMediumTimes(
+          "OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable." +
+              GetStringNameForOptimizationTarget(optimization_target_),
+          base::TimeTicks::Now() - *handler_created_time_);
+      handler_created_time_ = absl::nullopt;
+    }
+
     model_info_ = model_info;
     model_available_ = true;
 
@@ -202,6 +216,13 @@
 
   const proto::OptimizationTarget optimization_target_;
 
+  // The time that |optimization_target_| was registered wih |model_provider_|
+  // when |this| is created.
+  //
+  // Will only be non-nullopt if a model has not been received yet after the
+  // target was registered.
+  absl::optional<base::TimeTicks> handler_created_time_;
+
   // The owned model executor.
   std::unique_ptr<ModelExecutor<OutputType, InputTypes...>> model_executor_;
 
diff --git a/components/optimization_guide/core/model_handler_unittest.cc b/components/optimization_guide/core/model_handler_unittest.cc
index 181cb44..ab6f9498 100644
--- a/components/optimization_guide/core/model_handler_unittest.cc
+++ b/components/optimization_guide/core/model_handler_unittest.cc
@@ -118,14 +118,21 @@
 };
 
 TEST_F(ModelHandlerTest, ObserverIsAttachedCorrectly) {
+  base::HistogramTester histogram_tester;
+
   CreateModelHandler();
   EXPECT_TRUE(model_observer_tracker()->add_observer_called());
 
   ResetModelHandler();
   EXPECT_TRUE(model_observer_tracker()->remove_observer_called());
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelHandler.HandlerCreated.PainfulPageLoad", true, 1);
 }
 
 TEST_F(ModelHandlerTest, ModelFileUpdatedWrongTarget) {
+  base::HistogramTester histogram_tester;
+
   CreateModelHandler();
 
   PushModelFileToModelExecutor(
@@ -133,9 +140,18 @@
       /*model_metadata=*/absl::nullopt);
 
   EXPECT_FALSE(model_handler()->ModelAvailable());
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelHandler.HandlerCreated.PainfulPageLoad", true, 1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable."
+      "PainfulPageLoad",
+      0);
 }
 
 TEST_F(ModelHandlerTest, ParsedSupportedFeaturesForLoadedModelNoMetadata) {
+  base::HistogramTester histogram_tester;
+
   CreateModelHandler();
 
   PushModelFileToModelExecutor(
@@ -147,6 +163,33 @@
   EXPECT_FALSE(model_handler()
                    ->ParsedSupportedFeaturesForLoadedModel<proto::Duration>()
                    .has_value());
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelHandler.HandlerCreated.PainfulPageLoad", true, 1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable."
+      "PainfulPageLoad",
+      1);
+}
+
+TEST_F(ModelHandlerTest, MultipleModelUpdatesOnlyRecordsMetricOnce) {
+  base::HistogramTester histogram_tester;
+
+  CreateModelHandler();
+
+  PushModelFileToModelExecutor(
+      proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD,
+      /*model_metadata=*/absl::nullopt);
+  PushModelFileToModelExecutor(
+      proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD,
+      /*model_metadata=*/absl::nullopt);
+
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.ModelHandler.HandlerCreated.PainfulPageLoad", true, 1);
+  histogram_tester.ExpectTotalCount(
+      "OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable."
+      "PainfulPageLoad",
+      1);
 }
 
 TEST_F(ModelHandlerTest, ParsedSupportedFeaturesForLoadedModelWithMetadata) {
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java
index e9844c6..a1c42a8 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java
@@ -70,7 +70,7 @@
     public void setParams(PageInfoCookiesViewParams params) {
         Preference cookieSummary = findPreference(COOKIE_SUMMARY_PREFERENCE);
         NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan(
-                getResources(), (view) -> { params.onCookieSettingsLinkClicked.run(); });
+                getContext(), (view) -> { params.onCookieSettingsLinkClicked.run(); });
         cookieSummary.setSummary(
                 SpanApplier.applySpans(getString(R.string.page_info_cookies_description),
                         new SpanApplier.SpanInfo("<link>", "</link>", linkSpan)));
diff --git a/components/payments/content/service_worker_payment_app_factory.cc b/components/payments/content/service_worker_payment_app_factory.cc
index 68efab99..64f1591 100644
--- a/components/payments/content/service_worker_payment_app_factory.cc
+++ b/components/payments/content/service_worker_payment_app_factory.cc
@@ -24,18 +24,6 @@
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 
 namespace payments {
-namespace {
-
-std::vector<mojom::PaymentMethodDataPtr> Clone(
-    const std::vector<mojom::PaymentMethodDataPtr>& original) {
-  std::vector<mojom::PaymentMethodDataPtr> clone(original.size());
-  std::transform(
-      original.begin(), original.end(), clone.begin(),
-      [](const mojom::PaymentMethodDataPtr& item) { return item.Clone(); });
-  return clone;
-}
-
-}  // namespace
 
 class ServiceWorkerPaymentAppCreator {
  public:
@@ -202,7 +190,7 @@
       ->GetAllPaymentApps(
           delegate->GetFrameSecurityOrigin(),
           delegate->GetPaymentManifestWebDataService(),
-          Clone(delegate->GetMethodData()),
+          mojo::Clone(delegate->GetMethodData()),
           delegate->MayCrawlForInstallablePaymentApps(),
           base::BindOnce(&ServiceWorkerPaymentAppCreator::CreatePaymentApps,
                          creator_raw_pointer->GetWeakPtr()),
diff --git a/components/pdf/renderer/pdf_view_web_plugin_client.cc b/components/pdf/renderer/pdf_view_web_plugin_client.cc
index 7a283e0..b5cdff96 100644
--- a/components/pdf/renderer/pdf_view_web_plugin_client.cc
+++ b/components/pdf/renderer/pdf_view_web_plugin_client.cc
@@ -8,6 +8,7 @@
 #include "components/pdf/renderer/pdf_accessibility_tree.h"
 #include "content/public/common/use_zoom_for_dsf_policy.h"
 #include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/v8_value_converter.h"
 #include "printing/buildflags/buildflags.h"
 #include "third_party/blink/public/web/web_element.h"
 
@@ -19,12 +20,30 @@
 
 PdfViewWebPluginClient::PdfViewWebPluginClient(
     content::RenderFrame* render_frame)
-    : render_frame_(render_frame) {
+    : render_frame_(render_frame),
+      v8_value_converter_(content::V8ValueConverter::Create()) {
   DCHECK(render_frame_);
 }
 
 PdfViewWebPluginClient::~PdfViewWebPluginClient() = default;
 
+std::unique_ptr<base::Value> PdfViewWebPluginClient::FromV8Value(
+    v8::Local<v8::Value> value,
+    v8::Local<v8::Context> context) {
+  return v8_value_converter_->FromV8Value(value, context);
+}
+
+v8::Local<v8::Value> PdfViewWebPluginClient::ToV8Value(
+    const base::Value& value,
+    v8::Local<v8::Context> context) {
+  return v8_value_converter_->ToV8Value(&value, context);
+}
+
+base::WeakPtr<chrome_pdf::PdfViewWebPlugin::Client>
+PdfViewWebPluginClient::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
 void PdfViewWebPluginClient::Print(const blink::WebElement& element) {
   DCHECK(!element.IsNull());
 #if BUILDFLAG(ENABLE_PRINTING)
diff --git a/components/pdf/renderer/pdf_view_web_plugin_client.h b/components/pdf/renderer/pdf_view_web_plugin_client.h
index efa7bd28..f8b511fb 100644
--- a/components/pdf/renderer/pdf_view_web_plugin_client.h
+++ b/components/pdf/renderer/pdf_view_web_plugin_client.h
@@ -5,11 +5,15 @@
 #ifndef COMPONENTS_PDF_RENDERER_PDF_VIEW_WEB_PLUGIN_CLIENT_H_
 #define COMPONENTS_PDF_RENDERER_PDF_VIEW_WEB_PLUGIN_CLIENT_H_
 
+#include <memory>
+
+#include "base/memory/weak_ptr.h"
 #include "pdf/pdf_view_web_plugin.h"
 
 namespace content {
 class RenderFrame;
-}
+class V8ValueConverter;
+}  // namespace content
 
 namespace pdf {
 
@@ -21,6 +25,12 @@
   ~PdfViewWebPluginClient() override;
 
   // chrome_pdf::PdfViewWebPlugin::Client:
+  std::unique_ptr<base::Value> FromV8Value(
+      v8::Local<v8::Value> value,
+      v8::Local<v8::Context> context) override;
+  v8::Local<v8::Value> ToV8Value(const base::Value& value,
+                                 v8::Local<v8::Context> context) override;
+  base::WeakPtr<chrome_pdf::PdfViewWebPlugin::Client> GetWeakPtr() override;
   void Print(const blink::WebElement& element) override;
   void RecordComputedAction(const std::string& action) override;
   std::unique_ptr<chrome_pdf::PdfAccessibilityDataHandler>
@@ -30,6 +40,10 @@
 
  private:
   content::RenderFrame* const render_frame_;
+
+  const std::unique_ptr<content::V8ValueConverter> v8_value_converter_;
+
+  base::WeakPtrFactory<PdfViewWebPluginClient> weak_factory_{this};
 };
 
 }  // namespace pdf
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/BluetoothChooserDialog.java b/components/permissions/android/java/src/org/chromium/components/permissions/BluetoothChooserDialog.java
index 25a8e1a2..84a1539 100644
--- a/components/permissions/android/java/src/org/chromium/components/permissions/BluetoothChooserDialog.java
+++ b/components/permissions/android/java/src/org/chromium/components/permissions/BluetoothChooserDialog.java
@@ -347,7 +347,7 @@
 
     private NoUnderlineClickableSpan createLinkSpan(@LinkType int linkType) {
         return new NoUnderlineClickableSpan(
-                mContext.getResources(), (view) -> onBluetoothLinkClick(view, linkType));
+                mContext, (view) -> onBluetoothLinkClick(view, linkType));
     }
 
     private void onBluetoothLinkClick(View view, @LinkType int linkType) {
diff --git a/components/printing/browser/print_composite_client.cc b/components/printing/browser/print_composite_client.cc
index 35028f21..16582e1 100644
--- a/components/printing/browser/print_composite_client.cc
+++ b/components/printing/browser/print_composite_client.cc
@@ -16,6 +16,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/service_process_host.h"
@@ -103,21 +104,19 @@
 }
 
 PrintCompositeClient::RequestedSubFrame::RequestedSubFrame(
-    int render_process_id,
-    int render_frame_id,
+    content::GlobalRenderFrameHostId rfh_id,
     int document_cookie,
     mojom::DidPrintContentParamsPtr params,
     bool is_live)
-    : render_process_id_(render_process_id),
-      render_frame_id_(render_frame_id),
+    : rfh_id_(rfh_id),
       document_cookie_(document_cookie),
       params_(std::move(params)),
       is_live_(is_live) {}
+
 PrintCompositeClient::RequestedSubFrame::~RequestedSubFrame() = default;
 
 void PrintCompositeClient::OnDidPrintFrameContent(
-    int render_process_id,
-    int render_frame_id,
+    content::GlobalRenderFrameHostId rfh_id,
     int document_cookie,
     mojom::DidPrintContentParamsPtr params) {
   auto* outer_contents = web_contents()->GetOuterWebContents();
@@ -130,8 +129,8 @@
     // contents nested in multiple layers.
     auto* outer_client = PrintCompositeClient::FromWebContents(outer_contents);
     DCHECK(outer_client);
-    outer_client->OnDidPrintFrameContent(render_process_id, render_frame_id,
-                                         document_cookie, std::move(params));
+    outer_client->OnDidPrintFrameContent(rfh_id, document_cookie,
+                                         std::move(params));
     return;
   }
 
@@ -140,14 +139,12 @@
       // Queues the subframe information to |requested_subframes_| to handle it
       // after |compositor_| is created by the main frame.
       requested_subframes_.insert(std::make_unique<RequestedSubFrame>(
-          render_process_id, render_frame_id, document_cookie,
-          std::move(params), true));
+          rfh_id, document_cookie, std::move(params), /*is_live=*/true));
     }
     return;
   }
 
-  auto* render_frame_host =
-      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+  auto* render_frame_host = content::RenderFrameHost::FromID(rfh_id);
   if (!render_frame_host)
     return;
 
@@ -188,8 +185,8 @@
         // Queues the subframe information to |requested_subframes_| to handle
         // it after |compositor_| is created by the main frame.
         requested_subframes_.insert(std::make_unique<RequestedSubFrame>(
-            subframe_host->GetProcess()->GetID(), subframe_host->GetRoutingID(),
-            document_cookie, nullptr, false));
+            subframe_host->GetGlobalId(), document_cookie, /*params=*/nullptr,
+            /*is_live=*/false));
       }
       return;
     }
@@ -213,8 +210,7 @@
           std::move(params),
           base::BindOnce(&PrintCompositeClient::OnDidPrintFrameContent,
                          weak_ptr_factory_.GetWeakPtr(),
-                         subframe_host->GetProcess()->GetID(),
-                         subframe_host->GetRoutingID()));
+                         subframe_host->GetGlobalId()));
   pending_subframes_.insert(subframe_host);
 }
 
@@ -287,13 +283,11 @@
     if (!IsDocumentCookieValid(requested->document_cookie_))
       continue;
     if (requested->is_live_) {
-      OnDidPrintFrameContent(
-          requested->render_process_id_, requested->render_frame_id_,
-          requested->document_cookie_, std::move(requested->params_));
+      OnDidPrintFrameContent(requested->rfh_id_, requested->document_cookie_,
+                             std::move(requested->params_));
     } else {
-      compositor->NotifyUnavailableSubframe(
-          GenerateFrameGuid(content::RenderFrameHost::FromID(
-              requested->render_process_id_, requested->render_frame_id_)));
+      compositor->NotifyUnavailableSubframe(GenerateFrameGuid(
+          content::RenderFrameHost::FromID(requested->rfh_id_)));
     }
   }
   requested_subframes_.clear();
diff --git a/components/printing/browser/print_composite_client.h b/components/printing/browser/print_composite_client.h
index cd70c02..27479ce8 100644
--- a/components/printing/browser/print_composite_client.h
+++ b/components/printing/browser/print_composite_client.h
@@ -15,6 +15,7 @@
 #include "build/build_config.h"
 #include "components/printing/common/print.mojom.h"
 #include "components/services/print_compositor/public/mojom/print_compositor.mojom.h"
+#include "content/public/browser/global_routing_id.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
@@ -121,8 +122,7 @@
       mojom::PrintCompositor::Status status,
       base::ReadOnlySharedMemoryRegion region);
 
-  void OnDidPrintFrameContent(int render_process_id,
-                              int render_frame_id,
+  void OnDidPrintFrameContent(content::GlobalRenderFrameHostId rfh_id,
                               int document_cookie,
                               mojom::DidPrintContentParamsPtr params);
 
@@ -173,18 +173,15 @@
   base::flat_set<content::RenderFrameHost*> printed_subframes_;
 
   struct RequestedSubFrame {
-    RequestedSubFrame(int render_process_id,
-                      int render_frame_id,
+    RequestedSubFrame(content::GlobalRenderFrameHostId rfh_id,
                       int document_cookie,
                       mojom::DidPrintContentParamsPtr params,
                       bool is_live);
     ~RequestedSubFrame();
-    RequestedSubFrame(const PrintCompositeClient::RequestedSubFrame&) = delete;
-    RequestedSubFrame& operator=(
-        const PrintCompositeClient::RequestedSubFrame&) = delete;
+    RequestedSubFrame(const RequestedSubFrame&) = delete;
+    RequestedSubFrame& operator=(const RequestedSubFrame&) = delete;
 
-    int render_process_id_;
-    int render_frame_id_;
+    content::GlobalRenderFrameHostId rfh_id_;
     int document_cookie_;
     mojom::DidPrintContentParamsPtr params_;
     bool is_live_;
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.cc b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.cc
index e6abe430..7eed0595 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.cc
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.cc
@@ -30,6 +30,9 @@
 content::CommitDeferringCondition::Result
 PasswordProtectionCommitDeferringCondition::WillCommitNavigation(
     base::OnceClosure resume) {
+  if (invoke_callback_for_testing_)
+    std::move(invoke_callback_for_testing_).Run();
+
   // The request may have asked for a resumption before this condition was
   // executed. In that case, proceed without deferring.
   if (navigation_was_resumed_)
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h
index 52a086f..6892fec 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h
@@ -56,9 +56,12 @@
   // WillCommitNavigation will not defer the commit.
   void ResumeNavigation();
 
-  // Returns whether the NavigationHandle tried to commit but was deferred from
-  // doing so by this condition.
-  bool is_deferred_for_testing() const { return !resume_.is_null(); }
+  // For testing only. Registers a callback that will be invoked when
+  // WillCommitNavigatoin is called by the navigation. This is useful for
+  // yielding in a test when this condition is invoked.
+  void register_invoke_callback_for_testing(base::OnceClosure callback) {
+    invoke_callback_for_testing_ = std::move(callback);
+  }
 
  private:
   // A pointer to the PasswordProtectionRequestContent on whose behalf this
@@ -70,6 +73,8 @@
   // CommitDeferringCondition.
   base::OnceClosure resume_;
 
+  base::OnceClosure invoke_callback_for_testing_;
+
   // Set to true to indicate the request has asked to resume the navigation,
   // i.e. the request result didn't result in a modal being shown, or the user
   // has dismissed the modal.
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_service.cc b/components/safe_browsing/content/browser/password_protection/password_protection_service.cc
index 6f63cb1..dddcd05 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_service.cc
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_service.cc
@@ -122,45 +122,24 @@
           password_field_exists, this, GetRequestTimeoutInMS()));
   request->Start();
 
-  // TODO(bokan): Now that the throttle has been changed to a
-  // CommitDeferringCondition, a followup CL will remove this and make
-  // activations defer like other navigations. https://crbug.com/1234857
-  //
-  // PasswordProtectionService defers all navigations in the WebContents while
-  // there is a pending request triggered by a password reuse. However it does
-  // this via NavigationThrottles, which are not able to throttle navigations
-  // that activate a prerendered page or a back/forward cached page. As a
-  // temporary workaround, disable activations within this WebContents whenever
-  // this event occurs.
-  //
-  // This code only disallows for PASSWORD_REUSE_EVENT because of the following
-  // observations:
-  // 1) A |warning_request| has to start out as a |pending_request|.
-  // 2) Only trigger type PASSWORD_REUSE_EVENT requests can become
-  // |warning_request|.
-  //
-  // This holds because |warning_requests_| insertion only happens at code that
-  // moves a request from |pending_requests_| to |warning_requests_|, which only
-  // does so if is_modal_warning_showing() is true. is_modal_warning_showing()
-  // can only be set to true if ShouldShowModalWarning() is true, which is
-  // always false if trigger_type != PASSWORD_REUSE_EVENT.
-  //
-  // If we were to disallow for other trigger types, we may disable prerendering
-  // more than required.
-  if (request->trigger_type() ==
-      safe_browsing::LoginReputationClientRequest::PASSWORD_REUSE_EVENT) {
-    web_contents->DisallowActivationNavigationsForBug1234857();
-  }
-
   pending_requests_.insert(std::move(request));
 }
 
 std::unique_ptr<PasswordProtectionCommitDeferringCondition>
 PasswordProtectionService::MaybeCreateCommitDeferringCondition(
     content::NavigationHandle& navigation_handle) {
+  // Don't defer navigations that the user started themselves. This won't
+  // matter if the dialog is showing, since it's modal, but if a password reuse
+  // ping is in progress we shouldn't block the user from navigating.
   if (!navigation_handle.IsRendererInitiated())
     return nullptr;
 
+  // The goal of the deferral is to ensure the correct URL is in the omnibox
+  // while the warning modal is showing. Only the primary main frame affects
+  // the omnibox.
+  if (!navigation_handle.IsInPrimaryMainFrame())
+    return nullptr;
+
   content::WebContents* web_contents = navigation_handle.GetWebContents();
   for (scoped_refptr<PasswordProtectionRequest> request : pending_requests_) {
     PasswordProtectionRequestContent* request_content =
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
index 0d70d97..dabf9ca 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -2032,15 +2032,14 @@
   WebUIInfoSingleton::GetInstance()->UnregisterWebUIInstance(this);
 }
 
-void SafeBrowsingUIHandler::GetExperiments(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetExperiments(const base::Value::List& args) {
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
   ResolveJavascriptCallback(base::Value(callback_id), GetFeatureStatusList());
 }
 
-void SafeBrowsingUIHandler::GetPrefs(const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetPrefs(const base::Value::List& args) {
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
@@ -2049,7 +2048,7 @@
                                 user_prefs::UserPrefs::Get(browser_context_)));
 }
 
-void SafeBrowsingUIHandler::GetPolicies(const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetPolicies(const base::Value::List& args) {
   AllowJavascript();
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
@@ -2058,7 +2057,7 @@
                                 user_prefs::UserPrefs::Get(browser_context_)));
 }
 
-void SafeBrowsingUIHandler::GetCookie(const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetCookie(const base::Value::List& args) {
   DCHECK(!args.empty());
   std::string callback_id = args[0].GetString();
 
@@ -2090,8 +2089,7 @@
                             base::Value(std::move(response)));
 }
 
-void SafeBrowsingUIHandler::GetSavedPasswords(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetSavedPasswords(const base::Value::List& args) {
   password_manager::HashPasswordManager hash_manager(
       user_prefs::UserPrefs::Get(browser_context_));
 
@@ -2109,7 +2107,7 @@
 }
 
 void SafeBrowsingUIHandler::GetDatabaseManagerInfo(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   base::ListValue database_manager_info;
 
 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
@@ -2211,7 +2209,7 @@
 }
 
 void SafeBrowsingUIHandler::GetDownloadUrlsChecked(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::vector<std::pair<std::vector<GURL>, DownloadCheckResult>>&
       urls_checked = WebUIInfoSingleton::GetInstance()->download_urls_checked();
 
@@ -2229,7 +2227,7 @@
 }
 
 void SafeBrowsingUIHandler::GetSentClientDownloadRequests(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::vector<std::unique_ptr<ClientDownloadRequest>>& cdrs =
       WebUIInfoSingleton::GetInstance()->client_download_requests_sent();
 
@@ -2246,7 +2244,7 @@
 }
 
 void SafeBrowsingUIHandler::GetReceivedClientDownloadResponses(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::vector<std::unique_ptr<ClientDownloadResponse>>& cdrs =
       WebUIInfoSingleton::GetInstance()->client_download_responses_received();
 
@@ -2263,7 +2261,7 @@
 }
 
 void SafeBrowsingUIHandler::GetSentClientPhishingRequests(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::vector<ClientPhishingRequestAndToken>& cprs =
       WebUIInfoSingleton::GetInstance()->client_phishing_requests_sent();
 
@@ -2280,7 +2278,7 @@
 }
 
 void SafeBrowsingUIHandler::GetReceivedClientPhishingResponses(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::vector<std::unique_ptr<ClientPhishingResponse>>& cprs =
       WebUIInfoSingleton::GetInstance()->client_phishing_responses_received();
 
@@ -2296,8 +2294,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), cprs_received);
 }
 
-void SafeBrowsingUIHandler::GetSentCSBRRs(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetSentCSBRRs(const base::Value::List& args) {
   const std::vector<std::unique_ptr<ClientSafeBrowsingReportRequest>>& reports =
       WebUIInfoSingleton::GetInstance()->csbrrs_sent();
 
@@ -2313,7 +2310,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), sent_reports);
 }
 
-void SafeBrowsingUIHandler::GetPGEvents(const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetPGEvents(const base::Value::List& args) {
   const std::vector<sync_pb::UserEventSpecifics>& events =
       WebUIInfoSingleton::GetInstance()->pg_event_log();
 
@@ -2328,8 +2325,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), events_sent);
 }
 
-void SafeBrowsingUIHandler::GetSecurityEvents(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetSecurityEvents(const base::Value::List& args) {
   const std::vector<sync_pb::GaiaPasswordReuse>& events =
       WebUIInfoSingleton::GetInstance()->security_event_log();
 
@@ -2344,7 +2340,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), events_sent);
 }
 
-void SafeBrowsingUIHandler::GetPGPings(const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetPGPings(const base::Value::List& args) {
   const std::vector<LoginReputationClientRequestAndToken> requests =
       WebUIInfoSingleton::GetInstance()->pg_pings();
 
@@ -2363,8 +2359,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), pings_sent);
 }
 
-void SafeBrowsingUIHandler::GetPGResponses(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetPGResponses(const base::Value::List& args) {
   const std::map<int, LoginReputationClientResponse> responses =
       WebUIInfoSingleton::GetInstance()->pg_responses();
 
@@ -2383,8 +2378,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), responses_sent);
 }
 
-void SafeBrowsingUIHandler::GetRTLookupPings(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetRTLookupPings(const base::Value::List& args) {
   const std::vector<RTLookupRequestAndToken> requests =
       WebUIInfoSingleton::GetInstance()->rt_lookup_pings();
 
@@ -2405,7 +2399,7 @@
 }
 
 void SafeBrowsingUIHandler::GetRTLookupResponses(
-    const base::Value::ConstListView args) {
+    const base::Value::List& args) {
   const std::map<int, RTLookupResponse> responses =
       WebUIInfoSingleton::GetInstance()->rt_lookup_responses();
 
@@ -2424,8 +2418,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), responses_sent);
 }
 
-void SafeBrowsingUIHandler::GetReferrerChain(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetReferrerChain(const base::Value::List& args) {
   DCHECK_GE(args.size(), 2U);
   std::string url_string = args[1].GetString();
 
@@ -2461,8 +2454,7 @@
                             base::Value(referrer_chain_serialized));
 }
 
-void SafeBrowsingUIHandler::GetReferringAppInfo(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetReferringAppInfo(const base::Value::List& args) {
   base::Value referring_app_value;
 #if BUILDFLAG(IS_ANDROID)
   LoginReputationClientRequest::ReferringAppInfo info =
@@ -2482,8 +2474,7 @@
                             base::Value(referring_app_serialized));
 }
 
-void SafeBrowsingUIHandler::GetReportingEvents(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetReportingEvents(const base::Value::List& args) {
   base::ListValue reporting_events;
   for (const auto& reporting_event :
        WebUIInfoSingleton::GetInstance()->reporting_events()) {
@@ -2496,8 +2487,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), reporting_events);
 }
 
-void SafeBrowsingUIHandler::GetLogMessages(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetLogMessages(const base::Value::List& args) {
   const std::vector<std::pair<base::Time, std::string>>& log_messages =
       WebUIInfoSingleton::GetInstance()->log_messages();
 
@@ -2513,8 +2503,7 @@
   ResolveJavascriptCallback(base::Value(callback_id), messages_received);
 }
 
-void SafeBrowsingUIHandler::GetDeepScans(
-    const base::Value::ConstListView args) {
+void SafeBrowsingUIHandler::GetDeepScans(const base::Value::List& args) {
   base::ListValue pings_sent;
 #if BUILDFLAG(FULL_SAFE_BROWSING)
   for (const auto& token_and_data :
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
index 78bb31b..b878fe0 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
@@ -97,92 +97,90 @@
   void OnJavascriptDisallowed() override;
 
   // Get the experiments that are currently enabled per Chrome instance.
-  void GetExperiments(const base::Value::ConstListView args);
+  void GetExperiments(const base::Value::List& args);
 
   // Get the Safe Browsing related preferences for the current user.
-  void GetPrefs(const base::Value::ConstListView args);
+  void GetPrefs(const base::Value::List& args);
 
   // Get the Safe Browsing related policies for the current user.
-  void GetPolicies(const base::Value::ConstListView args);
+  void GetPolicies(const base::Value::List& args);
 
   // Get the Safe Browsing cookie.
-  void GetCookie(const base::Value::ConstListView args);
+  void GetCookie(const base::Value::List& args);
 
   // Get the current captured passwords.
-  void GetSavedPasswords(const base::Value::ConstListView args);
+  void GetSavedPasswords(const base::Value::List& args);
 
   // Get the information related to the Safe Browsing database and full hash
   // cache.
-  void GetDatabaseManagerInfo(const base::Value::ConstListView args);
+  void GetDatabaseManagerInfo(const base::Value::List& args);
 
   // Get the download URLs that have been checked since the oldest currently
   // open chrome://safe-browsing tab was opened.
-  void GetDownloadUrlsChecked(const base::Value::ConstListView args);
+  void GetDownloadUrlsChecked(const base::Value::List& args);
 
   // Get the ClientDownloadRequests that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetSentClientDownloadRequests(const base::Value::ConstListView args);
+  void GetSentClientDownloadRequests(const base::Value::List& args);
 
   // Get the ClientDownloadReponses that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetReceivedClientDownloadResponses(
-      const base::Value::ConstListView args);
+  void GetReceivedClientDownloadResponses(const base::Value::List& args);
 
   // Get the ClientPhishingRequests that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetSentClientPhishingRequests(const base::Value::ConstListView args);
+  void GetSentClientPhishingRequests(const base::Value::List& args);
 
   // Get the ClientPhishingResponses that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetReceivedClientPhishingResponses(
-      const base::Value::ConstListView args);
+  void GetReceivedClientPhishingResponses(const base::Value::List& args);
 
   // Get the ThreatDetails that have been collected since the oldest currently
   // open chrome://safe-browsing tab was opened.
-  void GetSentCSBRRs(const base::Value::ConstListView args);
+  void GetSentCSBRRs(const base::Value::List& args);
 
   // Get the PhishGuard events that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetPGEvents(const base::Value::ConstListView args);
+  void GetPGEvents(const base::Value::List& args);
 
   // Get the Security events that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetSecurityEvents(const base::Value::ConstListView args);
+  void GetSecurityEvents(const base::Value::List& args);
 
   // Get the PhishGuard pings that have been sent since the oldest currently
   // open chrome://safe-browsing tab was opened.
-  void GetPGPings(const base::Value::ConstListView args);
+  void GetPGPings(const base::Value::List& args);
 
   // Get the PhishGuard responses that have been received since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetPGResponses(const base::Value::ConstListView args);
+  void GetPGResponses(const base::Value::List& args);
 
   // Get the real time lookup pings that have been sent since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetRTLookupPings(const base::Value::ConstListView args);
+  void GetRTLookupPings(const base::Value::List& args);
 
   // Get the real time lookup responses that have been received since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetRTLookupResponses(const base::Value::ConstListView args);
+  void GetRTLookupResponses(const base::Value::List& args);
 
   // Get the current referrer chain for a given URL.
-  void GetReferrerChain(const base::Value::ConstListView args);
+  void GetReferrerChain(const base::Value::List& args);
 
   // Get the referring app info that launches Chrome on Android. Always set to
   // null if it's called from platforms other than Android.
-  void GetReferringAppInfo(const base::Value::ConstListView args);
+  void GetReferringAppInfo(const base::Value::List& args);
 
   // Get the list of log messages that have been received since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetLogMessages(const base::Value::ConstListView args);
+  void GetLogMessages(const base::Value::List& args);
 
   // Get the reporting events that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetReportingEvents(const base::Value::ConstListView args);
+  void GetReportingEvents(const base::Value::List& args);
 
   // Get the deep scanning requests that have been collected since the oldest
   // currently open chrome://safe-browsing tab was opened.
-  void GetDeepScans(const base::Value::ConstListView args);
+  void GetDeepScans(const base::Value::List& args);
 
   // Register callbacks for WebUI messages.
   void RegisterMessages() override;
diff --git a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc
index 5696af0..c7b4823 100644
--- a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc
+++ b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc
@@ -24,9 +24,7 @@
 #include "components/segmentation_platform/internal/database/mock_signal_database.h"
 #include "components/segmentation_platform/internal/database/signal_database.h"
 #include "components/segmentation_platform/internal/database/test_segment_info_database.h"
-#include "components/segmentation_platform/internal/execution/feature_aggregator.h"
 #include "components/segmentation_platform/internal/execution/feature_list_query_processor.h"
-#include "components/segmentation_platform/internal/execution/mock_feature_aggregator.h"
 #include "components/segmentation_platform/internal/execution/model_execution_manager.h"
 #include "components/segmentation_platform/internal/execution/model_execution_status.h"
 #include "components/segmentation_platform/internal/execution/segmentation_model_handler.h"
@@ -43,6 +41,9 @@
 using testing::SetArgReferee;
 
 namespace segmentation_platform {
+
+namespace {
+
 using Sample = SignalDatabase::Sample;
 
 class MockSegmentInfoDatabase : public test::TestSegmentInfoDatabase {
@@ -98,6 +99,23 @@
   MOCK_METHOD(bool, ModelAvailable, (), (const override));
 };
 
+// TODO(ssid): Use mock_feature_list_query_processor.h.
+class MockFeatureListQueryProcessor : public FeatureListQueryProcessor {
+ public:
+  MockFeatureListQueryProcessor()
+      : FeatureListQueryProcessor(nullptr, nullptr) {}
+  ~MockFeatureListQueryProcessor() override = default;
+  MOCK_METHOD(void,
+              ProcessFeatureList,
+              (const proto::SegmentationModelMetadata&,
+               OptimizationTarget,
+               base::Time,
+               FeatureProcessorCallback),
+              (override));
+};
+
+}  // namespace
+
 class ModelExecutionManagerTest : public testing::Test {
  public:
   ModelExecutionManagerTest() = default;
@@ -121,10 +139,8 @@
   void CreateModelExecutionManager(
       std::vector<OptimizationTarget> segment_ids,
       const ModelExecutionManager::SegmentationModelUpdatedCallback& callback) {
-    auto feature_aggregator = std::make_unique<MockFeatureAggregator>();
-    feature_aggregator_ = feature_aggregator.get();
-    feature_list_query_processor_ = std::make_unique<FeatureListQueryProcessor>(
-        signal_database_.get(), std::move(feature_aggregator));
+    feature_list_query_processor_ =
+        std::make_unique<MockFeatureListQueryProcessor>();
     model_execution_manager_ = std::make_unique<ModelExecutionManagerImpl>(
         segment_ids,
         base::BindRepeating(&ModelExecutionManagerTest::CreateModelHandler,
@@ -186,9 +202,8 @@
   base::SimpleTestClock clock_;
   std::unique_ptr<test::TestSegmentInfoDatabase> segment_database_;
   std::unique_ptr<MockSignalDatabase> signal_database_;
-  raw_ptr<MockFeatureAggregator> feature_aggregator_;
 
-  std::unique_ptr<FeatureListQueryProcessor> feature_list_query_processor_;
+  std::unique_ptr<MockFeatureListQueryProcessor> feature_list_query_processor_;
   std::unique_ptr<ModelExecutionManagerImpl> model_execution_manager_;
 };
 
@@ -366,4 +381,59 @@
   EXPECT_EQ(2, segment_info_from_db_2->prediction_result().result());
 }
 
+TEST_F(ModelExecutionManagerTest, FailedFeatureProcessing) {
+  auto segment_id =
+      OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB;
+  CreateModelExecutionManager({segment_id}, base::DoNothing());
+
+  // Initialize with required metadata.
+  segment_database_->SetBucketDuration(segment_id, 3, proto::TimeUnit::HOUR);
+  std::string user_action_name = "some_user_action";
+  segment_database_->AddUserActionFeature(segment_id, user_action_name, 3, 3,
+                                          proto::Aggregation::BUCKETED_COUNT);
+
+  EXPECT_CALL(*feature_list_query_processor_,
+              ProcessFeatureList(_, segment_id, clock_.Now(), _))
+      .WillOnce(
+          RunOnceCallback<3>(/*error=*/true, std::vector<float>{1, 2, 3}));
+
+  // The input tensor should contain all values flattened to a single vector.
+  EXPECT_CALL(FindHandler(segment_id), ModelAvailable())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(FindHandler(segment_id), ExecuteModelWithInput(_, _)).Times(0);
+
+  ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata));
+
+  EXPECT_CALL(*feature_list_query_processor_,
+              ProcessFeatureList(_, segment_id, clock_.Now(), _))
+      .WillOnce(RunOnceCallback<3>(/*error=*/true, std::vector<float>{}));
+  ExecuteModel(std::make_pair(0, ModelExecutionStatus::kInvalidMetadata));
+}
+
+TEST_F(ModelExecutionManagerTest, ExecuteModelWithMultipleFeatures) {
+  auto segment_id =
+      OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB;
+  CreateModelExecutionManager({segment_id}, base::DoNothing());
+
+  // Initialize with required metadata.
+  segment_database_->SetBucketDuration(segment_id, 3, proto::TimeUnit::HOUR);
+  std::string user_action_name = "some_user_action";
+  segment_database_->AddUserActionFeature(segment_id, user_action_name, 3, 3,
+                                          proto::Aggregation::BUCKETED_COUNT);
+
+  EXPECT_CALL(*feature_list_query_processor_,
+              ProcessFeatureList(_, segment_id, clock_.Now(), _))
+      .WillOnce(RunOnceCallback<3>(/*error=*/false,
+                                   std::vector<float>{1, 2, 3, 4, 5, 6, 7}));
+
+  // The input tensor should contain all values flattened to a single vector.
+  EXPECT_CALL(FindHandler(segment_id), ModelAvailable())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(FindHandler(segment_id),
+              ExecuteModelWithInput(_, std::vector<float>{1, 2, 3, 4, 5, 6, 7}))
+      .WillOnce(RunOnceCallback<0>(absl::make_optional(0.8)));
+
+  ExecuteModel(std::make_pair(0.8, ModelExecutionStatus::kSuccess));
+}
+
 }  // namespace segmentation_platform
diff --git a/components/services/quarantine/common.cc b/components/services/quarantine/common.cc
index 4158eb9..10d7c5d 100644
--- a/components/services/quarantine/common.cc
+++ b/components/services/quarantine/common.cc
@@ -25,7 +25,7 @@
     return source_url;
   }
 
-  url::Replacements<char> replacements;
+  GURL::Replacements replacements;
   replacements.ClearUsername();
   replacements.ClearPassword();
 
diff --git a/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedDialog.java b/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedDialog.java
index d070751..9fbe3f4e 100644
--- a/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedDialog.java
+++ b/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedDialog.java
@@ -83,7 +83,7 @@
     void show(boolean shouldPostDialog) {
         Resources resources = mContext.getResources();
         mClickableSpan = new NoUnderlineClickableSpan(
-                resources, (view) -> AdsBlockedDialogJni.get().onLearnMoreClicked(mNativeDialog));
+                mContext, (view) -> AdsBlockedDialogJni.get().onLearnMoreClicked(mNativeDialog));
         mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
                                .with(ModalDialogProperties.CONTROLLER, this)
                                .with(ModalDialogProperties.TITLE, resources,
diff --git a/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedInfoBar.java b/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedInfoBar.java
index e730e2f..4a5e5b80 100644
--- a/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedInfoBar.java
+++ b/components/subresource_filter/android/java/src/org/chromium/components/subresource_filter/AdsBlockedInfoBar.java
@@ -71,7 +71,7 @@
             description.append(learnMore);
 
             NoUnderlineClickableSpan clickableSpan =
-                    new NoUnderlineClickableSpan(layout.getResources(), (view) -> onLinkClicked());
+                    new NoUnderlineClickableSpan(layout.getContext(), (view) -> onLinkClicked());
             description.setSpan(clickableSpan, spanStart, description.length(),
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             layout.getMessageLayout().addDescription(description);
diff --git a/components/sync/base/unique_position.cc b/components/sync/base/unique_position.cc
index 5ce5336..b270de0 100644
--- a/components/sync/base/unique_position.cc
+++ b/components/sync/base/unique_position.cc
@@ -8,7 +8,6 @@
 #include <limits>
 
 #include "base/logging.h"
-#include "base/notreached.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
@@ -161,24 +160,6 @@
   ToProto().SerializeToString(blob);
 }
 
-int64_t UniquePosition::ToInt64() const {
-  uint64_t y = 0;
-  const std::string& s = Uncompress(compressed_);
-  size_t l = sizeof(int64_t);
-  if (s.length() < l) {
-    NOTREACHED();
-    l = s.length();
-  }
-  for (size_t i = 0; i < l; ++i) {
-    const uint8_t byte = s[l - i - 1];
-    y |= static_cast<uint64_t>(byte) << (i * 8);
-  }
-  y ^= 0x8000000000000000ULL;
-  // This is technically implementation-defined if y > INT64_MAX, so
-  // we're assuming that we're on a twos-complement machine.
-  return static_cast<int64_t>(y);
-}
-
 bool UniquePosition::IsValid() const {
   return !compressed_.empty();
 }
diff --git a/components/sync/base/unique_position.h b/components/sync/base/unique_position.h
index 25aebe6..1d9f574c 100644
--- a/components/sync/base/unique_position.h
+++ b/components/sync/base/unique_position.h
@@ -97,12 +97,6 @@
   // Returns the suffix.
   std::string GetSuffixForTest() const;
 
-  // Performs a lossy conversion to an int64_t position.  Positions converted to
-  // and from int64_ts using this and the FromInt64 function should maintain
-  // their
-  // relative orderings unless the int64_t values conflict.
-  int64_t ToInt64() const;
-
   bool IsValid() const;
 
   // Returns memory usage estimate.
diff --git a/components/sync/base/unique_position_unittest.cc b/components/sync/base/unique_position_unittest.cc
index a4675446..53d3886 100644
--- a/components/sync/base/unique_position_unittest.cc
+++ b/components/sync/base/unique_position_unittest.cc
@@ -567,16 +567,6 @@
   }
 }
 
-TEST_F(PositionFromIntTest, RoundTripConversion) {
-  for (size_t i = 0; i < kNumTestValues; ++i) {
-    const int64_t expected_value = kTestValues[i];
-    const UniquePosition pos =
-        UniquePosition::FromInt64(kTestValues[i], NextSuffix());
-    const int64_t value = pos.ToInt64();
-    EXPECT_EQ(expected_value, value) << "i = " << i;
-  }
-}
-
 template <typename T, typename LessThan = std::less<T>>
 class IndexedLessThan {
  public:
diff --git a/components/sync/engine/commit_contribution_impl.cc b/components/sync/engine/commit_contribution_impl.cc
index a3c4428..473e5f4f 100644
--- a/components/sync/engine/commit_contribution_impl.cc
+++ b/components/sync/engine/commit_contribution_impl.cc
@@ -237,12 +237,9 @@
           commit_proto->set_folder(true);
           break;
       }
-      // position_in_parent field is set only for legacy reasons.  See comments
-      // in sync.proto for more information.
       const UniquePosition unique_position = UniquePosition::FromProto(
           entity_data.specifics.bookmark().unique_position());
       DCHECK(unique_position.IsValid());
-      commit_proto->set_position_in_parent(unique_position.ToInt64());
       *commit_proto->mutable_unique_position() = unique_position.ToProto();
       // parent_id field is set only for legacy clients only, before M99.
       if (!entity_data.legacy_parent_id.empty()) {
diff --git a/components/sync/engine/commit_contribution_impl_unittest.cc b/components/sync/engine/commit_contribution_impl_unittest.cc
index 18a88a91..e6086b8 100644
--- a/components/sync/engine/commit_contribution_impl_unittest.cc
+++ b/components/sync/engine/commit_contribution_impl_unittest.cc
@@ -103,7 +103,6 @@
   EXPECT_EQ(kValue, entity.specifics().preference().value());
   EXPECT_TRUE(entity.parent_id_string().empty());
   EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
-  EXPECT_EQ(0, entity.position_in_parent());
 }
 
 TEST(CommitContributionImplTest, PopulateCommitProtoBookmark) {
@@ -146,7 +145,6 @@
   EXPECT_FALSE(entity.folder());
   EXPECT_FALSE(entity.parent_id_string().empty());
   EXPECT_TRUE(entity.unique_position().has_custom_compressed_v1());
-  EXPECT_NE(0, entity.position_in_parent());
 }
 
 TEST(CommitContributionImplTest, PopulateCommitProtoBookmarkFolder) {
@@ -189,7 +187,6 @@
   EXPECT_TRUE(entity.folder());
   EXPECT_FALSE(entity.parent_id_string().empty());
   EXPECT_TRUE(entity.unique_position().has_custom_compressed_v1());
-  EXPECT_NE(0, entity.position_in_parent());
 }
 
 // Verifies how PASSWORDS protos are committed on the wire, making sure the data
@@ -251,7 +248,6 @@
   EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty());
   EXPECT_TRUE(entity.parent_id_string().empty());
   EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
-  EXPECT_EQ(0, entity.position_in_parent());
 }
 
 // Same as above but uses CUSTOM_PASSPHRASE. In this case, field
@@ -308,7 +304,6 @@
   EXPECT_FALSE(entity.specifics().password().has_unencrypted_metadata());
   EXPECT_TRUE(entity.parent_id_string().empty());
   EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
-  EXPECT_EQ(0, entity.position_in_parent());
 }
 
 TEST(CommitContributionImplTest, ShouldPropagateFailedItemsOnCommitResponse) {
diff --git a/components/sync/engine/syncer_unittest.cc b/components/sync/engine/syncer_unittest.cc
index 3bea332b..722bfad 100644
--- a/components/sync/engine/syncer_unittest.cc
+++ b/components/sync/engine/syncer_unittest.cc
@@ -304,13 +304,13 @@
   const sync_pb::EntitySpecifics pref = MakeSpecifics(PREFERENCES);
 
   // Normal sync, all the data types should get synced.
-  mock_server_->AddUpdateSpecifics("1", "0", "A", 10, 10, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "A", 10, 10, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "B", 10, 10, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "B", 10, 10, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "C", 10, 10, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "C", 10, 10, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "D", 10, 10, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "D", 10, 10, false, pref);
 
   EXPECT_TRUE(SyncShareNudge());
   // Initial state. Everything is normal.
@@ -325,13 +325,13 @@
   mock_server_->set_throttling(true);
   mock_server_->SetPartialFailureTypes(throttled_types);
 
-  mock_server_->AddUpdateSpecifics("1", "0", "E", 20, 20, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "E", 20, 20, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "F", 20, 20, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "F", 20, 20, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "G", 20, 20, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "G", 20, 20, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "H", 20, 20, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "H", 20, 20, false, pref);
   EXPECT_TRUE(SyncShareNudge());
 
   // PREFERENCES continues to work normally (not throttled).
@@ -342,13 +342,13 @@
   // Unthrottled BOOKMARKS, then BOOKMARKS should get synced now.
   mock_server_->set_throttling(false);
 
-  mock_server_->AddUpdateSpecifics("1", "0", "E", 30, 30, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "E", 30, 30, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "F", 30, 30, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "F", 30, 30, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "G", 30, 30, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "G", 30, 30, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "H", 30, 30, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "H", 30, 30, false, pref);
   EXPECT_TRUE(SyncShareNudge());
   // BOOKMARKS unthrottled.
   EXPECT_EQ(2U, GetProcessor(BOOKMARKS)->GetNumUpdateResponses());
@@ -359,13 +359,13 @@
   const sync_pb::EntitySpecifics pref = MakeSpecifics(PREFERENCES);
 
   // Normal sync, all the data types should get synced.
-  mock_server_->AddUpdateSpecifics("1", "0", "A", 10, 10, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "A", 10, 10, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "B", 10, 10, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "B", 10, 10, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "C", 10, 10, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "C", 10, 10, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "D", 10, 10, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "D", 10, 10, false, pref);
 
   EXPECT_TRUE(SyncShareNudge());
   // Initial state. Everything is normal.
@@ -380,13 +380,13 @@
   mock_server_->set_partial_failure(true);
   mock_server_->SetPartialFailureTypes(failed_types);
 
-  mock_server_->AddUpdateSpecifics("1", "0", "E", 20, 20, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "E", 20, 20, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "F", 20, 20, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "F", 20, 20, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "G", 20, 20, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "G", 20, 20, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "H", 20, 20, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "H", 20, 20, false, pref);
   EXPECT_TRUE(SyncShareNudge());
 
   // PREFERENCES continues to work normally (not throttled).
@@ -397,13 +397,13 @@
   // Set BOOKMARKS not partial failed, then BOOKMARKS should get synced now.
   mock_server_->set_partial_failure(false);
 
-  mock_server_->AddUpdateSpecifics("1", "0", "E", 30, 30, true, 0, bookmark,
+  mock_server_->AddUpdateSpecifics("1", "0", "E", 30, 30, true, bookmark,
                                    foreign_cache_guid(), "-1");
-  mock_server_->AddUpdateSpecifics("2", "1", "F", 30, 30, false, 2, bookmark,
+  mock_server_->AddUpdateSpecifics("2", "1", "F", 30, 30, false, bookmark,
                                    foreign_cache_guid(), "-2");
-  mock_server_->AddUpdateSpecifics("3", "1", "G", 30, 30, false, 1, bookmark,
+  mock_server_->AddUpdateSpecifics("3", "1", "G", 30, 30, false, bookmark,
                                    foreign_cache_guid(), "-3");
-  mock_server_->AddUpdateSpecifics("4", "0", "H", 30, 30, false, 0, pref);
+  mock_server_->AddUpdateSpecifics("4", "0", "H", 30, 30, false, pref);
   EXPECT_TRUE(SyncShareNudge());
   // BOOKMARKS not failed.
   EXPECT_EQ(2U, GetProcessor(BOOKMARKS)->GetNumUpdateResponses());
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index f98a9311..432d2fd 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -910,7 +910,6 @@
   VISIT(specifics);
   VISIT(folder);
   VISIT(client_defined_unique_tag);
-  VISIT_BYTES(ordinal_in_parent);
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::SyncInvalidationsPayload& proto) {
diff --git a/components/sync/protocol/sync_entity.proto b/components/sync/protocol/sync_entity.proto
index 70eef11..997952c 100644
--- a/components/sync/protocol/sync_entity.proto
+++ b/components/sync/protocol/sync_entity.proto
@@ -115,45 +115,11 @@
   reserved 14;
   reserved "bookmark_favicon";
 
-  // Supplies a numeric position for this item, relative to other items with the
-  // same parent.  Deprecated in M26, though clients are still required to set
-  // it.
-  //
-  // Present in both GetUpdatesResponse and CommitMessage.
-  //
-  // At one point this was used as an alternative / supplement to
-  // the deprecated |insert_after_item_id|, but now it, too, has been
-  // deprecated.
-  //
-  // In order to maintain compatibility with older clients, newer clients should
-  // still set this field.  Its value should be based on the first 8 bytes of
-  // this item's |unique_position|.
-  //
-  // Nerwer clients must also support the receipt of items that contain
-  // |position_in_parent| but no |unique_position|.  They should locally convert
-  // the given int64 position to a UniquePosition.
-  //
-  // The conversion from int64 to UniquePosition is as follows:
-  // The int64 value will have its sign bit flipped then placed in big endian
-  // order as the first 8 bytes of the UniquePosition.  The subsequent bytes of
-  // the UniquePosition will consist of the item's unique suffix.
-  //
-  // Conversion from UniquePosition to int64 reverses this process: the first 8
-  // bytes of the position are to be interpreted as a big endian int64 value
-  // with its sign bit flipped.
+  // Ancient fields, predecessors for |unique_position|, deprecated with M26 and
+  // still supported to deal with old incoming data. See field |unique_position|
+  // for details as well as the data-upgrading implementation in
+  // GetUniquePositionFromSyncEntity().
   optional int64 position_in_parent = 15 [deprecated = true];
-
-  // Contains the ID of the element (under the same parent) after which this
-  // element resides. An empty string indicates that the element is the first
-  // element in the parent.  This value is used during commits to specify
-  // a relative position for a position change.  In the context of
-  // a GetUpdatesMessage, |position_in_parent| is used instead to
-  // communicate position.
-  //
-  // Present only in CommitMessage.
-  //
-  // This is deprecated.  Clients are allowed to omit this as long as they
-  // include |position_in_parent| instead.
   optional string insert_after_item_id = 16 [deprecated = true];
 
   reserved 17;
@@ -163,7 +129,7 @@
   // Present in both GetUpdatesResponse and CommitMessage.
   optional bool deleted = 18 [default = false];
 
-  // A GUID that identifies the the sync client who initially committed
+  // A unique ID that identifies the the sync client who initially committed
   // this entity.  This value corresponds to |cache_guid| in CommitMessage.
   // This field, along with |originator_client_item_id|, can be used to
   // reunite the original with its official committed version in the case
@@ -222,32 +188,28 @@
   // May be present in CommitMessages for the initial creation of an entity.
   // If present in Commit updates for the entity, it will be ignored.
   //
-  // Available in version 24+.
-  //
   // May be returned in GetUpdatesMessage and sent up in CommitMessage.
-  //
   optional string client_defined_unique_tag = 23;
 
-  // This positioning system had a relatively short life.  It was made obsolete
-  // by |unique_position| before either the client or server made much of an
-  // attempt to support it.  In fact, no client ever read or set this field.
-  //
-  // Deprecated in M26.
-  optional bytes ordinal_in_parent = 24 [deprecated = true];
+  reserved 24;
+  reserved "ordinal_in_parent";
 
-  // This is the fourth attempt at positioning.
+  // Introduced in M26, represents ordering among entities, in practice used for
+  // bookmarks only. Clients should not assume it is always populated in
+  // GetUpdatesMessage due to the following caveats:
+  // 1. Tombstones and permanent folders do not populate it (ordering is
+  //    irrelevant).
+  // 2. It may remain unset by future versions of the client, as long as the
+  //    field with the same name is populated inside BookmarkSpecifics. M94 and
+  //    above populate both for backward compatibility reasons, but when support
+  //    for M93 is retired, modern clients at the time may stop populating this
+  //    field.
+  // 3. Very old data (last committed by M25 or below, before the field was
+  //    introduced) does not include this field, and in that case the legacy
+  //    fields |position_in_parent| or |insert_after_item_id| must be honored
+  //    instead.
   //
-  // This field is present in both GetUpdatesResponse and CommitMessage, if the
-  // item's type requires it and the client that wrote the item supports it (M26
-  // or higher).  Clients must also be prepared to handle updates from clients
-  // that do not set this field.
-  //
-  // This field will not be set for items whose type ignores positioning.
-  // Clients should not attempt to read this field on the receipt of an item of
-  // a type that ignores positioning.
-  //
-  // Refer to its definition in unique_position.proto for more information about
-  // its internal representation.
+  // May be returned in GetUpdatesMessage and sent up in CommitMessage.
   optional UniquePosition unique_position = 25;
 
   // This used to be a list of sync attachment IDs, but it was never launched
diff --git a/components/sync/test/engine/mock_connection_manager.cc b/components/sync/test/engine/mock_connection_manager.cc
index a99db97..d5be79b 100644
--- a/components/sync/test/engine/mock_connection_manager.cc
+++ b/components/sync/test/engine/mock_connection_manager.cc
@@ -48,7 +48,6 @@
       throttling_(false),
       partial_failure_(false),
       fail_non_periodic_get_updates_(false),
-      next_position_in_parent_(2),
       num_get_updates_requests_(0) {
   SetNewTimestamp(0);
   SetAccessToken(kValidAccessToken);
@@ -225,11 +224,9 @@
     int64_t version,
     int64_t sync_ts,
     bool is_dir,
-    int64_t position,
     const sync_pb::EntitySpecifics& specifics) {
   sync_pb::SyncEntity* ent =
       AddUpdateMeta(id, parent_id, name, version, sync_ts);
-  ent->set_position_in_parent(position);
   ent->mutable_specifics()->CopyFrom(specifics);
   ent->set_folder(is_dir);
   return ent;
@@ -242,12 +239,11 @@
     int64_t version,
     int64_t sync_ts,
     bool is_dir,
-    int64_t position,
     const sync_pb::EntitySpecifics& specifics,
     const string& originator_cache_guid,
     const string& originator_client_item_id) {
-  sync_pb::SyncEntity* ent = AddUpdateSpecifics(
-      id, parent_id, name, version, sync_ts, is_dir, position, specifics);
+  sync_pb::SyncEntity* ent = AddUpdateSpecifics(id, parent_id, name, version,
+                                                sync_ts, is_dir, specifics);
   ent->set_originator_cache_guid(originator_cache_guid);
   ent->set_originator_client_item_id(originator_client_item_id);
   return ent;
@@ -267,7 +263,6 @@
   ent->set_version(version);
   ent->set_mtime(sync_ts);
   ent->set_ctime(1);
-  ent->set_position_in_parent(0);
   ent->set_folder(false);
   ent->mutable_specifics()->CopyFrom(specifics);
   return ent;
@@ -318,7 +313,6 @@
   ent->set_version(version);
   ent->set_mtime(sync_ts);
   ent->set_ctime(1);
-  ent->set_position_in_parent(GeneratePositionInParent());
 
   // This isn't perfect, but it works well enough.  This is an update, which
   // means the ID is a server ID, which means it never changes.  By making
diff --git a/components/sync/test/engine/mock_connection_manager.h b/components/sync/test/engine/mock_connection_manager.h
index 2a4dc3a..08405bd 100644
--- a/components/sync/test/engine/mock_connection_manager.h
+++ b/components/sync/test/engine/mock_connection_manager.h
@@ -94,7 +94,6 @@
       int64_t version,
       int64_t sync_ts,
       bool is_dir,
-      int64_t position,
       const sync_pb::EntitySpecifics& specifics);
   sync_pb::SyncEntity* AddUpdateSpecifics(
       const std::string& id,
@@ -103,7 +102,6 @@
       int64_t version,
       int64_t sync_ts,
       bool is_dir,
-      int64_t position,
       const sync_pb::EntitySpecifics& specifics,
       const std::string& originator_cache_guid,
       const std::string& originator_client_item_id);
@@ -273,11 +271,6 @@
   // a TRANSIENT_ERROR response.
   bool ShouldTransientErrorThisId(const std::string& id);
 
-  // Generate a numeric position_in_parent value.  We use a global counter
-  // that only decreases; this simulates new objects always being added to the
-  // front of the ordering.
-  int64_t GeneratePositionInParent() { return next_position_in_parent_--; }
-
   // Get a mutable update response which will eventually be returned to the
   // client.
   sync_pb::GetUpdatesResponse* GetUpdateResponse();
@@ -351,9 +344,6 @@
   std::unique_ptr<sync_pb::ClientCommand> gu_client_command_;
   std::unique_ptr<sync_pb::ClientCommand> commit_client_command_;
 
-  // The next value to use for the position_in_parent property.
-  int64_t next_position_in_parent_;
-
   ModelTypeSet expected_filter_;
 
   ModelTypeSet partial_failure_type_;
diff --git a/components/test/data/history/history.45.sql b/components/test/data/history/history.45.sql
index 6142f165..f9274ce 100644
--- a/components/test/data/history/history.45.sql
+++ b/components/test/data/history/history.45.sql
@@ -31,4 +31,4 @@
 CREATE INDEX segments_usage_seg_id ON segment_usage(segment_id);
 CREATE INDEX clusters_for_visit ON clusters_and_visits(visit_id);
 CREATE INDEX urls_url_index ON urls (url);
-COMMIT;
\ No newline at end of file
+COMMIT;
diff --git a/components/test/data/history/history.46.sql b/components/test/data/history/history.46.sql
index 59f39bf..d73470a1 100644
--- a/components/test/data/history/history.46.sql
+++ b/components/test/data/history/history.46.sql
@@ -2,7 +2,7 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','47');
+INSERT INTO meta VALUES('version','46');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,publicly_routable BOOLEAN DEFAULT FALSE NOT NULL);
@@ -15,7 +15,7 @@
 CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL);
 CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB);
-CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR);
+CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL);
 CREATE TABLE context_annotations(visit_id INTEGER PRIMARY KEY,context_annotation_flags INTEGER NOT NULL,duration_since_last_visit INTEGER,page_end_reason INTEGER);
 CREATE TABLE clusters(cluster_id INTEGER PRIMARY KEY,score NUMERIC NOT NULL);
 CREATE TABLE clusters_and_visits(cluster_id INTEGER NOT NULL,visit_id INTEGER NOT NULL,score NUMERIC NOT NULL,PRIMARY KEY(cluster_id,visit_id))WITHOUT ROWID;
diff --git a/components/test/data/history/history.47.sql b/components/test/data/history/history.47.sql
index 3bb9b5a..59f39bf 100644
--- a/components/test/data/history/history.47.sql
+++ b/components/test/data/history/history.47.sql
@@ -2,7 +2,7 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','48');
+INSERT INTO meta VALUES('version','47');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,publicly_routable BOOLEAN DEFAULT FALSE NOT NULL);
@@ -15,7 +15,7 @@
 CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL);
 CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB);
-CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR);
+CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR);
 CREATE TABLE context_annotations(visit_id INTEGER PRIMARY KEY,context_annotation_flags INTEGER NOT NULL,duration_since_last_visit INTEGER,page_end_reason INTEGER);
 CREATE TABLE clusters(cluster_id INTEGER PRIMARY KEY,score NUMERIC NOT NULL);
 CREATE TABLE clusters_and_visits(cluster_id INTEGER NOT NULL,visit_id INTEGER NOT NULL,score NUMERIC NOT NULL,PRIMARY KEY(cluster_id,visit_id))WITHOUT ROWID;
diff --git a/components/test/data/history/history.48.sql b/components/test/data/history/history.48.sql
index 68e4734..3bb9b5a 100644
--- a/components/test/data/history/history.48.sql
+++ b/components/test/data/history/history.48.sql
@@ -2,10 +2,10 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','49');
+INSERT INTO meta VALUES('version','48');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
-CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,opener_visit INTEGER);
+CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,publicly_routable BOOLEAN DEFAULT FALSE NOT NULL);
 CREATE TABLE visit_source(id INTEGER PRIMARY KEY,source INTEGER NOT NULL);
 CREATE TABLE keyword_search_terms (keyword_id INTEGER NOT NULL,url_id INTEGER NOT NULL,term LONGVARCHAR NOT NULL,normalized_term LONGVARCHAR NOT NULL);
 CREATE TABLE downloads (id INTEGER PRIMARY KEY,guid VARCHAR NOT NULL,current_path LONGVARCHAR NOT NULL,target_path LONGVARCHAR NOT NULL,start_time INTEGER NOT NULL,received_bytes INTEGER NOT NULL,total_bytes INTEGER NOT NULL,state INTEGER NOT NULL,danger_type INTEGER NOT NULL,interrupt_reason INTEGER NOT NULL,hash BLOB NOT NULL,end_time INTEGER NOT NULL,opened INTEGER NOT NULL,last_access_time INTEGER NOT NULL,transient INTEGER NOT NULL,referrer VARCHAR NOT NULL,site_url VARCHAR NOT NULL,tab_url VARCHAR NOT NULL,tab_referrer_url VARCHAR NOT NULL,http_method VARCHAR NOT NULL,by_ext_id VARCHAR NOT NULL,by_ext_name VARCHAR NOT NULL,etag VARCHAR NOT NULL,last_modified VARCHAR NOT NULL,mime_type VARCHAR(255) NOT NULL,original_mime_type VARCHAR(255) NOT NULL);
diff --git a/components/test/data/history/history.49.sql b/components/test/data/history/history.49.sql
index 44a2989e0..68e4734 100644
--- a/components/test/data/history/history.49.sql
+++ b/components/test/data/history/history.49.sql
@@ -2,7 +2,7 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','50');
+INSERT INTO meta VALUES('version','49');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,opener_visit INTEGER);
@@ -15,7 +15,7 @@
 CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL);
 CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB);
-CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,visibility_score NUMERIC,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR);
+CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR);
 CREATE TABLE context_annotations(visit_id INTEGER PRIMARY KEY,context_annotation_flags INTEGER NOT NULL,duration_since_last_visit INTEGER,page_end_reason INTEGER);
 CREATE TABLE clusters(cluster_id INTEGER PRIMARY KEY,score NUMERIC NOT NULL);
 CREATE TABLE clusters_and_visits(cluster_id INTEGER NOT NULL,visit_id INTEGER NOT NULL,score NUMERIC NOT NULL,PRIMARY KEY(cluster_id,visit_id))WITHOUT ROWID;
diff --git a/components/test/data/history/history.52.sql b/components/test/data/history/history.52.sql
index 6bf08838..59abc98 100644
--- a/components/test/data/history/history.52.sql
+++ b/components/test/data/history/history.52.sql
@@ -2,7 +2,7 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','53');
+INSERT INTO meta VALUES('version','52');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,opener_visit INTEGER);
@@ -15,7 +15,7 @@
 CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL);
 CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB);
-CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,visibility_score NUMERIC,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR,search_normalized_url VARCHAR,search_terms LONGVARCHAR);
+CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,visibility_score NUMERIC,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR);
 CREATE TABLE context_annotations(visit_id INTEGER PRIMARY KEY,context_annotation_flags INTEGER NOT NULL,duration_since_last_visit INTEGER,page_end_reason INTEGER,total_foreground_duration INTEGER);
 CREATE TABLE clusters(cluster_id INTEGER PRIMARY KEY,score NUMERIC NOT NULL);
 CREATE TABLE clusters_and_visits(cluster_id INTEGER NOT NULL,visit_id INTEGER NOT NULL,score NUMERIC NOT NULL,PRIMARY KEY(cluster_id,visit_id))WITHOUT ROWID;
diff --git a/components/test/data/history/history.51.sql b/components/test/data/history/history.53.sql
similarity index 96%
rename from components/test/data/history/history.51.sql
rename to components/test/data/history/history.53.sql
index 59abc98..6bf08838 100644
--- a/components/test/data/history/history.51.sql
+++ b/components/test/data/history/history.53.sql
@@ -2,7 +2,7 @@
 BEGIN TRANSACTION;
 CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);
 INSERT INTO meta VALUES('mmap_status','-1');
-INSERT INTO meta VALUES('version','52');
+INSERT INTO meta VALUES('version','53');
 INSERT INTO meta VALUES('last_compatible_version','16');
 CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL,incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL,opener_visit INTEGER);
@@ -15,7 +15,7 @@
 CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL);
 CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL);
 CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB);
-CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,visibility_score NUMERIC,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR);
+CREATE TABLE content_annotations(visit_id INTEGER PRIMARY KEY,visibility_score NUMERIC,floc_protected_score NUMERIC,categories VARCHAR,page_topics_model_version INTEGER,annotation_flags INTEGER NOT NULL,entities VARCHAR,related_searches VARCHAR,search_normalized_url VARCHAR,search_terms LONGVARCHAR);
 CREATE TABLE context_annotations(visit_id INTEGER PRIMARY KEY,context_annotation_flags INTEGER NOT NULL,duration_since_last_visit INTEGER,page_end_reason INTEGER,total_foreground_duration INTEGER);
 CREATE TABLE clusters(cluster_id INTEGER PRIMARY KEY,score NUMERIC NOT NULL);
 CREATE TABLE clusters_and_visits(cluster_id INTEGER NOT NULL,visit_id INTEGER NOT NULL,score NUMERIC NOT NULL,PRIMARY KEY(cluster_id,visit_id))WITHOUT ROWID;
diff --git a/components/viz/service/display/overlay_processor_ozone.cc b/components/viz/service/display/overlay_processor_ozone.cc
index 43b5f97..8fe459b1 100644
--- a/components/viz/service/display/overlay_processor_ozone.cc
+++ b/components/viz/service/display/overlay_processor_ozone.cc
@@ -4,10 +4,12 @@
 
 #include "components/viz/service/display/overlay_processor_ozone.h"
 
+#include <algorithm>
 #include <memory>
 #include <utility>
 #include <vector>
 
+#include "base/bind.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/timer/elapsed_timer.h"
@@ -130,6 +132,7 @@
         NOTREACHED();
     }
   }
+  MaybeObserveHardwareCapabilities();
 }
 
 OverlayProcessorOzone::~OverlayProcessorOzone() = default;
@@ -239,6 +242,26 @@
   }
 }
 
+void OverlayProcessorOzone::MaybeObserveHardwareCapabilities() {
+  // HardwareCapabilities isn't necessary unless attempting multiple overlays.
+  if (max_overlays_config_ <= 1) {
+    return;
+  }
+  overlay_candidates_->ObserveHardwareCapabilities(
+      base::BindRepeating(&OverlayProcessorOzone::ReceiveHardwareCapabilities,
+                          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void OverlayProcessorOzone::ReceiveHardwareCapabilities(
+    ui::HardwareCapabilities hardware_capabilities) {
+  // Subtract 1 because one of these overlay capable planes will be needed for
+  // the primary plane.
+  int max_overlays_supported =
+      hardware_capabilities.num_overlay_capable_planes - 1;
+  max_overlays_considered_ =
+      std::min(max_overlays_supported, max_overlays_config_);
+}
+
 gfx::Rect OverlayProcessorOzone::GetOverlayDamageRectForOutputSurface(
     const OverlayCandidate& overlay) const {
   return ToEnclosedRect(overlay.display_rect);
diff --git a/components/viz/service/display/overlay_processor_ozone.h b/components/viz/service/display/overlay_processor_ozone.h
index 337775b..5809388 100644
--- a/components/viz/service/display/overlay_processor_ozone.h
+++ b/components/viz/service/display/overlay_processor_ozone.h
@@ -10,6 +10,7 @@
 
 #include "components/viz/service/display/overlay_processor_using_strategy.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_candidates_ozone.h"
 
 namespace viz {
@@ -34,6 +35,15 @@
   void CheckOverlaySupportImpl(
       const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
       OverlayCandidateList* surfaces) override;
+  // If UseMultipleOverlays is enabled, set `ReceiveHardwareCapabilities` as a
+  // callback on `overlay_candidates_` to be called with a
+  // `HardwareCapabilities` once, and then each time displays are configured.
+  void MaybeObserveHardwareCapabilities();
+  // Updates `max_overlays_considered_` based on the overlay plane support in
+  // the received `HardwareCapabilities`.
+  void ReceiveHardwareCapabilities(
+      ui::HardwareCapabilities hardware_capabilities);
+
   gfx::Rect GetOverlayDamageRectForOutputSurface(
       const OverlayCandidate& candidate) const override;
   void RegisterOverlayRequirement(bool requires_overlay) override;
@@ -49,6 +59,7 @@
   std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_;
   const std::vector<OverlayStrategy> available_strategies_;
   gpu::SharedImageInterface* const shared_image_interface_;
+  base::WeakPtrFactory<OverlayProcessorOzone> weak_ptr_factory_{this};
 };
 }  // namespace viz
 
diff --git a/components/viz/service/display/overlay_processor_ozone_unittest.cc b/components/viz/service/display/overlay_processor_ozone_unittest.cc
index 675c8ec..7f785d3 100644
--- a/components/viz/service/display/overlay_processor_ozone_unittest.cc
+++ b/components/viz/service/display/overlay_processor_ozone_unittest.cc
@@ -4,8 +4,12 @@
 
 #include "components/viz/service/display/overlay_processor_ozone.h"
 
+#include <utility>
+
+#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/viz/common/features.h"
 #include "components/viz/test/test_context_provider.h"
 #include "gpu/command_buffer/client/shared_image_interface.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -13,6 +17,7 @@
 #include "ui/gfx/linux/native_pixmap_dmabuf.h"
 #include "ui/gfx/native_pixmap.h"
 #include "ui/gfx/native_pixmap_handle.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 
 using ::testing::_;
 using ::testing::Return;
@@ -36,6 +41,19 @@
       candidate.overlay_handled = !candidate.buffer_size.IsEmpty();
     }
   }
+
+  // Capture the callback so we can call it at will in tests.
+  void ObserveHardwareCapabilities(
+      ui::HardwareCapabilitiesCallback receive_callback) override {
+    receive_callback_ = std::move(receive_callback);
+  }
+
+  ui::HardwareCapabilitiesCallback& receive_callback() {
+    return receive_callback_;
+  }
+
+ private:
+  ui::HardwareCapabilitiesCallback receive_callback_;
 };
 
 class FakeNativePixmap : public gfx::NativePixmap {
@@ -229,6 +247,71 @@
   processor.CheckOverlaySupport(&primary_plane, &candidates);
   EXPECT_TRUE(candidates.at(0).overlay_handled);
 }
-#endif
+
+#endif  // !BUILDFLAG(IS_FUCHSIA)
+
+// Exposing max_overlays_considered_ saves us from retesting a lot of logic
+// that's already tested in overlay_unittest.cc.
+class TestOverlayProcessorOzone : public OverlayProcessorOzone {
+ public:
+  using OverlayProcessorOzone::OverlayProcessorOzone;
+
+  int MaxOverlaysConsidered() { return max_overlays_considered_; }
+};
+
+TEST(OverlayProcessorOzoneTest, ObserveHardwareCapabilites) {
+  // Enable 4 overlays
+  const std::vector<base::test::ScopedFeatureList::FeatureAndParams>
+      feature_and_params_list = {{features::kEnableOverlayPrioritization, {}},
+                                 {features::kUseMultipleOverlays,
+                                  {{features::kMaxOverlaysParam, "4"}}}};
+  base::test::ScopedFeatureList features;
+  features.InitWithFeaturesAndParameters(feature_and_params_list, {});
+
+  auto fake_candidates_unique = std::make_unique<FakeOverlayCandidatesOzone>();
+  auto* fake_candidates = fake_candidates_unique.get();
+
+  // No receive_callback yet.
+  EXPECT_TRUE(fake_candidates->receive_callback().is_null());
+
+  TestOverlayProcessorOzone processor(std::move(fake_candidates_unique), {},
+                                      nullptr);
+
+  // Receive callback is set.
+  EXPECT_FALSE(fake_candidates->receive_callback().is_null());
+  // Max overlays is still 1.
+  EXPECT_EQ(processor.MaxOverlaysConsidered(), 1);
+
+  ui::HardwareCapabilities hc;
+  hc.num_overlay_capable_planes = 6;
+  fake_candidates->receive_callback().Run(hc);
+
+  // Uses max_overlays_config_ = 4.
+  EXPECT_EQ(processor.MaxOverlaysConsidered(), 4);
+
+  hc.num_overlay_capable_planes = 4;
+  fake_candidates->receive_callback().Run(hc);
+
+  // Uses (num_overlay_capable_planes - 1) = 3.
+  EXPECT_EQ(processor.MaxOverlaysConsidered(), 3);
+}
+
+TEST(OverlayProcessorOzoneTest, NoObserveHardwareCapabilites) {
+  // Multiple overlays disabled.
+  base::test::ScopedFeatureList features;
+  features.InitAndDisableFeature(features::kUseMultipleOverlays);
+
+  auto fake_candidates_unique = std::make_unique<FakeOverlayCandidatesOzone>();
+  auto* fake_candidates = fake_candidates_unique.get();
+
+  // No receive_callback yet.
+  EXPECT_TRUE(fake_candidates->receive_callback().is_null());
+
+  TestOverlayProcessorOzone processor(std::move(fake_candidates_unique), {},
+                                      nullptr);
+
+  // Receive callback is still unset because multiple overlays is disabled.
+  EXPECT_TRUE(fake_candidates->receive_callback().is_null());
+}
 
 }  // namespace viz
diff --git a/components/viz/service/display/overlay_processor_using_strategy.cc b/components/viz/service/display/overlay_processor_using_strategy.cc
index 6b19e42..ffd58a06 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.cc
+++ b/components/viz/service/display/overlay_processor_using_strategy.cc
@@ -93,7 +93,7 @@
 }
 
 OverlayProcessorUsingStrategy::OverlayProcessorUsingStrategy()
-    : max_overlays_considered_(features::MaxOverlaysConsidered()) {}
+    : max_overlays_config_(features::MaxOverlaysConsidered()) {}
 
 OverlayProcessorUsingStrategy::~OverlayProcessorUsingStrategy() = default;
 
diff --git a/components/viz/service/display/overlay_processor_using_strategy.h b/components/viz/service/display/overlay_processor_using_strategy.h
index 71c8b87..9c562bd 100644
--- a/components/viz/service/display/overlay_processor_using_strategy.h
+++ b/components/viz/service/display/overlay_processor_using_strategy.h
@@ -118,6 +118,13 @@
   OverlayPrioritizationConfig prioritization_config_;
   OverlayCandidateTemporalTracker::Config tracker_config_;
 
+  // This is controlled by the "UseMultipleOverlays" feature's "max_overlays"
+  // param.
+  const int max_overlays_config_;
+  // This will remain 1 until hardware support for more than one overlay is
+  // confirmed in `OverlayProcessorOzone::ReceiveHardwareCapabilities`.
+  int max_overlays_considered_ = 1;
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
  protected:
   // TODO(b/181974042):  Remove when color space is plumbed.
@@ -274,8 +281,6 @@
   static ProposedCandidateKey ToProposeKey(
       const OverlayProposedCandidate& proposed);
 
-  const int max_overlays_considered_;
-
   std::unordered_map<ProposedCandidateKey,
                      OverlayCandidateTemporalTracker,
                      ProposedCandidateKeyHasher>
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index 5d2d3f1..4fba6c24 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -214,6 +214,8 @@
     prioritization_config_.changing_threshold = false;
     prioritization_config_.damage_rate_threshold = false;
     prioritization_config_.power_gain_sort = false;
+    // Don't wait for hardware support in these tests.
+    max_overlays_considered_ = max_overlays_config_;
   }
 
   void CheckOverlaySupportImpl(const PrimaryPlane* primary_plane,
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
index b95ae7c2..8689950e 100644
--- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
+++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.cc
@@ -638,6 +638,25 @@
     return;
   }
 
+  // The oracle only keeps track of the source size, which should be the
+  // size of the capture region. If the capture region is empty or if the
+  // capture region isn't a subset of the entire compositor frame region, we
+  // shouldn't capture.
+  const gfx::Rect compositor_frame_region =
+      resolved_target_->GetCopyOutputRequestRegion(VideoCaptureSubTarget{});
+  const gfx::Rect capture_region =
+      resolved_target_->GetCopyOutputRequestRegion(target_->sub_target);
+
+  // This likely means that there is a mismatch between the last aggregated
+  // surface and the last activated surface sizes. To be cautious, we refresh
+  // the frame although a frame damage event should happen shortly.
+  // TODO(https://crbug.com/1300943): we should likely just get the frame
+  // region from the last aggregated surface.
+  if (!compositor_frame_region.Contains(capture_region)) {
+    RequestRefreshFrame();
+    return;
+  }
+
   // Reserve a buffer from the pool for the next frame.
   const OracleFrameNumber oracle_frame_number = oracle_->next_frame_number();
   const gfx::Size capture_size =
@@ -692,6 +711,10 @@
   // At this point, the capture is going to proceed. Populate the VideoFrame's
   // metadata, and notify the oracle.
   const int64_t capture_frame_number = next_capture_frame_number_++;
+  // !WARNING: now that the frame number has been incremented, returning without
+  // adding the frame to the |delivery_queue_| or decrementing the frame number
+  // will cause the queue to be permanently stuck.
+
   VideoFrameMetadata& metadata = frame->metadata();
   metadata.capture_begin_time = clock_->NowTicks();
   metadata.capture_counter = capture_frame_number;
@@ -813,20 +836,6 @@
     return;
   }
 
-  // The oracle only keeps track of the source size, which should be the
-  // size of the capture region. If the capture region is empty or if the
-  // capture region isn't a subset of the entire compositor frame region, we
-  // shouldn't capture.
-  const gfx::Rect compositor_frame_region =
-      resolved_target_->GetCopyOutputRequestRegion(VideoCaptureSubTarget{});
-  const gfx::Rect capture_region =
-      resolved_target_->GetCopyOutputRequestRegion(target_->sub_target);
-
-  // This like means that the compositor frame is being resized but the surface
-  // hasn't been redrawn yet.
-  if (!compositor_frame_region.Contains(capture_region))
-    return;
-
   DCHECK(capture_region.size() == source_size);
   if (absl::holds_alternative<RegionCaptureCropId>(target_->sub_target)) {
     const float scale_factor = frame_metadata.device_scale_factor;
diff --git a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
index 9aceb32..3e4f833 100644
--- a/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
+++ b/components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl_unittest.cc
@@ -146,6 +146,10 @@
     return receiver_.BindNewPipeAndPassRemote();
   }
 
+  int num_frames_with_empty_region() const {
+    return num_frames_with_empty_region_;
+  }
+
  private:
   void OnFrameCaptured(
       media::mojom::VideoBufferHandlePtr data,
@@ -201,7 +205,11 @@
                        std::move(callbacks_remote)));
   }
 
-  void OnFrameWithEmptyRegionCapture() final {}
+  void OnFrameWithEmptyRegionCapture() final {
+    ++num_frames_with_empty_region_;
+  }
+
+  int num_frames_with_empty_region_ = 0;
 
   mojo::Receiver<mojom::FrameSinkVideoConsumer> receiver_{this};
   std::vector<scoped_refptr<VideoFrame>> frames_;
@@ -1531,6 +1539,123 @@
   EXPECT_EQ(kCropId, frame_sink_.current_crop_id());
 }
 
+// Tests that frames can be successfully delivered after one is dropped due to
+// having a zero-sized capture region.
+TEST_F(FrameSinkVideoCapturerTest, HandlesFrameWithEmptyRegion) {
+  const auto kCropId = RegionCaptureCropId::CreateRandom();
+  constexpr gfx::Rect kValidCropBounds{1, 2, 640, 478};
+
+  SwitchToSizeSet(kSizeSets[4]);
+  VideoCaptureTarget target(kVideoCaptureTarget.frame_sink_id, kCropId);
+  frame_sink_.set_crop_bounds(gfx::Rect{});
+  EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(target))
+      .WillRepeatedly(Return(&frame_sink_));
+
+  NiceMock<MockConsumer> consumer;
+  EXPECT_CALL(consumer, OnFrameCapturedMock()).Times(0);
+  EXPECT_CALL(consumer, OnStopped()).Times(1);
+
+  // Start capturing. frame_sink_ should now have one client capturing.
+  StartCapture(&consumer);
+  capturer_->ChangeTarget(target, /*crop_version=*/0);
+  EXPECT_EQ(frame_sink_.number_clients_capturing(), 1);
+
+  // No copy requests should have been issued/executed.
+  EXPECT_EQ(0, frame_sink_.num_copy_results());
+
+  // The refresh timer should be running--our initial attempt to get a frame
+  // failed due to being cropped to zero.
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
+
+  // Simulate several refresh timer intervals elapsing and the timer firing.
+  // Nothing should happen because the frames should be cropped to zero.
+  for (int i = 0; i < 5; ++i) {
+    AdvanceClockForRefreshTimer();
+    ASSERT_EQ(0, frame_sink_.num_copy_results());
+    ASSERT_TRUE(IsRefreshRetryTimerRunning());
+  }
+  // We should only get one notification--the first empty frame.
+  EXPECT_EQ(1, consumer.num_frames_with_empty_region());
+
+  // Now, set the crop bounds to be valid--meaning completely contained inside
+  // of the source rect. As it resolves, the next refresh capture should trigger
+  // a copy request.
+  frame_sink_.set_crop_bounds(kValidCropBounds);
+  AdvanceClockForRefreshTimer();
+  EXPECT_EQ(1, frame_sink_.num_copy_results());
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
+  EXPECT_EQ(1, consumer.num_frames_with_empty_region());
+
+  // The empty frame notification for the consumer is reset when the frame
+  // is delivered to the consumer, so we need to have a result before it gets
+  // reset.
+  EXPECT_CALL(consumer, OnFrameCapturedMock()).Times(1);
+  frame_sink_.SendCopyOutputResult(0);
+
+  // Now, set back to an entirely empty crop bounds--we should get a
+  // notification that we have an empty region.
+  frame_sink_.set_crop_bounds(gfx::Rect{});
+  capturer_->RequestRefreshFrame();
+  AdvanceClockForRefreshTimer();
+  EXPECT_EQ(1, frame_sink_.num_copy_results());
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
+  EXPECT_EQ(2, consumer.num_frames_with_empty_region());
+
+  StopCapture();
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
+}
+
+// Tests that frames can be successfully delivered after one is dropped due to
+// having a capture region that does not intersect with the compositor frame. In
+// the past, it was possible for a dropped frame to cause the delivery queue to
+// no longer be emptied. See https://crbug.com/1300742.
+TEST_F(FrameSinkVideoCapturerTest, HandlesFrameWithRegionCroppedToZero) {
+  const auto kCropId = RegionCaptureCropId::CreateRandom();
+  constexpr gfx::Rect kInvalidCropBounds{800, 600, 100, 100};
+  constexpr gfx::Rect kValidCropBounds{1, 2, 640, 478};
+
+  SwitchToSizeSet(kSizeSets[4]);
+  VideoCaptureTarget target(kVideoCaptureTarget.frame_sink_id, kCropId);
+  frame_sink_.set_crop_bounds(kInvalidCropBounds);
+  EXPECT_CALL(frame_sink_manager_, FindCapturableFrameSink(target))
+      .WillRepeatedly(Return(&frame_sink_));
+
+  NiceMock<MockConsumer> consumer;
+  EXPECT_CALL(consumer, OnFrameCapturedMock()).Times(0);
+  EXPECT_CALL(consumer, OnStopped()).Times(1);
+
+  // Start capturing. frame_sink_ should now have one client capturing.
+  StartCapture(&consumer);
+  capturer_->ChangeTarget(target, /*crop_version=*/0);
+  EXPECT_EQ(frame_sink_.number_clients_capturing(), 1);
+
+  // No copy requests should have been issued/executed.
+  EXPECT_EQ(0, frame_sink_.num_copy_results());
+
+  // The refresh timer should be running--our initial attempt to get a frame
+  // failed due to being cropped to zero.
+  EXPECT_TRUE(IsRefreshRetryTimerRunning());
+
+  // Simulate several refresh timer intervals elapsing and the timer firing.
+  // Nothing should happen because the frames should be cropped to zero.
+  for (int i = 0; i < 5; ++i) {
+    AdvanceClockForRefreshTimer();
+    ASSERT_EQ(0, frame_sink_.num_copy_results());
+    ASSERT_TRUE(IsRefreshRetryTimerRunning());
+  }
+
+  // Now, set the crop bounds to be valid--meaning completely contained inside
+  // of the source rect. As it resolves, the next refresh capture should trigger
+  // a copy request.
+  frame_sink_.set_crop_bounds(kValidCropBounds);
+  AdvanceClockForRefreshTimer();
+  EXPECT_EQ(1, frame_sink_.num_copy_results());
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
+
+  StopCapture();
+  EXPECT_FALSE(IsRefreshRetryTimerRunning());
+}
+
 TEST_F(FrameSinkVideoCapturerTest, HandlesSubtreeCaptureId) {
   SwitchToSizeSet(kSizeSets[4]);
   constexpr gfx::Rect kCaptureBounds{1, 2, 1024, 768};
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
index e6202bf..2d6370c 100644
--- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
+++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -123,8 +123,12 @@
         args.writeInt(1); // This indicates that the following options are present.
 
         try {
-            Fido2Api.appendBrowserMakeCredentialOptionsToParcel(options,
-                    Uri.parse(convertOriginToString(origin)), /* clientDataHash= */ null, args);
+            if (mSupportLevel == WebAuthenticationDelegate.Support.BROWSER) {
+                Fido2Api.appendBrowserMakeCredentialOptionsToParcel(options,
+                        Uri.parse(convertOriginToString(origin)), /* clientDataHash= */ null, args);
+            } else {
+                Fido2Api.appendMakeCredentialOptionsToParcel(options, args);
+            }
         } catch (NoSuchAlgorithmException e) {
             returnErrorAndResetCallback(AuthenticatorStatus.ALGORITHM_UNSUPPORTED);
             return;
@@ -203,8 +207,13 @@
         Fido2ApiCall.PendingIntentResult result = new Fido2ApiCall.PendingIntentResult(call);
         args.writeStrongBinder(result);
         args.writeInt(1); // This indicates that the following options are present.
-        Fido2Api.appendBrowserGetAssertionOptionsToParcel(
-                options, Uri.parse(callerOriginString), clientDataHash, args);
+
+        if (mSupportLevel == WebAuthenticationDelegate.Support.BROWSER) {
+            Fido2Api.appendBrowserGetAssertionOptionsToParcel(
+                    options, Uri.parse(callerOriginString), clientDataHash, args);
+        } else {
+            Fido2Api.appendGetAssertionOptionsToParcel(options, args);
+        }
 
         Task<PendingIntent> task = call.run(
                 Fido2ApiCall.METHOD_BROWSER_SIGN, Fido2ApiCall.TRANSACTION_SIGN, args, result);
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index c9154ee1..da0d4a6 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -545,6 +545,9 @@
   if (root_changed) {
     wcax->HandleNavigate();
   }
+
+  // Update the maximum number of nodes in the cache after each atomic update.
+  wcax->UpdateMaxNodesInCache();
 }
 
 void BrowserAccessibilityManagerAndroid::OnNodeCreated(ui::AXTree* tree,
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index 0239512..95dc993 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -595,6 +595,15 @@
   Java_WebContentsAccessibilityImpl_handleNavigate(env, obj);
 }
 
+void WebContentsAccessibilityAndroid::UpdateMaxNodesInCache() {
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+
+  Java_WebContentsAccessibilityImpl_updateMaxNodesInCache(env, obj);
+}
+
 void WebContentsAccessibilityAndroid::ClearNodeInfoCacheForGivenId(
     int32_t unique_id) {
   JNIEnv* env = AttachCurrentThread();
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h
index 23e34c0..998d278 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.h
+++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -389,6 +389,7 @@
   bool OnHoverEvent(const ui::MotionEventAndroid& event);
   void HandleHover(int32_t unique_id);
   void HandleNavigate();
+  void UpdateMaxNodesInCache();
   void ClearNodeInfoCacheForGivenId(int32_t unique_id);
   void HandleEndOfTestSignal();
   std::u16string GenerateAccessibilityNodeInfoString(int32_t unique_id);
diff --git a/content/browser/android/navigation_handle_proxy.cc b/content/browser/android/navigation_handle_proxy.cc
index a56e8a6..0e8bf218 100644
--- a/content/browser/android/navigation_handle_proxy.cc
+++ b/content/browser/android/navigation_handle_proxy.cc
@@ -81,7 +81,7 @@
 
   if (cpp_navigation_handle_->HasCommitted()) {
     // See http://crbug.com/251330 for why it's determined this way.
-    url::Replacements<char> replacements;
+    GURL::Replacements replacements;
     replacements.ClearRef();
     bool urls_same_ignoring_fragment =
         cpp_navigation_handle_->GetURL().ReplaceComponents(replacements) ==
diff --git a/content/browser/attribution_reporting/attribution_host.cc b/content/browser/attribution_reporting/attribution_host.cc
index a9e589a..ffc93a2 100644
--- a/content/browser/attribution_reporting/attribution_host.cc
+++ b/content/browser/attribution_reporting/attribution_host.cc
@@ -20,7 +20,6 @@
 #include "content/browser/attribution_reporting/attribution_page_metrics.h"
 #include "content/browser/attribution_reporting/attribution_policy.h"
 #include "content/browser/attribution_reporting/attribution_trigger.h"
-#include "content/browser/devtools/devtools_instrumentation.h"
 #include "content/browser/renderer_host/frame_tree.h"
 #include "content/browser/renderer_host/frame_tree_node.h"
 #include "content/browser/renderer_host/render_frame_host_impl.h"
@@ -37,7 +36,6 @@
 #include "mojo/public/cpp/bindings/message.h"
 #include "net/base/schemeful_site.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
-#include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -299,50 +297,20 @@
   if (!allowed)
     return;
 
-  const auto sanitize_trigger_data =
-      [&](const uint64_t unsanitized, CommonSourceInfo::SourceType source_type,
-          devtools_instrumentation::AttributionReportingIssueType issue_type) {
-        const uint64_t sanitized =
-            SanitizeTriggerData(unsanitized, source_type);
-
-        if (sanitized != unsanitized) {
-          devtools_instrumentation::ReportAttributionReportingIssue(
-              render_frame_host, issue_type, conversion->devtools_request_id,
-              base::NumberToString(unsanitized));
-        }
-
-        return sanitized;
-      };
-
-  // TODO(apaseltiner): Set this based on field in `conversion`.
-  absl::optional<int64_t> debug_key;
-
   net::SchemefulSite conversion_destination(main_frame_origin);
 
   AttributionTrigger storable_conversion(
-      sanitize_trigger_data(
-          conversion->conversion_data,
-          CommonSourceInfo::SourceType::kNavigation,
-          devtools_instrumentation::AttributionReportingIssueType::
-              kAttributionTriggerDataTooLarge),
-      std::move(conversion_destination), conversion->reporting_origin,
-      sanitize_trigger_data(
-          conversion->event_source_trigger_data,
-          CommonSourceInfo::SourceType::kEvent,
-          devtools_instrumentation::AttributionReportingIssueType::
-              kAttributionEventSourceTriggerDataTooLarge),
+      conversion->conversion_data, std::move(conversion_destination),
+      conversion->reporting_origin, conversion->event_source_trigger_data,
       conversion->priority,
       conversion->dedup_key.is_null()
           ? absl::nullopt
           : absl::make_optional(conversion->dedup_key->value),
-      debug_key);
+      /*debug_key=*/absl::nullopt);
 
   if (conversion_page_metrics_)
     conversion_page_metrics_->OnConversion(conversion->reporting_origin);
 
-  // TODO(apaseltiner): It would be nice to be able to report an issue in
-  // DevTools in the event that a debug key is present but the corresponding
-  // cookie is not.
   attribution_manager->HandleTrigger(std::move(storable_conversion));
 }
 
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
index ca4eee27..0e1de8ab 100644
--- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
+++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -257,6 +257,12 @@
 void AttributionInternalsHandlerImpl::OnReportSent(
     const AttributionReport& report,
     const SendResult& info) {
+  // TODO(crbug.com/1285317): Show aggregatable reports in internal page.
+  if (!absl::holds_alternative<AttributionReport::EventLevelData>(
+          report.data())) {
+    return;
+  }
+
   mojom::WebUIAttributionReport::Status status;
   switch (info.status) {
     case SendResult::Status::kSent:
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.cc b/content/browser/attribution_reporting/attribution_manager_impl.cc
index 63e09c5..063b145 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl.cc
+++ b/content/browser/attribution_reporting/attribution_manager_impl.cc
@@ -15,6 +15,8 @@
 #include "base/task/lazy_thread_pool_task_runner.h"
 #include "base/threading/sequence_bound.h"
 #include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregatable_report.h"
+#include "content/browser/aggregation_service/aggregation_service_impl.h"
 #include "content/browser/attribution_reporting/attribution_cookie_checker.h"
 #include "content/browser/attribution_reporting/attribution_cookie_checker_impl.h"
 #include "content/browser/attribution_reporting/attribution_data_host_manager_impl.h"
@@ -103,6 +105,12 @@
 
 // Called when |report| is to be sent over network, for logging metrics.
 void LogMetricsOnReportSend(const AttributionReport& report, base::Time now) {
+  // TODO(crbug.com/1285319): Log metrics for aggregatable reports.
+  if (!absl::holds_alternative<AttributionReport::EventLevelData>(
+          report.data())) {
+    return;
+  }
+
   // Use a large time range to capture users that might not open the browser for
   // a long time while a conversion report is pending. Revisit this range if it
   // is non-ideal for real world data.
@@ -120,6 +128,19 @@
                             time_from_conversion_to_report_send.InHours());
 }
 
+// Called when |report| is sent, failed or dropped, for logging metrics.
+void LogMetricsOnReportCompleted(const AttributionReport& report,
+                                 SendResult::Status status) {
+  // TODO(crbug.com/1285319): Log metrics for aggregatable reports.
+  if (!absl::holds_alternative<AttributionReport::EventLevelData>(
+          report.data())) {
+    return;
+  }
+
+  base::UmaHistogramEnumeration("Conversions.ReportSendOutcome",
+                                ConvertToConversionReportSendOutcome(status));
+}
+
 std::unique_ptr<AttributionStorageDelegate> MakeStorageDelegate() {
   bool debug_mode = base::CommandLine::ForCurrentProcess()->HasSwitch(
       switches::kConversionsDebugMode);
@@ -175,11 +196,13 @@
     scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
     std::unique_ptr<AttributionStorageDelegate> storage_delegate,
     std::unique_ptr<AttributionCookieChecker> cookie_checker,
-    std::unique_ptr<AttributionReportSender> report_sender) {
+    std::unique_ptr<AttributionReportSender> report_sender,
+    StoragePartitionImpl* storage_partition) {
   return absl::WrapUnique(new AttributionManagerImpl(
-      std::move(is_report_allowed_callback), user_data_directory,
-      std::move(special_storage_policy), std::move(storage_delegate),
-      std::move(cookie_checker), std::move(report_sender),
+      storage_partition, std::move(is_report_allowed_callback),
+      user_data_directory, std::move(special_storage_policy),
+      std::move(storage_delegate), std::move(cookie_checker),
+      std::move(report_sender),
       /*data_host_manager=*/nullptr));
 }
 
@@ -188,6 +211,7 @@
     const base::FilePath& user_data_directory,
     scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy)
     : AttributionManagerImpl(
+          storage_partition,
           DefaultIsReportAllowedCallback(storage_partition->browser_context()),
           user_data_directory,
           std::move(special_storage_policy),
@@ -199,6 +223,7 @@
               this)) {}
 
 AttributionManagerImpl::AttributionManagerImpl(
+    StoragePartitionImpl* storage_partition,
     IsReportAllowedCallback is_report_allowed_callback,
     const base::FilePath& user_data_directory,
     scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
@@ -206,7 +231,8 @@
     std::unique_ptr<AttributionCookieChecker> cookie_checker,
     std::unique_ptr<AttributionReportSender> report_sender,
     std::unique_ptr<AttributionDataHostManager> data_host_manager)
-    : is_report_allowed_callback_(std::move(is_report_allowed_callback)),
+    : storage_partition_(storage_partition),
+      is_report_allowed_callback_(std::move(is_report_allowed_callback)),
       attribution_storage_(base::SequenceBound<AttributionStorageSql>(
           g_storage_task_runner.Get(),
           user_data_directory,
@@ -428,8 +454,11 @@
 
 void AttributionManagerImpl::GetPendingReportsForInternalUse(
     base::OnceCallback<void(std::vector<AttributionReport>)> callback) {
-  GetAndHandleReports(std::move(callback),
-                      /*max_report_time=*/base::Time::Max(), /*limit=*/1000);
+  // TODO(crbug.com/1285317): Show aggregatable reports in internal page.
+
+  attribution_storage_.AsyncCall(&AttributionStorage::GetEventLevelReports)
+      .WithArgs(/*max_report_time=*/base::Time::Max(), /*limit=*/1000)
+      .Then(std::move(callback));
 }
 
 void AttributionManagerImpl::SendReportsForWebUI(
@@ -462,15 +491,6 @@
           std::move(done), weak_factory_.GetWeakPtr()));
 }
 
-void AttributionManagerImpl::GetAndHandleReports(
-    ReportsHandlerFunc handler_function,
-    base::Time max_report_time,
-    int limit) {
-  attribution_storage_.AsyncCall(&AttributionStorage::GetAttributionsToReport)
-      .WithArgs(max_report_time, limit)
-      .Then(std::move(handler_function));
-}
-
 void AttributionManagerImpl::GetReportsToSend() {
   // We only get the next report time strictly after now, because if we are
   // sending a report now but haven't finished doing so and it is still present
@@ -480,10 +500,10 @@
   //
   // TODO(apaseltiner): Consider limiting the number of reports being sent at
   // once, to avoid pulling an arbitrary number of reports into memory.
-  GetAndHandleReports(
-      base::BindOnce(&AttributionManagerImpl::OnGetReportsToSend,
-                     weak_factory_.GetWeakPtr()),
-      /*max_report_time=*/base::Time::Now(), /*limit=*/-1);
+  attribution_storage_.AsyncCall(&AttributionStorage::GetAttributionReports)
+      .WithArgs(/*max_report_time=*/base::Time::Now(), /*limit=*/-1)
+      .Then(base::BindOnce(&AttributionManagerImpl::OnGetReportsToSend,
+                           weak_factory_.GetWeakPtr()));
 }
 
 void AttributionManagerImpl::OnGetReportsToSend(
@@ -520,13 +540,7 @@
     DCHECK(report.ReportId().has_value());
     DCHECK_LE(report.report_time(), now);
 
-    DCHECK(absl::holds_alternative<AttributionReport::EventLevelData::Id>(
-        *report.ReportId()));
-    bool inserted =
-        reports_being_sent_
-            .emplace(absl::get<AttributionReport::EventLevelData::Id>(
-                *report.ReportId()))
-            .second;
+    bool inserted = reports_being_sent_.emplace(*report.ReportId()).second;
     if (!inserted) {
       done.Run();
       continue;
@@ -546,18 +560,38 @@
     if (log_metrics)
       LogMetricsOnReportSend(report, now);
 
-    report_sender_->SendReport(
-        std::move(report), base::BindOnce(&AttributionManagerImpl::OnReportSent,
-                                          weak_factory_.GetWeakPtr(), done));
+    using DispatchFunc =
+        void (AttributionManagerImpl::*)(AttributionReport, base::OnceClosure);
+
+    struct Visitor {
+      DispatchFunc operator()(const AttributionReport::EventLevelData&) {
+        return &AttributionManagerImpl::SendReport;
+      }
+      DispatchFunc operator()(
+          const AttributionReport::AggregatableContributionData&) {
+        return &AttributionManagerImpl::AssembleAggregateReport;
+      }
+    };
+
+    DispatchFunc func = absl::visit(Visitor{}, report.data());
+    (this->*func)(std::move(report), done);
   }
 }
 
 void AttributionManagerImpl::MarkReportCompleted(
-    AttributionReport::EventLevelData::Id report_id) {
+    AttributionReport::Id report_id) {
   size_t num_removed = reports_being_sent_.erase(report_id);
   DCHECK_EQ(num_removed, 1u);
 }
 
+void AttributionManagerImpl::SendReport(AttributionReport report,
+                                        base::OnceClosure done) {
+  report_sender_->SendReport(
+      std::move(report),
+      base::BindOnce(&AttributionManagerImpl::OnReportSent,
+                     weak_factory_.GetWeakPtr(), std::move(done)));
+}
+
 void AttributionManagerImpl::OnReportSent(base::OnceClosure done,
                                           AttributionReport report,
                                           SendResult info) {
@@ -578,11 +612,6 @@
     }
   }
 
-  DCHECK(absl::holds_alternative<AttributionReport::EventLevelData::Id>(
-      *report.ReportId()));
-  const auto report_id =
-      absl::get<AttributionReport::EventLevelData::Id>(*report.ReportId());
-
   if (should_retry) {
     // After updating the report's failure count and new report time in the DB,
     // add it directly to the queue so that the retry is attempted as the new
@@ -590,12 +619,12 @@
     // occur.
     attribution_storage_
         .AsyncCall(&AttributionStorage::UpdateReportForSendFailure)
-        .WithArgs(report_id, report.report_time())
+        .WithArgs(*report.ReportId(), report.report_time())
         .Then(base::BindOnce(
             [](base::OnceClosure done,
                base::WeakPtr<AttributionManagerImpl> manager,
-               AttributionReport::EventLevelData::Id report_id,
-               base::Time new_report_time, bool success) {
+               AttributionReport::Id report_id, base::Time new_report_time,
+               bool success) {
               std::move(done).Run();
 
               if (manager && success) {
@@ -604,15 +633,15 @@
                 manager->NotifyReportsChanged();
               }
             },
-            std::move(done), weak_factory_.GetWeakPtr(), report_id,
+            std::move(done), weak_factory_.GetWeakPtr(), *report.ReportId(),
             report.report_time()));
   } else {
     attribution_storage_.AsyncCall(&AttributionStorage::DeleteReport)
-        .WithArgs(report_id)
+        .WithArgs(*report.ReportId())
         .Then(base::BindOnce(
             [](base::OnceClosure done,
                base::WeakPtr<AttributionManagerImpl> manager,
-               AttributionReport::EventLevelData::Id report_id, bool success) {
+               AttributionReport::Id report_id, bool success) {
               std::move(done).Run();
 
               if (manager && success) {
@@ -620,11 +649,9 @@
                 manager->NotifyReportsChanged();
               }
             },
-            std::move(done), weak_factory_.GetWeakPtr(), report_id));
+            std::move(done), weak_factory_.GetWeakPtr(), *report.ReportId()));
 
-    base::UmaHistogramEnumeration(
-        "Conversions.ReportSendOutcome",
-        ConvertToConversionReportSendOutcome(info.status));
+    LogMetricsOnReportCompleted(report, info.status);
   }
 
   // TODO(apaseltiner): Consider surfacing retry attempts in internals UI.
@@ -638,6 +665,81 @@
     observer.OnReportSent(report, info);
 }
 
+void AttributionManagerImpl::AssembleAggregateReport(AttributionReport report,
+                                                     base::OnceClosure done) {
+  // TODO(crbug.com/1285319): Add metrics for early exit.
+
+  AggregationServiceImpl* aggregation_service = nullptr;
+  if (storage_partition_)
+    aggregation_service = storage_partition_->GetAggregationService();
+
+  if (!aggregation_service) {
+    OnReportSent(
+        std::move(done), std::move(report),
+        SendResult(SendResult::Status::kDropped, /*http_response_code=*/0));
+    return;
+  }
+
+  const auto* aggregate_data =
+      absl::get_if<AttributionReport::AggregatableContributionData>(
+          &report.data());
+  DCHECK(aggregate_data);
+
+  const AttributionInfo& attribution_info = report.attribution_info();
+
+  AggregatableReportSharedInfo::DebugMode debug_mode =
+      attribution_info.source.common_info().debug_key().has_value() &&
+              attribution_info.debug_key.has_value()
+          ? AggregatableReportSharedInfo::DebugMode::kEnabled
+          : AggregatableReportSharedInfo::DebugMode::kDisabled;
+
+  absl::optional<AggregatableReportRequest> request =
+      AggregatableReportRequest::Create(
+          AggregationServicePayloadContents(
+              AggregationServicePayloadContents::Operation::kHistogram,
+              aggregate_data->contribution.key(),
+              aggregate_data->contribution.value(),
+              AggregationServicePayloadContents::ProcessingType::kSingleServer),
+          AggregatableReportSharedInfo(
+              report.report_time(), report.PrivacyBudgetKey(),
+              report.external_report_id(),
+              attribution_info.source.common_info().reporting_origin(),
+              debug_mode));
+  if (!request.has_value()) {
+    OnReportSent(
+        std::move(done), std::move(report),
+        SendResult(SendResult::Status::kDropped, /*http_response_code=*/0));
+    return;
+  }
+
+  aggregation_service->AssembleReport(
+      std::move(*request),
+      base::BindOnce(&AttributionManagerImpl::OnAggregateReportAssembled,
+                     weak_factory_.GetWeakPtr(), std::move(done),
+                     std::move(report)));
+}
+
+void AttributionManagerImpl::OnAggregateReportAssembled(
+    base::OnceClosure done,
+    AttributionReport report,
+    absl::optional<AggregatableReport> assembled_report,
+    AggregationService::AssemblyStatus status) {
+  if (!assembled_report.has_value()) {
+    OnReportSent(
+        std::move(done), std::move(report),
+        SendResult(SendResult::Status::kDropped, /*http_response_code=*/0));
+    return;
+  }
+
+  auto* aggregate_data =
+      absl::get_if<AttributionReport::AggregatableContributionData>(
+          &report.data());
+  DCHECK(aggregate_data);
+  aggregate_data->assembled_report = std::move(*assembled_report);
+
+  SendReport(std::move(report), std::move(done));
+}
+
 void AttributionManagerImpl::NotifySourcesChanged() {
   for (auto& observer : observers_)
     observer.OnSourcesChanged();
@@ -654,4 +756,20 @@
     observer.OnSourceDeactivated(source);
 }
 
+void AttributionManagerImpl::AddAggregatableAttributionForTesting(
+    AggregatableAttribution aggregatable_attribution) {
+  base::Time report_time = aggregatable_attribution.report_time;
+
+  attribution_storage_
+      .AsyncCall(&AttributionStorage::AddAggregatableAttributionForTesting)
+      .WithArgs(std::move(aggregatable_attribution))
+      .Then(base::BindOnce(
+          [](base::WeakPtr<AttributionManagerImpl> manager,
+             base::Time report_time, bool success) {
+            if (manager && success)
+              manager->scheduler_.ScheduleSend(report_time);
+          },
+          weak_factory_.GetWeakPtr(), report_time));
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h
index 2689883..80cf48f 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl.h
+++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -17,6 +17,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/threading/sequence_bound.h"
+#include "content/browser/aggregation_service/aggregation_service.h"
 #include "content/browser/attribution_reporting/attribution_data_host_manager.h"
 #include "content/browser/attribution_reporting/attribution_manager.h"
 #include "content/browser/attribution_reporting/attribution_report.h"
@@ -37,6 +38,7 @@
 
 namespace content {
 
+class AggregatableReport;
 class AttributionCookieChecker;
 class AttributionReportSender;
 class AttributionStorageDelegate;
@@ -86,7 +88,8 @@
       scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
       std::unique_ptr<AttributionStorageDelegate> storage_delegate,
       std::unique_ptr<AttributionCookieChecker> cookie_checker,
-      std::unique_ptr<AttributionReportSender> report_sender);
+      std::unique_ptr<AttributionReportSender> report_sender,
+      StoragePartitionImpl* storage_partition = nullptr);
 
   AttributionManagerImpl(
       StoragePartitionImpl* storage_partition,
@@ -122,10 +125,14 @@
 
   void MaybeEnqueueEventForTesting(SourceOrTrigger event);
 
+  void AddAggregatableAttributionForTesting(
+      AggregatableAttribution aggregatable_attribution);
+
  private:
   friend class AttributionManagerImplTest;
 
   AttributionManagerImpl(
+      StoragePartitionImpl* storage_partition,
       IsReportAllowedCallback is_report_allowed_callback,
       const base::FilePath& user_data_directory,
       scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy,
@@ -140,15 +147,6 @@
   void StoreSource(StorableSource source);
   void StoreTrigger(AttributionTrigger trigger);
 
-  // Retrieves at most |limit| reports from storage whose |report_time| <=
-  // |max_report_time|, and calls |handler_function| on them; use a negative
-  // number for no limit.
-  using ReportsHandlerFunc =
-      base::OnceCallback<void(std::vector<AttributionReport>)>;
-  void GetAndHandleReports(ReportsHandlerFunc handler_function,
-                           base::Time max_report_time,
-                           int limit);
-
   void GetReportsToSend();
   void OnGetReportsToSend(std::vector<AttributionReport> reports);
 
@@ -158,10 +156,18 @@
   void SendReports(std::vector<AttributionReport> reports,
                    bool log_metrics,
                    base::RepeatingClosure done);
+  void SendReport(AttributionReport report, base::OnceClosure done);
   void OnReportSent(base::OnceClosure done,
                     AttributionReport report,
                     SendResult info);
-  void MarkReportCompleted(AttributionReport::EventLevelData::Id report_id);
+  void AssembleAggregateReport(AttributionReport report,
+                               base::OnceClosure done);
+  void OnAggregateReportAssembled(
+      base::OnceClosure done,
+      AttributionReport report,
+      absl::optional<AggregatableReport> assembled_report,
+      AggregationService::AssemblyStatus status);
+  void MarkReportCompleted(AttributionReport::Id report_id);
 
   void OnReportStored(CreateReportResult result);
 
@@ -170,10 +176,13 @@
   void NotifySourceDeactivated(const DeactivatedSource& source);
 
   // Friend to expose the AttributionStorage for certain tests.
-  friend std::vector<AttributionReport> GetAttributionsToReportForTesting(
+  friend std::vector<AttributionReport> GetAttributionReportsForTesting(
       AttributionManagerImpl* manager,
       base::Time max_report_time);
 
+  // Might be `nullptr` for testing.
+  raw_ptr<StoragePartitionImpl> storage_partition_;
+
   // Internally holds a non-owning pointer to `BrowserContext`.
   IsReportAllowedCallback is_report_allowed_callback_;
 
@@ -202,7 +211,7 @@
   // Set of all conversion IDs that are currently being sent, deleted, or
   // updated. The number of concurrent conversion reports being sent at any time
   // is expected to be small, so a `flat_set` is used.
-  base::flat_set<AttributionReport::EventLevelData::Id> reports_being_sent_;
+  base::flat_set<AttributionReport::Id> reports_being_sent_;
 
   base::ObserverList<AttributionObserver> observers_;
 
diff --git a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
index 3938ce5..180547b 100644
--- a/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_manager_impl_unittest.cc
@@ -27,6 +27,10 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "content/browser/aggregation_service/aggregatable_report.h"
+#include "content/browser/aggregation_service/aggregation_service_impl.h"
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+#include "content/browser/attribution_reporting/aggregatable_attribution.h"
 #include "content/browser/attribution_reporting/attribution_cookie_checker.h"
 #include "content/browser/attribution_reporting/attribution_observer.h"
 #include "content/browser/attribution_reporting/attribution_observer_types.h"
@@ -40,6 +44,7 @@
 #include "content/browser/attribution_reporting/send_result.h"
 #include "content/browser/attribution_reporting/storable_source.h"
 #include "content/browser/attribution_reporting/stored_source.h"
+#include "content/browser/storage_partition_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/test/browser_task_environment.h"
@@ -183,6 +188,39 @@
   base::circular_deque<base::OnceCallback<void(bool)>> callbacks_;
 };
 
+class MockAggregationService : public AggregationServiceImpl {
+ public:
+  explicit MockAggregationService(StoragePartitionImpl* partition)
+      : AggregationServiceImpl(/*run_in_memory=*/true,
+                               /*user_data_directory=*/base::FilePath(),
+                               partition) {}
+
+  void AssembleReport(AggregatableReportRequest report_request,
+                      AssemblyCallback callback) override {
+    calls_.push_back(std::move(report_request));
+    callbacks_.push_back(std::move(callback));
+  }
+
+  using AssembleReportCalls = std::vector<AggregatableReportRequest>;
+
+  const AssembleReportCalls& calls() const { return calls_; }
+
+  void RunCallback(size_t index,
+                   absl::optional<AggregatableReport> report,
+                   AssemblyStatus status) {
+    std::move(callbacks_[index]).Run(std::move(report), status);
+  }
+
+  void Reset() {
+    calls_.clear();
+    callbacks_.clear();
+  }
+
+ private:
+  AssembleReportCalls calls_;
+  std::vector<AssemblyCallback> callbacks_;
+};
+
 }  // namespace
 
 class AttributionManagerImplTest : public testing::Test {
@@ -200,6 +238,7 @@
         network::TestNetworkConnectionTracker::GetInstance());
 
     CreateManager();
+    CreateAggregationService();
   }
 
   void CreateManager() {
@@ -220,7 +259,9 @@
             browser_context_.get()),
         dir_.GetPath(), mock_storage_policy_, std::move(storage_delegate),
         absl::WrapUnique(cookie_checker_.get()),
-        absl::WrapUnique(report_sender_.get()));
+        absl::WrapUnique(report_sender_.get()),
+        static_cast<StoragePartitionImpl*>(
+            browser_context_->GetDefaultStoragePartition()));
   }
 
   void ShutdownManager() {
@@ -233,6 +274,23 @@
     }
   }
 
+  void CreateAggregationService() {
+    auto* partition = static_cast<StoragePartitionImpl*>(
+        browser_context_->GetDefaultStoragePartition());
+    auto aggregation_service =
+        std::make_unique<MockAggregationService>(partition);
+    aggregation_service_ = aggregation_service.get();
+    partition->OverrideAggregationServiceForTesting(
+        std::move(aggregation_service));
+  }
+
+  void ShutdownAggregationService() {
+    auto* partition = static_cast<StoragePartitionImpl*>(
+        browser_context_->GetDefaultStoragePartition());
+    aggregation_service_ = nullptr;
+    partition->OverrideAggregationServiceForTesting(nullptr);
+  }
+
   std::vector<StoredSource> StoredSources() {
     std::vector<StoredSource> result;
     base::RunLoop loop;
@@ -276,6 +334,7 @@
   const raw_ptr<MockCookieChecker> cookie_checker_;
   const raw_ptr<MockReportSender> report_sender_;
   raw_ptr<ConfigurableStorageDelegate> storage_delegate_;
+  raw_ptr<MockAggregationService> aggregation_service_;
 
   std::unique_ptr<AttributionManagerImpl> attribution_manager_;
 };
@@ -1425,4 +1484,137 @@
   EXPECT_THAT(StoredSources(), SizeIs(1));
 }
 
+TEST_F(AttributionManagerImplTest,
+       AggregateReportAssemblySucceeded_ReportSent) {
+  attribution_manager_->HandleSource(SourceBuilder().Build());
+
+  attribution_manager_->AddAggregatableAttributionForTesting(
+      AggregatableAttribution(
+          AttributionInfo(
+              SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+              /*time=*/base::Time::Now(), /*debug_key=*/absl::nullopt),
+          /*report_time=*/base::Time::Now() + base::Hours(1),
+          /*contributions=*/
+          {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}));
+
+  // Make sure the report is not sent earlier than its report time.
+  task_environment_.FastForwardBy(base::Hours(1) - base::Microseconds(1));
+  EXPECT_THAT(aggregation_service_->calls(), IsEmpty());
+
+  task_environment_.FastForwardBy(base::Microseconds(1));
+  EXPECT_THAT(aggregation_service_->calls(), SizeIs(1));
+
+  std::vector<AggregatableReport::AggregationServicePayload> payloads;
+  payloads.emplace_back(/*payload=*/kABCD1234AsBytes,
+                        /*key_id=*/"key_1",
+                        /*debug_cleartext_payload=*/absl::nullopt);
+  payloads.emplace_back(/*payload=*/kEFGH5678AsBytes,
+                        /*key_id=*/"key_2",
+                        /*debug_cleartext_payload=*/absl::nullopt);
+
+  AggregatableReportSharedInfo shared_info(
+      base::Time::FromJavaTime(1234567890123),
+      /*privacy_budget_key=*/"example_pbk", DefaultExternalReportID(),
+      /*reporting_origin=*/
+      url::Origin::Create(GURL("https://example.reporting")),
+      AggregatableReportSharedInfo::DebugMode::kDisabled);
+
+  AggregatableReport report(std::move(payloads), shared_info.SerializeAsJson());
+  aggregation_service_->RunCallback(0, std::move(report),
+                                    AggregationService::AssemblyStatus::kOk);
+  EXPECT_THAT(report_sender_->calls(), SizeIs(1));
+}
+
+TEST_F(AttributionManagerImplTest,
+       AggregateReportAssemblyFailed_ReportNotSent) {
+  attribution_manager_->HandleSource(SourceBuilder().Build());
+
+  attribution_manager_->AddAggregatableAttributionForTesting(
+      AggregatableAttribution(
+          AttributionInfo(
+              SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+              /*time=*/base::Time::Now(), /*debug_key=*/absl::nullopt),
+          /*report_time=*/base::Time::Now() + base::Hours(1),
+          /*contributions=*/
+          {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}));
+
+  // Make sure the report is not sent earlier than its report time.
+  task_environment_.FastForwardBy(base::Hours(1) - base::Microseconds(1));
+  EXPECT_THAT(aggregation_service_->calls(), IsEmpty());
+
+  task_environment_.FastForwardBy(base::Microseconds(1));
+  EXPECT_THAT(aggregation_service_->calls(), SizeIs(1));
+
+  aggregation_service_->RunCallback(
+      0, absl::nullopt, AggregationService::AssemblyStatus::kAssemblyFailed);
+  EXPECT_THAT(report_sender_->calls(), SizeIs(0));
+}
+
+TEST_F(AttributionManagerImplTest, AggregationServiceDisabled_ReportNotSent) {
+  ShutdownAggregationService();
+
+  attribution_manager_->HandleSource(SourceBuilder().Build());
+
+  attribution_manager_->AddAggregatableAttributionForTesting(
+      AggregatableAttribution(
+          AttributionInfo(
+              SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+              /*time=*/base::Time::Now(), /*debug_key=*/absl::nullopt),
+          /*report_time=*/base::Time::Now() + base::Hours(1),
+          /*contributions=*/
+          {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}));
+
+  task_environment_.FastForwardBy(base::Hours(1));
+  EXPECT_THAT(report_sender_->calls(), IsEmpty());
+}
+
+TEST_F(AttributionManagerImplTest, EventAndAggregateReportsStored_BothSent) {
+  attribution_manager_->HandleSource(
+      SourceBuilder().SetExpiry(kImpressionExpiry).Build());
+  attribution_manager_->HandleTrigger(DefaultTrigger());
+
+  attribution_manager_->AddAggregatableAttributionForTesting(
+      AggregatableAttribution(
+          AttributionInfo(
+              SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+              /*time=*/base::Time::Now(), /*debug_key=*/absl::nullopt),
+          /*report_time=*/base::Time::Now() + kFirstReportingWindow,
+          /*contributions=*/
+          {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)}));
+
+  // Make sure the report is not sent earlier than its report time.
+  task_environment_.FastForwardBy(kFirstReportingWindow -
+                                  base::Microseconds(1));
+  EXPECT_THAT(aggregation_service_->calls(), IsEmpty());
+
+  task_environment_.FastForwardBy(base::Microseconds(1));
+
+  // Event-level report was sent.
+  EXPECT_THAT(report_sender_->calls(), SizeIs(1));
+
+  EXPECT_THAT(aggregation_service_->calls(), SizeIs(1));
+
+  std::vector<AggregatableReport::AggregationServicePayload> payloads;
+  payloads.emplace_back(/*payload=*/kABCD1234AsBytes,
+                        /*key_id=*/"key_1",
+                        /*debug_cleartext_payload=*/absl::nullopt);
+  payloads.emplace_back(/*payload=*/kEFGH5678AsBytes,
+                        /*key_id=*/"key_2",
+                        /*debug_cleartext_payload=*/absl::nullopt);
+
+  AggregatableReportSharedInfo shared_info(
+      base::Time::FromJavaTime(1234567890123),
+      /*privacy_budget_key=*/"example_pbk", DefaultExternalReportID(),
+      /*reporting_origin=*/
+      url::Origin::Create(GURL("https://example.reporting")),
+      AggregatableReportSharedInfo::DebugMode::kDisabled);
+
+  AggregatableReport report(std::move(payloads), shared_info.SerializeAsJson());
+  aggregation_service_->RunCallback(0, std::move(report),
+                                    AggregationService::AssemblyStatus::kOk);
+
+  // Aggregatable report was sent.
+  EXPECT_THAT(report_sender_->calls(), SizeIs(2));
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_policy.cc b/content/browser/attribution_reporting/attribution_policy.cc
index 4eae7310..45fa64c 100644
--- a/content/browser/attribution_reporting/attribution_policy.cc
+++ b/content/browser/attribution_reporting/attribution_policy.cc
@@ -5,7 +5,6 @@
 #include "content/browser/attribution_reporting/attribution_policy.h"
 
 #include <math.h>
-#include <stdint.h>
 
 #include "base/check_op.h"
 #include "base/cxx17_backports.h"
@@ -14,12 +13,6 @@
 
 namespace content {
 
-uint64_t SanitizeTriggerData(uint64_t trigger_data,
-                             CommonSourceInfo::SourceType source_type) {
-  const uint64_t cardinality = TriggerDataCardinality(source_type);
-  return trigger_data % cardinality;
-}
-
 base::Time GetExpiryTimeForImpression(
     const absl::optional<base::TimeDelta>& declared_expiry,
     base::Time impression_time,
diff --git a/content/browser/attribution_reporting/attribution_policy.h b/content/browser/attribution_reporting/attribution_policy.h
index f48f0b3..04a7ccc04 100644
--- a/content/browser/attribution_reporting/attribution_policy.h
+++ b/content/browser/attribution_reporting/attribution_policy.h
@@ -5,8 +5,6 @@
 #ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_POLICY_H_
 #define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_POLICY_H_
 
-#include <stdint.h>
-
 #include "content/browser/attribution_reporting/common_source_info.h"
 #include "content/common/content_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -18,10 +16,6 @@
 
 namespace content {
 
-CONTENT_EXPORT
-uint64_t SanitizeTriggerData(uint64_t trigger_data,
-                             CommonSourceInfo::SourceType source_type);
-
 // Returns the expiry time for an impression that is clamped to a maximum
 // value of 30 days from |impression_time|.
 CONTENT_EXPORT
diff --git a/content/browser/attribution_reporting/attribution_policy_unittest.cc b/content/browser/attribution_reporting/attribution_policy_unittest.cc
index 51e4bf42..49c31ef8 100644
--- a/content/browser/attribution_reporting/attribution_policy_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_policy_unittest.cc
@@ -11,29 +11,6 @@
 
 namespace content {
 
-TEST(AttributionPolicyTest, HighEntropyTriggerData_StrippedToLowerBits) {
-  EXPECT_EQ(0u,
-            SanitizeTriggerData(8, CommonSourceInfo::SourceType::kNavigation));
-  EXPECT_EQ(1u,
-            SanitizeTriggerData(9, CommonSourceInfo::SourceType::kNavigation));
-
-  EXPECT_EQ(0u, SanitizeTriggerData(2, CommonSourceInfo::SourceType::kEvent));
-  EXPECT_EQ(1u, SanitizeTriggerData(3, CommonSourceInfo::SourceType::kEvent));
-}
-
-TEST(AttributionPolicyTest, LowEntropyTriggerData_Unchanged) {
-  for (uint64_t trigger_data = 0; trigger_data < 8; trigger_data++) {
-    EXPECT_EQ(trigger_data,
-              SanitizeTriggerData(trigger_data,
-                                  CommonSourceInfo::SourceType::kNavigation));
-  }
-  for (uint64_t trigger_data = 0; trigger_data < 2; trigger_data++) {
-    EXPECT_EQ(trigger_data,
-              SanitizeTriggerData(trigger_data,
-                                  CommonSourceInfo::SourceType::kEvent));
-  }
-}
-
 TEST(AttributionPolicyTest, NoExpiryForImpression_DefaultUsed) {
   const base::Time impression_time = base::Time::Now();
 
diff --git a/content/browser/attribution_reporting/attribution_report.cc b/content/browser/attribution_reporting/attribution_report.cc
index df8bede..4141905 100644
--- a/content/browser/attribution_reporting/attribution_report.cc
+++ b/content/browser/attribution_reporting/attribution_report.cc
@@ -4,13 +4,19 @@
 
 #include "content/browser/attribution_reporting/attribution_report.h"
 
+#include <memory>
+#include <string>
 #include <utility>
 
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/cxx17_backports.h"
+#include "base/memory/raw_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 #include "content/browser/attribution_reporting/common_source_info.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
 #include "net/base/schemeful_site.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/gurl.h"
@@ -116,48 +122,86 @@
 }
 
 base::Value AttributionReport::ReportBody() const {
-  const auto* event_data = absl::get_if<EventLevelData>(&data_);
-  DCHECK(event_data);
+  struct Visitor {
+    raw_ptr<const AttributionReport> report;
 
-  base::Value dict(base::Value::Type::DICTIONARY);
+    base::Value operator()(const EventLevelData& data) {
+      base::Value dict(base::Value::Type::DICTIONARY);
 
-  const CommonSourceInfo& common_source_info =
-      attribution_info_.source.common_info();
+      const CommonSourceInfo& common_source_info =
+          report->attribution_info().source.common_info();
 
-  dict.SetStringKey("attribution_destination",
-                    common_source_info.ConversionDestination().Serialize());
+      dict.SetStringKey("attribution_destination",
+                        common_source_info.ConversionDestination().Serialize());
 
-  // The API denotes these values as strings; a `uint64_t` cannot be put in
-  // a dict as an integer in order to be opaque to various API configurations.
-  dict.SetStringKey("source_event_id",
-                    base::NumberToString(common_source_info.source_event_id()));
+      // The API denotes these values as strings; a `uint64_t` cannot be put in
+      // a dict as an integer in order to be opaque to various API
+      // configurations.
+      dict.SetStringKey(
+          "source_event_id",
+          base::NumberToString(common_source_info.source_event_id()));
 
-  dict.SetStringKey("trigger_data",
-                    base::NumberToString(event_data->trigger_data));
+      dict.SetStringKey("trigger_data",
+                        base::NumberToString(data.trigger_data));
 
-  const char* source_type = nullptr;
-  switch (common_source_info.source_type()) {
-    case CommonSourceInfo::SourceType::kNavigation:
-      source_type = "navigation";
-      break;
-    case CommonSourceInfo::SourceType::kEvent:
-      source_type = "event";
-      break;
-  }
-  dict.SetStringKey("source_type", source_type);
+      const char* source_type = nullptr;
+      switch (common_source_info.source_type()) {
+        case CommonSourceInfo::SourceType::kNavigation:
+          source_type = "navigation";
+          break;
+        case CommonSourceInfo::SourceType::kEvent:
+          source_type = "event";
+          break;
+      }
+      dict.SetStringKey("source_type", source_type);
 
-  dict.SetStringKey("report_id", external_report_id_.AsLowercaseString());
+      dict.SetStringKey("report_id",
+                        report->external_report_id().AsLowercaseString());
 
-  dict.SetDoubleKey("randomized_trigger_rate",
-                    event_data->randomized_trigger_rate);
+      dict.SetDoubleKey("randomized_trigger_rate",
+                        data.randomized_trigger_rate);
 
-  if (absl::optional<uint64_t> debug_key = common_source_info.debug_key())
-    dict.SetStringKey("source_debug_key", base::NumberToString(*debug_key));
+      if (absl::optional<uint64_t> debug_key = common_source_info.debug_key()) {
+        dict.SetStringKey("source_debug_key", base::NumberToString(*debug_key));
+      }
 
-  if (absl::optional<uint64_t> debug_key = attribution_info_.debug_key)
-    dict.SetStringKey("trigger_debug_key", base::NumberToString(*debug_key));
+      if (absl::optional<uint64_t> debug_key =
+              report->attribution_info().debug_key) {
+        dict.SetStringKey("trigger_debug_key",
+                          base::NumberToString(*debug_key));
+      }
 
-  return dict;
+      return dict;
+    }
+
+    base::Value operator()(const AggregatableContributionData& data) {
+      DCHECK(data.assembled_report.has_value());
+
+      const CommonSourceInfo& common_info =
+          report->attribution_info().source.common_info();
+
+      base::Value::DictStorage dict = data.assembled_report->GetAsJson();
+      dict.emplace("source_site", common_info.ImpressionSite().Serialize());
+      dict.emplace("attribution_destination",
+                   common_info.ConversionDestination().Serialize());
+      dict.emplace(
+          "source_registration_time",
+          base::NumberToString(common_info.impression_time().ToJavaTime() /
+                               base::Time::kMillisecondsPerSecond));
+
+      if (absl::optional<uint64_t> debug_key = common_info.debug_key())
+        dict.emplace("source_debug_key", base::NumberToString(*debug_key));
+
+      if (absl::optional<uint64_t> debug_key =
+              report->attribution_info().debug_key) {
+        dict.emplace("trigger_debug_key", base::NumberToString(*debug_key));
+      }
+
+      return base::Value(std::move(dict));
+    }
+  };
+
+  return absl::visit(Visitor{.report = this}, data_);
 }
 
 absl::optional<AttributionReport::Id> AttributionReport::ReportId() const {
@@ -165,6 +209,44 @@
                      data_);
 }
 
+std::string AttributionReport::PrivacyBudgetKey() const {
+  DCHECK(absl::holds_alternative<AggregatableContributionData>(data_));
+
+  std::unique_ptr<crypto::SecureHash> ctx =
+      crypto::SecureHash::Create(crypto::SecureHash::Algorithm::SHA256);
+
+  const CommonSourceInfo& common_source_info =
+      attribution_info_.source.common_info();
+  const std::string serialized_reporting_origin =
+      common_source_info.reporting_origin().Serialize();
+  const std::string serialized_source_site =
+      common_source_info.ImpressionSite().Serialize();
+  const std::string serialized_attribution_destination =
+      common_source_info.ConversionDestination().Serialize();
+
+  static constexpr char kDelimiter[] = ";";
+
+  ctx->Update(serialized_reporting_origin.data(),
+              serialized_reporting_origin.size());
+
+  ctx->Update(kDelimiter, sizeof(kDelimiter));
+  ctx->Update(serialized_source_site.data(), serialized_source_site.size());
+
+  ctx->Update(kDelimiter, sizeof(kDelimiter));
+  ctx->Update(serialized_attribution_destination.data(),
+              serialized_attribution_destination.size());
+
+  // TODO(linnan): Replace with a real version once a version string is decided.
+  static constexpr char kVersion[] = "1.0";
+  ctx->Update(kDelimiter, sizeof(kDelimiter));
+  ctx->Update(kVersion, sizeof(kVersion));
+
+  std::string output(crypto::kSHA256Length, 0);
+  ctx->Finish(base::data(output), output.size());
+
+  return output;
+}
+
 void AttributionReport::set_report_time(base::Time report_time) {
   report_time_ = report_time;
 }
diff --git a/content/browser/attribution_reporting/attribution_report.h b/content/browser/attribution_reporting/attribution_report.h
index 345465f0..50ef399 100644
--- a/content/browser/attribution_reporting/attribution_report.h
+++ b/content/browser/attribution_reporting/attribution_report.h
@@ -10,6 +10,7 @@
 #include "base/guid.h"
 #include "base/time/time.h"
 #include "base/types/strong_alias.h"
+#include "content/browser/aggregation_service/aggregatable_report.h"
 #include "content/browser/attribution_reporting/aggregatable_attribution.h"
 #include "content/browser/attribution_reporting/attribution_info.h"
 #include "content/common/content_export.h"
@@ -83,6 +84,10 @@
     // If null, an ID has not been assigned yet.
     absl::optional<Id> id;
 
+    // The report assembled by the aggregation service. If null, the report has
+    // not been assembled yet.
+    absl::optional<AggregatableReport> assembled_report;
+
     // When adding new members, the corresponding `operator==()` definition in
     // `attribution_test_utils.h` should also be updated.
   };
@@ -108,6 +113,11 @@
 
   absl::optional<Id> ReportId() const;
 
+  // This will be included in aggregatable report to allow aggregation service
+  // to do privacy budgeting. Note that this will DCHECK that the underlying
+  // data is `AggregatableContributionData`.
+  std::string PrivacyBudgetKey() const;
+
   const AttributionInfo& attribution_info() const { return attribution_info_; }
 
   base::Time report_time() const { return report_time_; }
diff --git a/content/browser/attribution_reporting/attribution_storage.h b/content/browser/attribution_reporting/attribution_storage.h
index e8791f4..db69572 100644
--- a/content/browser/attribution_reporting/attribution_storage.h
+++ b/content/browser/attribution_reporting/attribution_storage.h
@@ -76,11 +76,21 @@
   virtual CreateReportResult MaybeCreateAndStoreReport(
       const AttributionTrigger& trigger) = 0;
 
+  // Returns all of the event-level reports that should be sent before
+  // |max_report_time|. This call is logically const, and does not modify the
+  // underlying storage. |limit| limits the number of reports to return; use
+  // a negative number for no limit.
+  // TODO(crbug.com/1285317): Consider removing this interface or changing to
+  // for testing.
+  virtual std::vector<AttributionReport> GetEventLevelReports(
+      base::Time max_report_time,
+      int limit = -1) = 0;
+
   // Returns all of the reports that should be sent before
   // |max_report_time|. This call is logically const, and does not modify the
   // underlying storage. |limit| limits the number of reports to return; use
   // a negative number for no limit. Reports are shuffled before being returned.
-  virtual std::vector<AttributionReport> GetAttributionsToReport(
+  virtual std::vector<AttributionReport> GetAttributionReports(
       base::Time max_report_time,
       int limit = -1) = 0;
 
@@ -108,7 +118,7 @@
   // its report time to the given value. Should be called after a transient
   // failure to send the report so that it is retried later.
   [[nodiscard]] virtual bool UpdateReportForSendFailure(
-      AttributionReport::EventLevelData::Id report_id,
+      AttributionReport::Id report_id,
       base::Time new_report_time) = 0;
 
   // Adjusts the report time of all reports that should have been sent while the
@@ -135,14 +145,6 @@
   // Aggregate Attribution:
   [[nodiscard]] virtual bool AddAggregatableAttributionForTesting(
       const AggregatableAttribution& aggregatable_attribution) = 0;
-
-  // Returns all of the aggregatable reports that should be sent before
-  // `max_report_time`. This call is logically const, and does not modify the
-  // underlying storage. `limit` limits the number of reports to return; use a
-  // negative number for no limit.
-  virtual std::vector<AttributionReport>
-  GetAggregatableContributionReportsForTesting(base::Time max_report_time,
-                                               int limit = -1) = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate.h b/content/browser/attribution_reporting/attribution_storage_delegate.h
index 7528301..a97ffe766 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate.h
+++ b/content/browser/attribution_reporting/attribution_storage_delegate.h
@@ -137,6 +137,11 @@
   // Returns the maximum sum of the contributions (values) across all buckets
   // per source.
   virtual int64_t GetAggregatableBudgetPerSource() const = 0;
+
+  // Sanitizes `trigger_data` according to the data limits for `source_type`.
+  virtual uint64_t SanitizeTriggerData(
+      uint64_t trigger_data,
+      CommonSourceInfo::SourceType source_type) const = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
index b41670e..93ad1cf 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/attribution_reporting/attribution_storage_delegate_impl.h"
 
+#include <stdint.h>
+
 #include <cstdlib>
 #include <utility>
 
@@ -20,6 +22,19 @@
 
 namespace content {
 
+namespace {
+
+uint64_t TriggerDataCardinality(CommonSourceInfo::SourceType source_type) {
+  switch (source_type) {
+    case CommonSourceInfo::SourceType::kNavigation:
+      return 8;
+    case CommonSourceInfo::SourceType::kEvent:
+      return 2;
+  }
+}
+
+}  // namespace
+
 // static
 std::unique_ptr<AttributionStorageDelegate>
 AttributionStorageDelegateImpl::CreateForTesting(
@@ -254,4 +269,11 @@
   return 65536;
 }
 
+uint64_t AttributionStorageDelegateImpl::SanitizeTriggerData(
+    uint64_t trigger_data,
+    CommonSourceInfo::SourceType source_type) const {
+  const uint64_t cardinality = TriggerDataCardinality(source_type);
+  return trigger_data % cardinality;
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl.h b/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
index 952d6fa..6223ff6 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl.h
@@ -64,6 +64,9 @@
   RandomizedResponse GetRandomizedResponse(
       const CommonSourceInfo& source) override;
   int64_t GetAggregatableBudgetPerSource() const override;
+  uint64_t SanitizeTriggerData(
+      uint64_t trigger_data,
+      CommonSourceInfo::SourceType source_type) const override;
 
   // Generates fake reports using a random "stars and bars" sequence index of a
   // possible output of the API.
diff --git a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
index e280203..8ab4dca 100644
--- a/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_delegate_impl_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "content/browser/attribution_reporting/attribution_storage_delegate_impl.h"
 
+#include <stdint.h>
+
 #include <vector>
 
 #include "base/containers/flat_map.h"
@@ -364,4 +366,25 @@
                            /*tolerance=*/0.9);
 }
 
+TEST(AttributionStorageDelegateImplTest, SanitizeTriggerData) {
+  const struct {
+    CommonSourceInfo::SourceType source_type;
+    uint64_t trigger_data;
+    uint64_t expected;
+  } kTestCases[] = {
+      {CommonSourceInfo::SourceType::kNavigation, 7, 7},
+      {CommonSourceInfo::SourceType::kNavigation, 8, 0},
+      {CommonSourceInfo::SourceType::kNavigation, 9, 1},
+      {CommonSourceInfo::SourceType::kEvent, 1, 1},
+      {CommonSourceInfo::SourceType::kEvent, 2, 0},
+      {CommonSourceInfo::SourceType::kEvent, 3, 1},
+  };
+
+  for (const auto& test_case : kTestCases) {
+    EXPECT_EQ(test_case.expected,
+              AttributionStorageDelegateImpl().SanitizeTriggerData(
+                  test_case.trigger_data, test_case.source_type));
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
index de2582c..49846f7f 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include <iterator>
 #include <limits>
 #include <string>
 #include <tuple>
@@ -21,6 +22,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/checked_math.h"
+#include "base/ranges/algorithm.h"
 #include "base/time/time.h"
 #include "content/browser/attribution_reporting/aggregatable_attribution.h"
 #include "content/browser/attribution_reporting/attribution_info.h"
@@ -37,6 +39,7 @@
 #include "sql/database.h"
 #include "sql/recovery.h"
 #include "sql/statement.h"
+#include "sql/statement_id.h"
 #include "sql/transaction.h"
 #include "third_party/abseil-cpp/absl/numeric/int128.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -206,6 +209,32 @@
 const base::FilePath::CharType kDatabasePath[] =
     FILE_PATH_LITERAL("Conversions");
 
+#define ATTRIBUTION_CONVERSIONS_TABLE "conversions"
+#define ATTRIBUTION_AGGREGATABLE_CONTRIBUTIONS_TABLE \
+  "aggregatable_contributions"
+
+#define ATTRIBUTION_UPDATE_FAILED_REPORT_SQL(table, column) \
+  "UPDATE " table                                           \
+  " SET report_time=?,"                                     \
+  "failed_send_attempts=failed_send_attempts+1 "            \
+  "WHERE " column "=?"
+
+#define ATTRIBUTION_NEXT_REPORT_TIME_SQL(table) \
+  "SELECT MIN(report_time) FROM " table " WHERE report_time>?"
+
+// Set the report time for all reports that should have been sent before now
+// to now + a random number of microseconds between `min_delay` and
+// `max_delay`, both inclusive. We use RANDOM, instead of a method on the
+// delegate, to avoid having to pull all reports into memory and update them
+// one by one. We use ABS because RANDOM may return a negative integer. We add
+// 1 to the difference between `max_delay` and `min_delay` to ensure that the
+// range of generated values is inclusive. If `max_delay == min_delay`, we
+// take the remainder modulo 1, which is always 0.
+#define ATTRIBUTION_SET_REPORT_TIME_SQL(table) \
+  "UPDATE " table                              \
+  " SET report_time=?+ABS(RANDOM()%?) "        \
+  "WHERE report_time<?"
+
 void RecordInitializationStatus(
     const AttributionStorageSql::InitStatus status) {
   base::UmaHistogramEnumeration("Conversions.Storage.Sql.InitStatus2", status);
@@ -334,6 +363,17 @@
   return ReadSourceFromStatement(statement);
 }
 
+absl::optional<base::Time> GetMinTime(absl::optional<base::Time> a,
+                                      absl::optional<base::Time> b) {
+  if (!a.has_value())
+    return b;
+
+  if (!b.has_value())
+    return a;
+
+  return std::min(*a, *b);
+}
+
 }  // namespace
 
 // static
@@ -558,6 +598,10 @@
     const base::Time trigger_time = common_info.impression_time();
 
     for (const auto& fake_report : *randomized_response) {
+      DCHECK_EQ(fake_report.trigger_data,
+                delegate_->SanitizeTriggerData(fake_report.trigger_data,
+                                               common_info.source_type()));
+
       if (!StoreReport(source_id, fake_report.trigger_data, trigger_time,
                        fake_report.report_time,
                        /*priority=*/0, delegate_->NewReportID(),
@@ -747,6 +791,9 @@
       trigger_data = trigger.event_source_trigger_data();
       break;
   }
+  // TODO(apaseltiner): Consider informing the manager if the trigger
+  // data was out of range for DevTools issue reporting.
+  trigger_data = delegate_->SanitizeTriggerData(trigger_data, source_type);
 
   const base::Time report_time =
       delegate_->GetReportTime(source_to_attribute->source.common_info(),
@@ -1042,15 +1089,45 @@
   return report;
 }
 
-// TODO(linnan): Move `GetAggregatableContributionReportsForTesting()` into this
-// function.
-std::vector<AttributionReport> AttributionStorageSql::GetAttributionsToReport(
+std::vector<AttributionReport> AttributionStorageSql::GetEventLevelReports(
     base::Time max_report_time,
     int limit) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent))
     return {};
 
+  return GetEventLevelReportsInternal(max_report_time, limit);
+}
+
+std::vector<AttributionReport> AttributionStorageSql::GetAttributionReports(
+    base::Time max_report_time,
+    int limit) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent))
+    return {};
+
+  std::vector<AttributionReport> reports =
+      GetEventLevelReportsInternal(max_report_time, limit);
+  std::vector<AttributionReport> aggregate_reports =
+      GetAggregatableContributionReportsInternal(max_report_time, limit);
+
+  reports.insert(reports.end(),
+                 std::make_move_iterator(aggregate_reports.begin()),
+                 std::make_move_iterator(aggregate_reports.end()));
+
+  if (limit < 0 || reports.size() <= static_cast<size_t>(limit))
+    return reports;
+
+  base::ranges::sort(reports, /*comp=*/{}, &AttributionReport::report_time);
+
+  return std::vector<AttributionReport>(
+      std::make_move_iterator(reports.begin()),
+      std::make_move_iterator(reports.begin() + limit));
+}
+
+std::vector<AttributionReport>
+AttributionStorageSql::GetEventLevelReportsInternal(base::Time max_report_time,
+                                                    int limit) {
   // Get at most |limit| entries in the conversions table with a |report_time|
   // no greater than |max_report_time| and their matching information from the
   // impression table. Negatives are treated as no limit
@@ -1091,11 +1168,19 @@
   if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent))
     return absl::nullopt;
 
-  static constexpr char kNextReportTimeSql[] =
-      "SELECT MIN(report_time) FROM conversions "
-      "WHERE report_time > ?";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kNextReportTimeSql));
+  absl::optional<base::Time> next_event_report_time =
+      GetNextEventLevelReportTime(time);
+  absl::optional<base::Time> next_aggregate_report_time =
+      GetNextAggregatableContributionReportTime(time);
+
+  return GetMinTime(next_event_report_time, next_aggregate_report_time);
+}
+
+absl::optional<base::Time> AttributionStorageSql::GetNextReportTime(
+    sql::StatementID id,
+    const char* sql,
+    base::Time time) {
+  sql::Statement statement(db_->GetCachedStatement(id, sql));
   statement.BindTime(0, time);
 
   if (statement.Step() &&
@@ -1106,6 +1191,13 @@
   return absl::nullopt;
 }
 
+absl::optional<base::Time> AttributionStorageSql::GetNextEventLevelReportTime(
+    base::Time time) {
+  static constexpr char kNextReportTimeSql[] =
+      ATTRIBUTION_NEXT_REPORT_TIME_SQL(ATTRIBUTION_CONVERSIONS_TABLE);
+  return GetNextReportTime(SQL_FROM_HERE, kNextReportTimeSql, time);
+}
+
 std::vector<AttributionReport> AttributionStorageSql::GetReports(
     const std::vector<AttributionReport::EventLevelData::Id>& ids) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1242,20 +1334,47 @@
 }
 
 bool AttributionStorageSql::UpdateReportForSendFailure(
-    AttributionReport::EventLevelData::Id conversion_id,
+    AttributionReport::Id report_id,
     base::Time new_report_time) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent))
     return false;
 
-  static constexpr char kUpdateFailedReportSql[] =
-      "UPDATE conversions SET report_time = ?,"
-      "failed_send_attempts = failed_send_attempts + 1 "
-      "WHERE conversion_id = ?";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kUpdateFailedReportSql));
+  struct Visitor {
+    raw_ptr<AttributionStorageSql> storage;
+    base::Time new_report_time;
+
+    bool operator()(AttributionReport::EventLevelData::Id id) {
+      DCHECK_CALLED_ON_VALID_SEQUENCE(storage->sequence_checker_);
+      static constexpr char kUpdateFailedReportSql[] =
+          ATTRIBUTION_UPDATE_FAILED_REPORT_SQL(ATTRIBUTION_CONVERSIONS_TABLE,
+                                               "conversion_id");
+      return storage->UpdateReportForSendFailure(
+          SQL_FROM_HERE, kUpdateFailedReportSql, *id, new_report_time);
+    }
+
+    bool operator()(AttributionReport::AggregatableContributionData::Id id) {
+      DCHECK_CALLED_ON_VALID_SEQUENCE(storage->sequence_checker_);
+      static constexpr char kUpdateFailedReportSql[] =
+          ATTRIBUTION_UPDATE_FAILED_REPORT_SQL(
+              ATTRIBUTION_AGGREGATABLE_CONTRIBUTIONS_TABLE, "contribution_id");
+      return storage->UpdateReportForSendFailure(
+          SQL_FROM_HERE, kUpdateFailedReportSql, *id, new_report_time);
+    }
+  };
+
+  return absl::visit(
+      Visitor{.storage = this, .new_report_time = new_report_time}, report_id);
+}
+
+bool AttributionStorageSql::UpdateReportForSendFailure(
+    sql::StatementID id,
+    const char* sql,
+    int64_t report_id,
+    base::Time new_report_time) {
+  sql::Statement statement(db_->GetCachedStatement(id, sql));
   statement.BindTime(0, new_report_time);
-  statement.BindInt64(1, *conversion_id);
+  statement.BindInt64(1, report_id);
   return statement.Run() && db_->GetLastChangeCount() == 1;
 }
 
@@ -1275,27 +1394,39 @@
 
   base::Time now = base::Time::Now();
 
-  // Set the report time for all reports that should have been sent before now
-  // to now + a random number of microseconds between `min` and `max`, both
-  // inclusive. We use RANDOM, instead of a method on the delegate, to avoid
-  // having to pull all reports into memory and update them one by one. We use
-  // ABS because RANDOM may return a negative integer. We add 1 to the
-  // difference between `max` and `min` to ensure that the range of generated
-  // values is inclusive. If `max == min`, we take the remainder modulo 1, which
-  // is always 0.
-  static constexpr char kSetReportTimeSql[] =
-      "UPDATE conversions "
-      "SET report_time=?+ABS(RANDOM()%?)"
-      "WHERE report_time<?";
-  sql::Statement statement(
-      db_->GetCachedStatement(SQL_FROM_HERE, kSetReportTimeSql));
-  statement.BindTime(0, now + delay->min);
-  statement.BindInt64(1, 1 + (delay->max - delay->min).InMicroseconds());
-  statement.BindTime(2, now);
-  if (!statement.Run())
-    return absl::nullopt;
+  absl::optional<base::Time> next_event_report_time =
+      AdjustOfflineEventLevelReportTimes(delay->min, delay->max, now);
+  absl::optional<base::Time> next_aggregate_report_time =
+      AdjustOfflineAggregatableContributionReportTimes(delay->min, delay->max,
+                                                       now);
+  return GetMinTime(next_event_report_time, next_aggregate_report_time);
+}
 
-  return GetNextReportTime(base::Time::Min());
+bool AttributionStorageSql::AdjustOfflineReportTimes(sql::StatementID id,
+                                                     const char* sql,
+                                                     base::TimeDelta min_delay,
+                                                     base::TimeDelta max_delay,
+                                                     base::Time now) {
+  sql::Statement statement(db_->GetCachedStatement(id, sql));
+  statement.BindTime(0, now + min_delay);
+  statement.BindInt64(1, 1 + (max_delay - min_delay).InMicroseconds());
+  statement.BindTime(2, now);
+  return statement.Run();
+}
+
+absl::optional<base::Time>
+AttributionStorageSql::AdjustOfflineEventLevelReportTimes(
+    base::TimeDelta min_delay,
+    base::TimeDelta max_delay,
+    base::Time now) {
+  static constexpr char kSetReportTimeSql[] =
+      ATTRIBUTION_SET_REPORT_TIME_SQL(ATTRIBUTION_CONVERSIONS_TABLE);
+  if (!AdjustOfflineReportTimes(SQL_FROM_HERE, kSetReportTimeSql, min_delay,
+                                max_delay, now)) {
+    return absl::nullopt;
+  }
+
+  return GetNextEventLevelReportTime(base::Time::Min());
 }
 
 void AttributionStorageSql::ClearData(
@@ -1824,7 +1955,7 @@
     return false;
 
   // Optimize sorting reports by report time for calls to
-  // GetAttributionsToReport(). The reports with the earliest report times are
+  // `GetAttributionReports()`. The reports with the earliest report times are
   // periodically fetched from storage to be sent.
   static constexpr char kConversionReportTimeIndexSql[] =
       "CREATE INDEX IF NOT EXISTS conversion_report_idx "
@@ -1877,7 +2008,7 @@
 
   // Optimizes aggregatable report look up by source id during calls to
   // `DeleteExpiredSources()`, `ClearAggregatableAttributionForSourceIds()`,
-  // `GetAggregatableContributionReportsForTesting()`.
+  // `GetAggregatableContributionReportsInternal()`.
   static constexpr char kAggregateSourceIdIndexSql[] =
       "CREATE INDEX IF NOT EXISTS aggregate_source_id_idx "
       "ON aggregatable_report_metadata(source_id)";
@@ -1927,7 +2058,7 @@
 
   // Optimizes contribution report look up by report time to get reports in a
   // time range during calls to
-  // `GetAggregatableContributionReportsForTesting()`.
+  // `GetAggregatableContributionReportsInternal()`.
   static constexpr char kContributionReportTimeIndexSql[] =
       "CREATE INDEX IF NOT EXISTS contribution_report_time_idx "
       "ON aggregatable_contributions(report_time)";
@@ -2250,13 +2381,9 @@
 }
 
 std::vector<AttributionReport>
-AttributionStorageSql::GetAggregatableContributionReportsForTesting(
+AttributionStorageSql::GetAggregatableContributionReportsInternal(
     base::Time max_report_time,
     int limit) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent))
-    return {};
-
   // TODO(linnan): Consider breaking the SQL query down for simplicity.
   // See the comment in crrev.com/c/3379484 for more information.
   static constexpr char kGetContributionsSql[] =
@@ -2441,4 +2568,27 @@
   return statement.Run() && db_->GetLastChangeCount() == 1;
 }
 
+absl::optional<base::Time>
+AttributionStorageSql::GetNextAggregatableContributionReportTime(
+    base::Time time) {
+  static constexpr char kNextReportTimeSql[] = ATTRIBUTION_NEXT_REPORT_TIME_SQL(
+      ATTRIBUTION_AGGREGATABLE_CONTRIBUTIONS_TABLE);
+  return GetNextReportTime(SQL_FROM_HERE, kNextReportTimeSql, time);
+}
+
+absl::optional<base::Time>
+AttributionStorageSql::AdjustOfflineAggregatableContributionReportTimes(
+    base::TimeDelta min_delay,
+    base::TimeDelta max_delay,
+    base::Time now) {
+  static constexpr char kSetReportTimeSql[] = ATTRIBUTION_SET_REPORT_TIME_SQL(
+      ATTRIBUTION_AGGREGATABLE_CONTRIBUTIONS_TABLE);
+  if (!AdjustOfflineReportTimes(SQL_FROM_HERE, kSetReportTimeSql, min_delay,
+                                max_delay, now)) {
+    return absl::nullopt;
+  }
+
+  return GetNextAggregatableContributionReportTime(base::Time::Min());
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h
index dc74bcf6..d053eb1 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.h
+++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_STORAGE_SQL_H_
 #define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_STORAGE_SQL_H_
 
+#include <stdint.h>
+
 #include <memory>
 #include <vector>
 
@@ -27,6 +29,7 @@
 namespace sql {
 class Database;
 class Statement;
+class StatementID;
 }  // namespace sql
 
 namespace content {
@@ -96,7 +99,10 @@
       int deactivated_source_return_limit = -1) override;
   CreateReportResult MaybeCreateAndStoreReport(
       const AttributionTrigger& trigger) override;
-  std::vector<AttributionReport> GetAttributionsToReport(
+  std::vector<AttributionReport> GetEventLevelReports(
+      base::Time max_report_time,
+      int limit = -1) override;
+  std::vector<AttributionReport> GetAttributionReports(
       base::Time max_report_time,
       int limit = -1) override;
   absl::optional<base::Time> GetNextReportTime(base::Time time) override;
@@ -104,9 +110,8 @@
       const std::vector<AttributionReport::EventLevelData::Id>& ids) override;
   std::vector<StoredSource> GetActiveSources(int limit = -1) override;
   bool DeleteReport(AttributionReport::Id report_id) override;
-  bool UpdateReportForSendFailure(
-      AttributionReport::EventLevelData::Id report_id,
-      base::Time new_report_time) override;
+  bool UpdateReportForSendFailure(AttributionReport::Id report_id,
+                                  base::Time new_report_time) override;
   absl::optional<base::Time> AdjustOfflineReportTimes() override;
   void ClearData(
       base::Time delete_begin,
@@ -114,9 +119,6 @@
       base::RepeatingCallback<bool(const url::Origin&)> filter) override;
   bool AddAggregatableAttributionForTesting(
       const AggregatableAttribution& aggregatable_attribution) override;
-  std::vector<AttributionReport> GetAggregatableContributionReportsForTesting(
-      base::Time max_report_time,
-      int limit = -1) override;
 
   void ClearAllDataAllTime() VALID_CONTEXT_REQUIRED(sequence_checker_);
 
@@ -205,6 +207,36 @@
   absl::optional<AttributionReport> ReadReportFromStatement(sql::Statement&)
       VALID_CONTEXT_REQUIRED(sequence_checker_);
 
+  std::vector<AttributionReport> GetEventLevelReportsInternal(
+      base::Time max_report_time,
+      int limit) VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  [[nodiscard]] bool UpdateReportForSendFailure(sql::StatementID id,
+                                                const char* sql,
+                                                int64_t report_id,
+                                                base::Time new_report_time)
+      VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  absl::optional<base::Time> GetNextReportTime(sql::StatementID id,
+                                               const char* sql,
+                                               base::Time time)
+      VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  [[nodiscard]] bool AdjustOfflineReportTimes(sql::StatementID id,
+                                              const char* sql,
+                                              base::TimeDelta min_delay,
+                                              base::TimeDelta max_delay,
+                                              base::Time now)
+      VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  absl::optional<base::Time> GetNextEventLevelReportTime(base::Time time)
+      VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  absl::optional<base::Time> AdjustOfflineEventLevelReportTimes(
+      base::TimeDelta min_delay,
+      base::TimeDelta max_delay,
+      base::Time now) VALID_CONTEXT_REQUIRED(sequence_checker_);
+
   // Initializes the database if necessary, and returns whether the database is
   // open. |should_create| indicates whether the database should be created if
   // it is not already.
@@ -252,6 +284,10 @@
       const std::vector<StoredSource::Id>& source_ids)
       VALID_CONTEXT_REQUIRED(sequence_checker_);
 
+  std::vector<AttributionReport> GetAggregatableContributionReportsInternal(
+      base::Time max_report_time,
+      int limit) VALID_CONTEXT_REQUIRED(sequence_checker_);
+
   // Deletes the report with `report_id` without checking the the DB
   // initialization status or the number of deleted rows. Returns false on
   // failure.
@@ -275,6 +311,14 @@
       int64_t additional_budget_consumed)
       VALID_CONTEXT_REQUIRED(sequence_checker_);
 
+  absl::optional<base::Time> GetNextAggregatableContributionReportTime(
+      base::Time time) VALID_CONTEXT_REQUIRED(sequence_checker_);
+
+  absl::optional<base::Time> AdjustOfflineAggregatableContributionReportTimes(
+      base::TimeDelta min_delay,
+      base::TimeDelta max_delay,
+      base::Time now) VALID_CONTEXT_REQUIRED(sequence_checker_);
+
   static bool g_run_in_memory_;
 
   // If set, database errors will not crash the client when run in debug mode.
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc
index 26c8f7d..7a681c1 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations_unittest.cc
@@ -45,7 +45,7 @@
 
     // We need to run an operation on storage to force the lazy initialization.
     std::ignore =
-        static_cast<AttributionStorage*>(&storage)->GetAttributionsToReport(
+        static_cast<AttributionStorage*>(&storage)->GetAttributionReports(
             base::Time::Min());
   }
 
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
index b03ed97..60c99ec 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql_unittest.cc
@@ -129,7 +129,7 @@
   // Operations which don't need to run on an empty database should not create
   // the database.
   OpenDatabase();
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
   CloseDatabase();
 
   EXPECT_FALSE(base::PathExists(db_path()));
@@ -171,16 +171,16 @@
 TEST_F(AttributionStorageSqlTest, DatabaseReopened_DataPersisted) {
   OpenDatabase();
   AddReportToStorage();
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
   CloseDatabase();
   OpenDatabase();
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
 }
 
 TEST_F(AttributionStorageSqlTest, CorruptDatabase_RecoveredOnOpen) {
   OpenDatabase();
   AddReportToStorage();
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
   CloseDatabase();
 
   // Corrupt the database.
@@ -193,7 +193,7 @@
   EXPECT_NO_FATAL_FAILURE(OpenDatabase());
 
   // Data should be recovered.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
 
   EXPECT_TRUE(expecter.SawExpectedErrors());
 }
@@ -201,7 +201,7 @@
 TEST_F(AttributionStorageSqlTest, VersionTooNew_RazesDB) {
   OpenDatabase();
   AddReportToStorage();
-  ASSERT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  ASSERT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
   CloseDatabase();
 
   {
@@ -218,7 +218,7 @@
 
   // The DB should be razed because the version is too new.
   ASSERT_NO_FATAL_FAILURE(OpenDatabase());
-  ASSERT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  ASSERT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 // Create an impression with three conversions and craft a query that will
@@ -249,7 +249,7 @@
       base::Time::Min(), base::Time::Max(),
       base::BindRepeating(std::equal_to<url::Origin>(),
                           impression.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -287,7 +287,7 @@
       base::Time::Now(), base::Time::Now(),
       base::BindRepeating(std::equal_to<url::Origin>(),
                           impression.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -321,7 +321,7 @@
   // Use a time range that only intersects the last conversion.
   auto null_filter = base::RepeatingCallback<bool(const url::Origin&)>();
   storage()->ClearData(base::Time::Now(), base::Time::Now(), null_filter);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -355,7 +355,7 @@
 
   auto null_filter = base::RepeatingCallback<bool(const url::Origin&)>();
   storage()->ClearData(base::Time::Min(), base::Time::Max(), null_filter);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -414,9 +414,7 @@
       base::Time::Min(), base::Time::Max(),
       base::BindRepeating(std::equal_to<url::Origin>(),
                           stored_source.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAggregatableContributionReportsForTesting(
-                  base::Time::Max()),
-              IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -463,9 +461,7 @@
       base::Time::Now(), base::Time::Now(),
       base::BindRepeating(std::equal_to<url::Origin>(),
                           stored_source.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAggregatableContributionReportsForTesting(
-                  base::Time::Max()),
-              IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -506,9 +502,7 @@
   // Use a time range that only intersects the last aggregatable attribution.
   storage()->ClearData(base::Time::Now(), base::Time::Now(),
                        base::NullCallback());
-  EXPECT_THAT(storage()->GetAggregatableContributionReportsForTesting(
-                  base::Time::Max()),
-              IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -553,9 +547,7 @@
 
   storage()->ClearData(base::Time::Min(), base::Time::Max(),
                        base::NullCallback());
-  EXPECT_THAT(storage()->GetAggregatableContributionReportsForTesting(
-                  base::Time::Max()),
-              IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
@@ -786,7 +778,7 @@
               .SetReportingOrigin(impression.common_info().reporting_origin())
               .Build()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(EventLevelDataIs(TriggerDataIs(kMaxUint64))));
 }
 
@@ -884,7 +876,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   EXPECT_THAT(reports, SizeIs(1));
   EXPECT_TRUE(storage()->DeleteReport(
       *(absl::get<AttributionReport::EventLevelData>(reports[0].data()).id)));
@@ -919,8 +911,7 @@
       AttributionReport::AggregatableContributionData::Id(1)));
 
   EXPECT_THAT(
-      storage()->GetAggregatableContributionReportsForTesting(
-          base::Time::Max()),
+      storage()->GetAttributionReports(base::Time::Max()),
       ElementsAre(AttributionReport(
           attribution_info, aggregatable_attribution.report_time,
           DefaultExternalReportID(),
@@ -930,9 +921,7 @@
 
   EXPECT_TRUE(storage()->DeleteReport(
       AttributionReport::AggregatableContributionData::Id(2)));
-  EXPECT_THAT(storage()->GetAggregatableContributionReportsForTesting(
-                  base::Time::Max()),
-              IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   CloseDatabase();
 
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc
index 2537a83..0839afa 100644
--- a/content/browser/attribution_reporting/attribution_storage_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -136,7 +136,7 @@
   EXPECT_NO_FATAL_FAILURE(storage->StoreSource(SourceBuilder().Build()));
   EXPECT_EQ(AttributionTrigger::Result::kNoMatchingImpressions,
             storage->MaybeCreateAndStoreReport(DefaultTrigger()).status());
-  EXPECT_THAT(storage->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage->GetAttributionReports(base::Time::Now()), IsEmpty());
   EXPECT_THAT(storage->GetActiveSources(), IsEmpty());
   EXPECT_TRUE(storage->DeleteReport(AttributionReport::EventLevelData::Id(0)));
   EXPECT_NO_FATAL_FAILURE(storage->ClearData(
@@ -172,7 +172,7 @@
        GetWithNoMatchingImpressions_NoImpressionsReturned) {
   EXPECT_EQ(AttributionTrigger::Result::kNoMatchingImpressions,
             MaybeCreateAndStoreReport(DefaultTrigger()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest, GetWithMatchingImpression_ImpressionReturned) {
@@ -216,7 +216,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(EventLevelDataIs(TriggerDataIs(456u))));
 }
 
@@ -272,7 +272,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 }
 
@@ -288,7 +288,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest,
@@ -303,7 +303,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest, ConversionReportDeleted_RemovedFromStorage) {
@@ -314,11 +314,11 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   EXPECT_THAT(reports, SizeIs(1));
   DeleteReports(reports);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest,
@@ -372,7 +372,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   // Delete the report.
-  DeleteReports(storage()->GetAttributionsToReport(base::Time::Now()));
+  DeleteReports(storage()->GetAttributionReports(base::Time::Now()));
 
   // Store a new impression that should mark the first inactive.
   SourceBuilder builder;
@@ -389,7 +389,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   // Verify it was the new impression that converted.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 }
 
@@ -405,7 +405,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   // Delete the report.
-  DeleteReports(storage()->GetAttributionsToReport(base::Time::Now()));
+  DeleteReports(storage()->GetAttributionReports(base::Time::Now()));
 
   // Store a new impression with a different reporting origin.
   storage()->StoreSource(SourceBuilder()
@@ -421,7 +421,7 @@
       GetExpectedReport(builder.BuildStored(), conversion);
 
   // Verify it was the first impression that converted.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 }
 
@@ -448,7 +448,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(third_expected_conversion));
 }
 
@@ -470,25 +470,24 @@
   // Advance to the first impression's report time and verify only its report is
   // available.
   task_environment_.FastForwardBy(kReportDelay - base::Milliseconds(1));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 
   task_environment_.FastForwardBy(base::Milliseconds(1));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
 }
 
-TEST_F(AttributionStorageTest,
-       GetAttributionsToReportMultipleTimes_SameResult) {
+TEST_F(AttributionStorageTest, GetAttributionReportsMultipleTimes_SameResult) {
   storage()->StoreSource(SourceBuilder().Build());
   EXPECT_EQ(AttributionTrigger::Result::kSuccess,
             MaybeCreateAndStoreReport(DefaultTrigger()));
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> first_call_reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   std::vector<AttributionReport> second_call_reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
 
-  // Expect that |GetAttributionsToReport()| did not delete any conversions.
+  // Expect that |GetAttributionReports()| did not delete any conversions.
   EXPECT_EQ(first_call_reports, second_call_reports);
 }
 
@@ -615,7 +614,7 @@
       now - base::Minutes(20), now + base::Minutes(20),
       GetMatcher(impression.common_info().impression_origin()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 }
 
 // The null filter should match all origins.
@@ -659,7 +658,7 @@
 
   auto null_filter = base::RepeatingCallback<bool(const url::Origin&)>();
   storage()->ClearData(base::Time::Now(), base::Time::Now(), null_filter);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), SizeIs(5));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), SizeIs(5));
 }
 
 TEST_F(AttributionStorageTest, ClearDataWithImpressionOutsideRange) {
@@ -674,7 +673,7 @@
   storage()->ClearData(
       base::Time::Now(), base::Time::Now(),
       GetMatcher(impression.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 }
 
 // Deletions with time range between the impression and conversion should not
@@ -702,7 +701,7 @@
       start + base::Minutes(1), start + base::Minutes(10),
       GetMatcher(impression.common_info().impression_origin()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
               ElementsAre(expected_report));
 }
 // Test that only a subset of impressions / conversions are deleted with
@@ -726,7 +725,7 @@
   // impressions should share the origin.
   storage()->ClearData(
       start, start, GetMatcher(impression1.common_info().impression_origin()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), SizeIs(1));
 }
 
 // The max time range with a null filter should delete everything.
@@ -748,7 +747,7 @@
   storage()->ClearData(base::Time::Min(), base::Time::Max(), null_filter);
 
   // Verify that everything is deleted.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 }
 
 // Same as the above test, but uses base::Time() instead of base::Time::Min()
@@ -771,7 +770,7 @@
   storage()->ClearData(base::Time(), base::Time::Max(), null_filter);
 
   // Verify that everything is deleted.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest, MaxAttributionReportsBetweenSites) {
@@ -798,7 +797,7 @@
   const AttributionReport expected_report =
       GetExpectedReport(SourceBuilder().BuildStored(), conversion);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
               ElementsAre(expected_report, expected_report));
 }
 
@@ -841,7 +840,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest, NeverAttributeImpression_Deactivates) {
@@ -863,7 +862,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(AllOf(ReportSourceIs(SourceEventIdIs(5u)),
                                 EventLevelDataIs(TriggerDataIs(7u)))));
 }
@@ -901,7 +900,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 }
 
@@ -924,7 +923,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
 TEST_F(AttributionStorageTest,
@@ -1057,7 +1056,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(ReportSourceIs(SourceEventIdIs(5u))));
 }
 
@@ -1080,7 +1079,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(ReportSourceIs(SourceEventIdIs(5u))));
 }
 
@@ -1129,7 +1128,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 
   EXPECT_THAT(storage()->GetActiveSources(), IsEmpty());
@@ -1139,7 +1138,7 @@
   EXPECT_EQ(AttributionTrigger::Result::kNoMatchingImpressions,
             MaybeCreateAndStoreReport(DefaultTrigger()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(expected_report));
 }
 
@@ -1207,7 +1206,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(AllOf(ReportSourceIs(SourceEventIdIs(5u)),
                                 EventLevelDataIs(TriggerDataIs(21u))),
                           AllOf(ReportSourceIs(SourceEventIdIs(7u)),
@@ -1233,7 +1232,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(EventLevelDataIs(TriggerDataIs(9u))));
 }
 
@@ -1265,7 +1264,7 @@
             MaybeCreateAndStoreReport(
                 TriggerBuilder().SetPriority(2).SetTriggerData(5).Build()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
               ElementsAre(EventLevelDataIs(TriggerDataIs(3u)),
                           EventLevelDataIs(TriggerDataIs(5u))));
 }
@@ -1367,7 +1366,7 @@
                     .Build()));
 
   task_environment_.FastForwardBy(kReportDelay);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(EventLevelDataIs(TriggerDataIs(71u)),
                           EventLevelDataIs(TriggerDataIs(72u)),
                           EventLevelDataIs(TriggerDataIs(73u))));
@@ -1399,7 +1398,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> actual_reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   EXPECT_THAT(actual_reports, ElementsAre(EventLevelDataIs(TriggerDataIs(3u))));
 
   // Simulate the report being sent and deleted from storage.
@@ -1419,10 +1418,10 @@
                     .Build()));
 
   task_environment_.FastForwardBy(kReportDelay);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), IsEmpty());
 }
 
-TEST_F(AttributionStorageTest, GetAttributionsToReport_SetsPriority) {
+TEST_F(AttributionStorageTest, GetAttributionReports_SetsPriority) {
   storage()->StoreSource(SourceBuilder().Build());
   EXPECT_EQ(
       AttributionTrigger::Result::kSuccess,
@@ -1430,7 +1429,7 @@
 
   task_environment_.FastForwardBy(kReportDelay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(EventLevelDataIs(TriggerPriorityIs(13))));
 }
 
@@ -1454,19 +1453,19 @@
   storage()->StoreSource(SourceBuilder().Build());
   EXPECT_EQ(AttributionTrigger::Result::kSuccess,
             MaybeCreateAndStoreReport(DefaultTrigger()));
-  auto reports = storage()->GetAttributionsToReport(base::Time::Max());
+  auto reports = storage()->GetAttributionReports(base::Time::Max());
   EXPECT_THAT(reports,
               ElementsAre(Property(&AttributionReport::ReportId, IsTrue())));
   const AttributionReport::Id id1 = *reports.front().ReportId();
 
   storage()->ClearData(base::Time::Min(), base::Time::Max(),
                        base::NullCallback());
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()), IsEmpty());
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty());
 
   storage()->StoreSource(SourceBuilder().Build());
   EXPECT_EQ(AttributionTrigger::Result::kSuccess,
             MaybeCreateAndStoreReport(DefaultTrigger()));
-  reports = storage()->GetAttributionsToReport(base::Time::Max());
+  reports = storage()->GetAttributionReports(base::Time::Max());
   EXPECT_THAT(reports,
               ElementsAre(Property(&AttributionReport::ReportId, IsTrue())));
   const AttributionReport::Id id2 = *reports.front().ReportId();
@@ -1482,7 +1481,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> actual_reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   EXPECT_THAT(actual_reports, ElementsAre(FailedSendAttemptsIs(0)));
 
   const base::TimeDelta delay = base::Days(2);
@@ -1494,7 +1493,7 @@
 
   task_environment_.FastForwardBy(delay);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(AllOf(FailedSendAttemptsIs(1),
                                 ReportTimeIs(new_report_time))));
 }
@@ -1513,7 +1512,7 @@
   EXPECT_EQ(
       AttributionTrigger::Result::kSuccess,
       MaybeCreateAndStoreReport(TriggerBuilder().SetDedupKey(13).Build()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(1));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(1));
 
   SourceBuilder builder2;
   builder2.SetSourceEventId(9);
@@ -1547,7 +1546,7 @@
             MaybeCreateAndStoreReport(DefaultTrigger()));
   EXPECT_EQ(AttributionTrigger::Result::kSuccess,
             MaybeCreateAndStoreReport(DefaultTrigger()));
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()), SizeIs(2));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()), SizeIs(2));
 
   // 2 sources are deactivated, but only 1 should be returned.
   SourceBuilder builder3;
@@ -1578,7 +1577,7 @@
   }
 
   task_environment_.FastForwardBy(kReportDelay);
-  auto reports = storage()->GetAttributionsToReport(base::Time::Now());
+  auto reports = storage()->GetAttributionReports(base::Time::Now());
   EXPECT_THAT(reports, SizeIs(3));
 
   // Simulate the reports being sent and removed from storage.
@@ -1604,7 +1603,7 @@
   task_environment_.FastForwardBy(kReportDelay);
 
   std::vector<AttributionReport> actual_reports =
-      storage()->GetAttributionsToReport(base::Time::Now());
+      storage()->GetAttributionReports(base::Time::Now());
   EXPECT_EQ(1u, actual_reports.size());
   EXPECT_EQ(DefaultExternalReportID(), actual_reports[0].external_report_id());
 }
@@ -1623,8 +1622,20 @@
 
   const base::Time original_report_time = base::Time::Now() + kReportDelay;
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
-              ElementsAre(ReportTimeIs(original_report_time)));
+  AggregatableAttribution aggregatable_attribution(
+      AttributionInfo(
+          SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+          /*time=*/base::Time::Now(),
+          /*debug_key=*/absl::nullopt),
+      /*report_time=*/original_report_time,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution));
+
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              ElementsAre(ReportTimeIs(original_report_time),
+                          ReportTimeIs(original_report_time)));
 
   task_environment_.FastForwardBy(kReportDelay);
 
@@ -1632,8 +1643,9 @@
 
   // The report time should not be changed as it is equal to now, not strictly
   // less than it.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
-              ElementsAre(ReportTimeIs(original_report_time)));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              ElementsAre(ReportTimeIs(original_report_time),
+                          ReportTimeIs(original_report_time)));
 
   task_environment_.FastForwardBy(base::Milliseconds(1));
 
@@ -1642,8 +1654,9 @@
   EXPECT_EQ(storage()->AdjustOfflineReportTimes(), new_report_time);
 
   // The report time should be changed as it is strictly less than now.
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
-              ElementsAre(ReportTimeIs(new_report_time)));
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              ElementsAre(ReportTimeIs(new_report_time),
+                          ReportTimeIs(new_report_time)));
 }
 
 TEST_F(AttributionStorageTest, AdjustOfflineReportTimes_Range) {
@@ -1657,20 +1670,33 @@
 
   const base::Time original_report_time = base::Time::Now() + kReportDelay;
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
-              ElementsAre(ReportTimeIs(original_report_time)));
+  AggregatableAttribution aggregatable_attribution(
+      AttributionInfo(
+          SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+          /*time=*/base::Time::Now(), /*debug_key=*/absl::nullopt),
+      /*report_time=*/original_report_time,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution));
+
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              ElementsAre(ReportTimeIs(original_report_time),
+                          ReportTimeIs(original_report_time)));
 
   task_environment_.FastForwardBy(kReportDelay + base::Milliseconds(1));
 
   storage()->AdjustOfflineReportTimes();
 
   EXPECT_THAT(
-      storage()->GetAttributionsToReport(base::Time::Max()),
+      storage()->GetAttributionReports(base::Time::Max()),
       ElementsAre(ReportTimeIs(AllOf(Ge(base::Time::Now() + base::Hours(1)),
+                                     Le(base::Time::Now() + base::Hours(3)))),
+                  ReportTimeIs(AllOf(Ge(base::Time::Now() + base::Hours(1)),
                                      Le(base::Time::Now() + base::Hours(3))))));
 }
 
-TEST_F(AttributionStorageTest, GetNextReportTime) {
+TEST_F(AttributionStorageTest, GetNextEventReportTime) {
   const auto origin_a = url::Origin::Create(GURL("https://a.example/"));
   const auto origin_b = url::Origin::Create(GURL("https://b.example/"));
 
@@ -1699,7 +1725,7 @@
   EXPECT_EQ(storage()->GetNextReportTime(report_time_b), absl::nullopt);
 }
 
-TEST_F(AttributionStorageTest, GetAttributionsToReport_Shuffles) {
+TEST_F(AttributionStorageTest, GetAttributionReports_Shuffles) {
   storage()->StoreSource(SourceBuilder().Build());
   EXPECT_EQ(
       AttributionTrigger::Result::kSuccess,
@@ -1711,7 +1737,7 @@
       AttributionTrigger::Result::kSuccess,
       MaybeCreateAndStoreReport(TriggerBuilder().SetTriggerData(2).Build()));
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(
+  EXPECT_THAT(storage()->GetAttributionReports(
                   /*max_report_time=*/base::Time::Max(), /*limit=*/-1),
               ElementsAre(EventLevelDataIs(TriggerDataIs(3)),
                           EventLevelDataIs(TriggerDataIs(1)),
@@ -1719,7 +1745,7 @@
 
   delegate()->set_reverse_reports_on_shuffle(true);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(
+  EXPECT_THAT(storage()->GetAttributionReports(
                   /*max_report_time=*/base::Time::Max(), /*limit=*/-1),
               ElementsAre(EventLevelDataIs(TriggerDataIs(2)),
                           EventLevelDataIs(TriggerDataIs(1)),
@@ -1740,7 +1766,7 @@
       MaybeCreateAndStoreReport(TriggerBuilder().SetDebugKey(33).Build()));
 
   task_environment_.FastForwardBy(kReportDelay);
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Now()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Now()),
               ElementsAre(AllOf(ReportSourceIs(SourceDebugKeyIs(22)),
                                 TriggerDebugKeyIs(33))));
 }
@@ -1815,7 +1841,7 @@
           TriggerBuilder().SetReportingOrigin(origin3).SetDebugKey(3).Build()),
       AttributionTrigger::Result::kExcessiveReportingOrigins);
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
               ElementsAre(TriggerDebugKeyIs(1), TriggerDebugKeyIs(2)));
 }
 
@@ -1842,8 +1868,7 @@
   auto stored_source = SourceBuilder().BuildStored();
 
   EXPECT_THAT(
-      storage()->GetAggregatableContributionReportsForTesting(
-          base::Time::Max()),
+      storage()->GetAttributionReports(base::Time::Max()),
       ElementsAre(
           AttributionReport(
               attribution_info, aggregatable_attribution.report_time,
@@ -1920,7 +1945,7 @@
 }
 
 TEST_F(AttributionStorageTest,
-       GetAttributionsToReport_SetsRandomizedTriggerRate) {
+       GetAttributionReports_SetsRandomizedTriggerRate) {
   delegate()->set_randomized_response_rates({
       .navigation = .2,
       .event = .4,
@@ -1945,7 +1970,7 @@
   MaybeCreateAndStoreReport(
       TriggerBuilder().SetReportingOrigin(origin2).Build());
 
-  EXPECT_THAT(storage()->GetAttributionsToReport(base::Time::Max()),
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
               UnorderedElementsAre(
                   AllOf(ReportSourceIs(SourceTypeIs(
                             CommonSourceInfo::SourceType::kNavigation)),
@@ -1955,4 +1980,140 @@
                         EventLevelDataIs(RandomizedTriggerRateIs(.4)))));
 }
 
+TEST_F(AttributionStorageTest,
+       UpdateAggregatableContributionReportForSendFailure) {
+  base::Time now = base::Time::Now();
+
+  SourceBuilder builder(now);
+  storage()->StoreSource(builder.Build());
+
+  AggregatableAttribution aggregatable_attribution(
+      AttributionInfo(builder.SetSourceId(StoredSource::Id(1)).BuildStored(),
+                      /*time=*/now,
+                      /*debug_key=*/absl::nullopt),
+      /*report_time=*/now + base::Hours(2),
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)});
+
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution));
+
+  base::Time new_report_time = now + base::Hours(5);
+  EXPECT_TRUE(storage()->UpdateReportForSendFailure(
+      AttributionReport::AggregatableContributionData::Id(1), new_report_time));
+
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              ElementsAre(AllOf(
+                  Property(&AttributionReport::report_time, new_report_time),
+                  Property(&AttributionReport::failed_send_attempts, 1))));
+}
+
+TEST_F(AttributionStorageTest, GetNextAggregatableContributionReportTime) {
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), absl::nullopt);
+
+  storage()->StoreSource(SourceBuilder().Build());
+
+  base::Time now = base::Time::Now();
+
+  AttributionInfo attribution_info(
+      SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+      /*time=*/now, /*debug_key=*/absl::nullopt);
+
+  const base::Time report_time_a = now + base::Minutes(5);
+  AggregatableAttribution aggregatable_attribution_a(
+      attribution_info, /*report_time=*/report_time_a,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution_a));
+
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), report_time_a);
+  EXPECT_EQ(storage()->GetNextReportTime(report_time_a), absl::nullopt);
+
+  const base::Time report_time_b = base::Time::Now() + base::Minutes(10);
+  AggregatableAttribution aggregatable_attribution_b(
+      attribution_info, /*report_time=*/report_time_b,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/3, /*value=*/4)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution_b));
+
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), report_time_a);
+  EXPECT_EQ(storage()->GetNextReportTime(report_time_a), report_time_b);
+  EXPECT_EQ(storage()->GetNextReportTime(report_time_b), absl::nullopt);
+}
+
+// Will return minimum of next event report and next aggregatable report time if
+// both present.
+TEST_F(AttributionStorageTest, GetNextReportTime) {
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), absl::nullopt);
+
+  storage()->StoreSource(SourceBuilder().Build());
+
+  EXPECT_EQ(AttributionTrigger::Result::kSuccess,
+            MaybeCreateAndStoreReport(DefaultTrigger()));
+
+  base::Time now = base::Time::Now();
+
+  AttributionInfo attribution_info(
+      SourceBuilder().SetSourceId(StoredSource::Id(1)).BuildStored(),
+      /*time=*/now, /*debug_key=*/absl::nullopt);
+
+  const base::Time report_time_a = now + kReportDelay;
+
+  const base::Time report_time_b = report_time_a + base::Milliseconds(1);
+  AggregatableAttribution aggregatable_attribution_a(
+      attribution_info, /*report_time=*/report_time_b,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/1, /*value=*/2)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution_a));
+
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), report_time_a);
+
+  const base::Time report_time_c = report_time_a - base::Milliseconds(1);
+  AggregatableAttribution aggregatable_attribution_b(
+      attribution_info, /*report_time=*/report_time_c,
+      /*contributions=*/
+      {AggregatableHistogramContribution(/*key=*/3, /*value=*/4)});
+  EXPECT_TRUE(storage()->AddAggregatableAttributionForTesting(
+      aggregatable_attribution_b));
+
+  EXPECT_EQ(storage()->GetNextReportTime(base::Time::Min()), report_time_c);
+}
+
+TEST_F(AttributionStorageTest, TriggerDataSanitized) {
+  delegate()->set_trigger_data_cardinality(/*navigation=*/4, /*event=*/3);
+
+  const auto origin1 = url::Origin::Create(GURL("https://r1.test"));
+  const auto origin2 = url::Origin::Create(GURL("https://r2.test"));
+
+  storage()->StoreSource(
+      SourceBuilder()
+          .SetReportingOrigin(origin1)
+          .SetSourceType(CommonSourceInfo::SourceType::kNavigation)
+          .Build());
+  MaybeCreateAndStoreReport(
+      TriggerBuilder().SetReportingOrigin(origin1).SetTriggerData(6).Build());
+
+  storage()->StoreSource(
+      SourceBuilder()
+          .SetReportingOrigin(origin2)
+          .SetSourceType(CommonSourceInfo::SourceType::kEvent)
+          .Build());
+  MaybeCreateAndStoreReport(TriggerBuilder()
+                                .SetReportingOrigin(origin2)
+                                .SetEventSourceTriggerData(4)
+                                .Build());
+
+  EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()),
+              UnorderedElementsAre(
+                  AllOf(ReportSourceIs(SourceTypeIs(
+                            CommonSourceInfo::SourceType::kNavigation)),
+                        EventLevelDataIs(TriggerDataIs(2))),
+                  AllOf(ReportSourceIs(
+                            SourceTypeIs(CommonSourceInfo::SourceType::kEvent)),
+                        EventLevelDataIs(TriggerDataIs(1)))));
+}
+
 }  // namespace content
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc
index 24f7ccb..e9c1a86 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.cc
+++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -160,6 +160,33 @@
   return aggregatable_budget_per_source_;
 }
 
+uint64_t ConfigurableStorageDelegate::SanitizeTriggerData(
+    uint64_t trigger_data,
+    CommonSourceInfo::SourceType source_type) const {
+  switch (source_type) {
+    case CommonSourceInfo::SourceType::kNavigation:
+      if (!navigation_trigger_data_cardinality_)
+        return trigger_data;
+
+      return trigger_data % *navigation_trigger_data_cardinality_;
+    case CommonSourceInfo::SourceType::kEvent:
+      if (!event_trigger_data_cardinality_)
+        return trigger_data;
+
+      return trigger_data % *event_trigger_data_cardinality_;
+  }
+}
+
+void ConfigurableStorageDelegate::set_trigger_data_cardinality(
+    uint64_t navigation,
+    uint64_t event) {
+  DCHECK_GT(navigation, 0u);
+  DCHECK_GT(event, 0u);
+
+  navigation_trigger_data_cardinality_ = navigation;
+  event_trigger_data_cardinality_ = event;
+}
+
 AttributionManager* TestManagerProvider::GetManager(
     WebContents* web_contents) const {
   return manager_;
@@ -528,6 +555,8 @@
 
 // Does not compare ID as it is set by the underlying sqlite db and
 // should not be tested.
+// Also does not compare the assembled report as it is returned by the
+// aggregation service from all the other data.
 bool operator==(const AttributionReport::AggregatableContributionData& a,
                 const AttributionReport::AggregatableContributionData& b) {
   return a.contribution == b.contribution;
@@ -838,13 +867,13 @@
   return map;
 }
 
-std::vector<AttributionReport> GetAttributionsToReportForTesting(
+std::vector<AttributionReport> GetAttributionReportsForTesting(
     AttributionManagerImpl* manager,
     base::Time max_report_time) {
   base::RunLoop run_loop;
   std::vector<AttributionReport> attribution_reports;
   manager->attribution_storage_
-      .AsyncCall(&AttributionStorage::GetAttributionsToReport)
+      .AsyncCall(&AttributionStorage::GetAttributionReports)
       .WithArgs(max_report_time, /*limit=*/-1)
       .Then(base::BindOnce(base::BindLambdaForTesting(
           [&](std::vector<AttributionReport> reports) {
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h
index 9938458..2acee26 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.h
+++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -159,6 +159,9 @@
   RandomizedResponse GetRandomizedResponse(
       const CommonSourceInfo& source) override;
   int64_t GetAggregatableBudgetPerSource() const override;
+  uint64_t SanitizeTriggerData(
+      uint64_t trigger_data,
+      CommonSourceInfo::SourceType source_type) const override;
 
   void set_max_attributions_per_source(int max) {
     max_attributions_per_source_ = max;
@@ -213,6 +216,8 @@
     randomized_response_ = std::move(randomized_response);
   }
 
+  void set_trigger_data_cardinality(uint64_t navigation, uint64_t event);
+
  private:
   int max_attributions_per_source_ = INT_MAX;
   int max_sources_per_origin_ = INT_MAX;
@@ -236,11 +241,14 @@
   absl::optional<OfflineReportDelayConfig> offline_report_delay_config_;
 
   // If true, `ShuffleReports()` reverses the reports to allow testing the
-  // proper call from `AttributionStorage::GetAttributionsToReport()`.
+  // proper call from `AttributionStorage::GetAttributionReports()`.
   bool reverse_reports_on_shuffle_ = false;
 
   AttributionRandomizedResponseRates randomized_response_rates_;
   RandomizedResponse randomized_response_ = absl::nullopt;
+
+  absl::optional<uint64_t> navigation_trigger_data_cardinality_;
+  absl::optional<uint64_t> event_trigger_data_cardinality_;
 };
 
 // Test manager provider which can be used to inject a fake AttributionManager.
@@ -547,7 +555,7 @@
 
 std::ostream& operator<<(std::ostream& out, StorableSource::Result status);
 
-std::vector<AttributionReport> GetAttributionsToReportForTesting(
+std::vector<AttributionReport> GetAttributionReportsForTesting(
     AttributionManagerImpl* manager,
     base::Time max_report_time);
 
diff --git a/content/browser/attribution_reporting/attribution_trigger.h b/content/browser/attribution_reporting/attribution_trigger.h
index a32c115..1535c4a1e 100644
--- a/content/browser/attribution_reporting/attribution_trigger.h
+++ b/content/browser/attribution_reporting/attribution_trigger.h
@@ -39,9 +39,10 @@
   };
 
   // Should only be created with values that the browser process has already
-  // validated. At creation time, |trigger_data_| should already be stripped
-  // to a lower entropy. |conversion_destination| should be filled by a
-  // navigation origin known by the browser process.
+  // validated. |trigger_data| and |event_source_trigger_data| will be sanitized
+  // to a lower entropy by the `AttributionStorageDelegate` before storage.
+  // |conversion_destination| should be filled by a navigation origin known by
+  // the browser process.
   AttributionTrigger(uint64_t trigger_data,
                      net::SchemefulSite conversion_destination,
                      url::Origin reporting_origin,
diff --git a/content/browser/attribution_reporting/attribution_utils.cc b/content/browser/attribution_reporting/attribution_utils.cc
index 2cd5af2..f9726a32 100644
--- a/content/browser/attribution_reporting/attribution_utils.cc
+++ b/content/browser/attribution_reporting/attribution_utils.cc
@@ -110,15 +110,6 @@
   return ReportTimeFromDeadline(source.impression_time(), deadline);
 }
 
-uint64_t TriggerDataCardinality(CommonSourceInfo::SourceType source_type) {
-  switch (source_type) {
-    case CommonSourceInfo::SourceType::kNavigation:
-      return 8;
-    case CommonSourceInfo::SourceType::kEvent:
-      return 2;
-  }
-}
-
 std::string SerializeAttributionJson(const base::Value& body,
                                      bool pretty_print) {
   int options = pretty_print ? base::JSONWriter::OPTIONS_PRETTY_PRINT : 0;
diff --git a/content/browser/attribution_reporting/attribution_utils.h b/content/browser/attribution_reporting/attribution_utils.h
index de45fe1..538166c 100644
--- a/content/browser/attribution_reporting/attribution_utils.h
+++ b/content/browser/attribution_reporting/attribution_utils.h
@@ -5,8 +5,6 @@
 #ifndef CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_UTILS_H_
 #define CONTENT_BROWSER_ATTRIBUTION_REPORTING_ATTRIBUTION_UTILS_H_
 
-#include <stdint.h>
-
 #include <string>
 
 #include "content/browser/attribution_reporting/common_source_info.h"
@@ -29,8 +27,6 @@
 // Calculates the report time for a given source and window index.
 base::Time ReportTimeAtWindow(const CommonSourceInfo& source, int window_index);
 
-uint64_t TriggerDataCardinality(CommonSourceInfo::SourceType source_type);
-
 std::string SerializeAttributionJson(const base::Value& body,
                                      bool pretty_print = false);
 
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 38e4b8f..a84a74fe 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -1017,39 +1017,33 @@
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::
               EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX)) {
-    exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeSameSiteUnspecifiedTreatedAsLax);
+    exclusion_reasons->push_back(protocol::Audits::CookieExclusionReasonEnum::
+                                     ExcludeSameSiteUnspecifiedTreatedAsLax);
   }
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE)) {
-    exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeSameSiteNoneInsecure);
+    exclusion_reasons->push_back(protocol::Audits::CookieExclusionReasonEnum::
+                                     ExcludeSameSiteNoneInsecure);
   }
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)) {
     exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeSameSiteLax);
+        protocol::Audits::CookieExclusionReasonEnum::ExcludeSameSiteLax);
   }
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)) {
     exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeSameSiteStrict);
+        protocol::Audits::CookieExclusionReasonEnum::ExcludeSameSiteStrict);
   }
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY)) {
     exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeInvalidSameParty);
+        protocol::Audits::CookieExclusionReasonEnum::ExcludeInvalidSameParty);
   }
   if (status.HasExclusionReason(
           net::CookieInclusionStatus::EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT)) {
-    exclusion_reasons->push_back(
-        protocol::Audits::SameSiteCookieExclusionReasonEnum::
-            ExcludeSamePartyCrossPartyContext);
+    exclusion_reasons->push_back(protocol::Audits::CookieExclusionReasonEnum::
+                                     ExcludeSamePartyCrossPartyContext);
   }
 
   return exclusion_reasons;
@@ -1061,76 +1055,67 @@
   if (status.HasWarningReason(
           net::CookieInclusionStatus::
               WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteUnspecifiedCrossSiteContext);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteUnspecifiedCrossSiteContext);
   }
   if (status.HasWarningReason(
           net::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE)) {
     warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteNoneInsecure);
+        protocol::Audits::CookieWarningReasonEnum::WarnSameSiteNoneInsecure);
   }
   if (status.HasWarningReason(net::CookieInclusionStatus::
                                   WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteUnspecifiedLaxAllowUnsafe);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteUnspecifiedLaxAllowUnsafe);
   }
 
   // There can only be one of the following warnings.
   if (status.HasWarningReason(net::CookieInclusionStatus::
                                   WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteStrictLaxDowngradeStrict);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteStrictLaxDowngradeStrict);
   } else if (status.HasWarningReason(
                  net::CookieInclusionStatus::
                      WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteStrictCrossDowngradeStrict);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteStrictCrossDowngradeStrict);
   } else if (status.HasWarningReason(
                  net::CookieInclusionStatus::
                      WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteStrictCrossDowngradeLax);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteStrictCrossDowngradeLax);
   } else if (status.HasWarningReason(
                  net::CookieInclusionStatus::
                      WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteLaxCrossDowngradeStrict);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteLaxCrossDowngradeStrict);
   } else if (status.HasWarningReason(
                  net::CookieInclusionStatus::
                      WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE)) {
-    warning_reasons->push_back(
-        protocol::Audits::SameSiteCookieWarningReasonEnum::
-            WarnSameSiteLaxCrossDowngradeLax);
+    warning_reasons->push_back(protocol::Audits::CookieWarningReasonEnum::
+                                   WarnSameSiteLaxCrossDowngradeLax);
   }
 
   return warning_reasons;
 }
 
-protocol::String BuildCookieOperation(
-    blink::mojom::SameSiteCookieOperation operation) {
+protocol::String BuildCookieOperation(blink::mojom::CookieOperation operation) {
   switch (operation) {
-    case blink::mojom::SameSiteCookieOperation::kReadCookie:
-      return protocol::Audits::SameSiteCookieOperationEnum::ReadCookie;
-    case blink::mojom::SameSiteCookieOperation::kSetCookie:
-      return protocol::Audits::SameSiteCookieOperationEnum::SetCookie;
+    case blink::mojom::CookieOperation::kReadCookie:
+      return protocol::Audits::CookieOperationEnum::ReadCookie;
+    case blink::mojom::CookieOperation::kSetCookie:
+      return protocol::Audits::CookieOperationEnum::SetCookie;
   }
 }
 
 }  // namespace
 
-void ReportSameSiteCookieIssue(
+void ReportCookieIssue(
     RenderFrameHostImpl* render_frame_host_impl,
     const network::mojom::CookieOrLineWithAccessResultPtr& excluded_cookie,
     const GURL& url,
     const net::SiteForCookies& site_for_cookies,
-    blink::mojom::SameSiteCookieOperation operation,
+    blink::mojom::CookieOperation operation,
     const absl::optional<std::string>& devtools_request_id) {
   auto exclusion_reasons =
       BuildExclusionReasons(excluded_cookie->access_result.status);
@@ -1151,8 +1136,8 @@
                            .Build();
   }
 
-  auto same_site_details =
-      protocol::Audits::SameSiteCookieIssueDetails::Create()
+  auto cookie_issue_details =
+      protocol::Audits::CookieIssueDetails::Create()
           .SetCookieExclusionReasons(std::move(exclusion_reasons))
           .SetCookieWarningReasons(std::move(warning_reasons))
           .SetOperation(BuildCookieOperation(operation))
@@ -1167,27 +1152,25 @@
                                .SetPath(cookie.Path())
                                .SetDomain(cookie.Domain())
                                .Build();
-    same_site_details->SetCookie(std::move(affected_cookie));
+    cookie_issue_details->SetCookie(std::move(affected_cookie));
   } else {
     CHECK(excluded_cookie->cookie_or_line->is_cookie_string());
-    same_site_details->SetRawCookieLine(
+    cookie_issue_details->SetRawCookieLine(
         excluded_cookie->cookie_or_line->get_cookie_string());
   }
 
   if (!site_for_cookies.IsNull()) {
-    same_site_details->SetSiteForCookies(
+    cookie_issue_details->SetSiteForCookies(
         site_for_cookies.RepresentativeUrl().spec());
   }
 
-  auto details =
-      protocol::Audits::InspectorIssueDetails::Create()
-          .SetSameSiteCookieIssueDetails(std::move(same_site_details))
-          .Build();
+  auto details = protocol::Audits::InspectorIssueDetails::Create()
+                     .SetCookieIssueDetails(std::move(cookie_issue_details))
+                     .Build();
 
   auto issue =
       protocol::Audits::InspectorIssue::Create()
-          .SetCode(
-              protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue)
+          .SetCode(protocol::Audits::InspectorIssueCodeEnum::CookieIssue)
           .SetDetails(std::move(details))
           .Build();
 
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h
index 29416ce..bc709e1 100644
--- a/content/browser/devtools/devtools_instrumentation.h
+++ b/content/browser/devtools/devtools_instrumentation.h
@@ -240,12 +240,12 @@
     base::SafeRef<RenderFrameHostImpl> owner_render_frame_host,
     FencedFrame* fenced_frame);
 
-void ReportSameSiteCookieIssue(
+void ReportCookieIssue(
     RenderFrameHostImpl* render_frame_host_impl,
     const network::mojom::CookieOrLineWithAccessResultPtr& excluded_cookie,
     const GURL& url,
     const net::SiteForCookies& site_for_cookies,
-    blink::mojom::SameSiteCookieOperation operation,
+    blink::mojom::CookieOperation operation,
     const absl::optional<std::string>& devtools_request_id);
 
 enum class AttributionReportingIssueType {
diff --git a/content/browser/devtools/devtools_issue_storage_browsertest.cc b/content/browser/devtools/devtools_issue_storage_browsertest.cc
index 6079ebf..655ad20 100644
--- a/content/browser/devtools/devtools_issue_storage_browsertest.cc
+++ b/content/browser/devtools/devtools_issue_storage_browsertest.cc
@@ -49,7 +49,7 @@
     std::unique_ptr<base::DictionaryValue> notification =
         WaitForNotification("Audits.issueAdded", true);
     EXPECT_EQ(*(notification->FindDictPath("issue")->FindStringPath("code")),
-              protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue);
+              protocol::Audits::InspectorIssueCodeEnum::CookieIssue);
   }
 };
 
@@ -59,8 +59,7 @@
   auto issueDetails = protocol::Audits::InspectorIssueDetails::Create();
   auto inspector_issue =
       protocol::Audits::InspectorIssue::Create()
-          .SetCode(
-              protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue)
+          .SetCode(protocol::Audits::InspectorIssueCodeEnum::CookieIssue)
           .SetDetails(issueDetails.Build())
           .Build();
   devtools_instrumentation::ReportBrowserInitiatedIssue(rfh,
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 1232949..aa1fba3 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -1413,9 +1413,6 @@
           CacheControlNoStoreHTTPOnlyCookieModified;
     case Reason::kNoResponseHead:
       return Page::BackForwardCacheNotRestoredReasonEnum::NoResponseHead;
-    case Reason::kActivationNavigationsDisallowedForBug1234857:
-      return Page::BackForwardCacheNotRestoredReasonEnum::
-          ActivationNavigationsDisallowedForBug1234857;
     case Reason::kBlocklistedFeatures:
       // Blocklisted features should be handled separately and be broken down
       // into sub reasons.
@@ -1701,7 +1698,6 @@
       return Page::BackForwardCacheNotRestoredReasonTypeEnum::PageSupportNeeded;
     case Reason::kNetworkRequestDatapipeDrainedAsBytesConsumer:
     case Reason::kUnknown:
-    case Reason::kActivationNavigationsDisallowedForBug1234857:
       return Page::BackForwardCacheNotRestoredReasonTypeEnum::SupportPending;
     case Reason::kBlocklistedFeatures:
       NOTREACHED();
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
index 04b8e5bf..7300b88 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -63,17 +63,17 @@
 void IndexedDBInternalsHandler::RegisterMessages() {
   // TODO(https://crbug.com/1199077): Fix this name as part of storage key
   // migration.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "getAllOrigins",
       base::BindRepeating(&IndexedDBInternalsHandler::GetAllStorageKeys,
                           base::Unretained(this)));
   // TODO(https://crbug.com/1199077): Fix this name as part of storage key
   // migration.
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "downloadOriginData",
       base::BindRepeating(&IndexedDBInternalsHandler::DownloadStorageKeyData,
                           base::Unretained(this)));
-  web_ui()->RegisterMessageCallback(
+  web_ui()->RegisterDeprecatedMessageCallback2(
       "forceClose",
       base::BindRepeating(&IndexedDBInternalsHandler::ForceCloseStorageKey,
                           base::Unretained(this)));
diff --git a/content/browser/loader/navigation_early_hints_browsertest.cc b/content/browser/loader/navigation_early_hints_browsertest.cc
index c68d177..6808748 100644
--- a/content/browser/loader/navigation_early_hints_browsertest.cc
+++ b/content/browser/loader/navigation_early_hints_browsertest.cc
@@ -19,6 +19,9 @@
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
 #include "content/public/test/content_mock_cert_verifier.h"
+#include "content/public/test/fenced_frame_test_util.h"
+#include "content/public/test/prerender_test_util.h"
+#include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/url_loader_interceptor.h"
 #include "content/shell/browser/shell.h"
 #include "content/test/content_browser_test_utils_internal.h"
@@ -141,7 +144,12 @@
 // Early Hints are only plumbed over HTTP/2 or HTTP/3 (QUIC).
 class NavigationEarlyHintsTest : public ContentBrowserTest {
  public:
-  NavigationEarlyHintsTest() = default;
+  NavigationEarlyHintsTest() {
+    feature_list_.InitWithFeatures(
+        {features::kEarlyHintsPreloadForNavigation,
+         net::features::kSplitCacheByNetworkIsolationKey},
+        {});
+  }
   ~NavigationEarlyHintsTest() override = default;
 
   void SetUpOnMainThread() override {
@@ -160,10 +168,6 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     command_line->AppendSwitchASCII(switches::kOriginToForceQuicOn, "*");
     mock_cert_verifier_.SetUpCommandLine(command_line);
-    feature_list_.InitWithFeatures(
-        {features::kEarlyHintsPreloadForNavigation,
-         net::features::kSplitCacheByNetworkIsolationKey},
-        {});
 
     ASSERT_TRUE(net::QuicSimpleTestServer::Start());
 
@@ -300,19 +304,22 @@
     return title16 == title_watcher.WaitAndGetTitle();
   }
 
-  NavigationEarlyHintsManager* GetEarlyHintsManager() {
-    RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
-        shell()->web_contents()->GetMainFrame());
+  NavigationEarlyHintsManager* GetEarlyHintsManager(RenderFrameHostImpl* rfh) {
     return rfh->early_hints_manager();
   }
 
   PreloadedResources WaitForPreloadedResources() {
+    return WaitForPreloadedResources(static_cast<RenderFrameHostImpl*>(
+        shell()->web_contents()->GetMainFrame()));
+  }
+
+  PreloadedResources WaitForPreloadedResources(RenderFrameHostImpl* rfh) {
     base::RunLoop loop;
     PreloadedResources result;
-    if (!GetEarlyHintsManager())
+    if (!GetEarlyHintsManager(rfh))
       return result;
 
-    GetEarlyHintsManager()->WaitForPreloadsFinishedForTesting(
+    GetEarlyHintsManager(rfh)->WaitForPreloadsFinishedForTesting(
         base::BindLambdaForTesting([&](PreloadedResources preloaded_resources) {
           result = preloaded_resources;
           loop.Quit();
@@ -698,7 +705,9 @@
   ASSERT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
   EXPECT_EQ(preconnect_listener().num_accepted_sockets(), 1UL);
-  EXPECT_TRUE(GetEarlyHintsManager()->WasResourceHintsReceived());
+  EXPECT_TRUE(GetEarlyHintsManager(static_cast<RenderFrameHostImpl*>(
+                                       shell()->web_contents()->GetMainFrame()))
+                  ->WasResourceHintsReceived());
 }
 
 class NavigationEarlyHintsAddressSpaceTest : public NavigationEarlyHintsTest {
@@ -1016,4 +1025,135 @@
   }
 }
 
+class NavigationEarlyHintsPrerenderTest : public NavigationEarlyHintsTest {
+ public:
+  NavigationEarlyHintsPrerenderTest()
+      : prerender_helper_(base::BindRepeating(
+            &NavigationEarlyHintsPrerenderTest::web_contents,
+            base::Unretained(this))) {}
+  ~NavigationEarlyHintsPrerenderTest() override = default;
+
+  test::PrerenderTestHelper* prerender_helper() { return &prerender_helper_; }
+
+  WebContents* web_contents() { return shell()->web_contents(); }
+
+ private:
+  test::PrerenderTestHelper prerender_helper_;
+};
+
+IN_PROC_BROWSER_TEST_F(NavigationEarlyHintsPrerenderTest,
+                       AllowPreloadInPrerendering) {
+  EXPECT_TRUE(NavigateToURL(
+      shell(), net::QuicSimpleTestServer::GetFileURL("/title1.html")));
+  ResponseEntry entry = CreatePageEntryWithHintedScript(net::HTTP_OK);
+  RegisterResponse(entry);
+
+  // Loads a page in the prerender.
+  int host_id = prerender_helper()->AddPrerender(
+      net::QuicSimpleTestServer::GetFileURL(kPageWithHintedScriptPath));
+  RenderFrameHostImpl* prerender_rfh = static_cast<RenderFrameHostImpl*>(
+      prerender_helper()->GetPrerenderedMainFrameHost(host_id));
+  EXPECT_NE(prerender_rfh, nullptr);
+  EXPECT_NE(prerender_rfh->early_hints_manager(), nullptr);
+
+  PreloadedResources preloads = WaitForPreloadedResources(prerender_rfh);
+  EXPECT_EQ(preloads.size(), 1UL);
+
+  GURL script_url = net::QuicSimpleTestServer::GetFileURL(kHintedScriptPath);
+  EXPECT_TRUE(preloads.contains(script_url));
+}
+
+class NavigationEarlyHintsFencedFrameTest : public NavigationEarlyHintsTest {
+ public:
+  NavigationEarlyHintsFencedFrameTest() = default;
+
+  test::FencedFrameTestHelper& fenced_frame_test_helper() {
+    return fenced_frame_test_helper_;
+  }
+
+  ResponseEntry CreatePageEntryWithHintedScriptInFencedFrame(
+      net::HttpStatusCode status_code) {
+    RegisterHintedScriptResource();
+
+    ResponseEntry entry(kPageWithHintedScriptPath, status_code);
+    entry.headers["supports-loading-mode"] = "fenced-frame";
+    entry.body = kPageWithHintedScriptBody;
+    HeaderField link_header = CreatePreloadLinkForScript();
+    HeaderField fenced_frame_header =
+        HeaderField("supports-loading-mode", "fenced-frame");
+    entry.AddEarlyHints(
+        {std::move(link_header), std::move(fenced_frame_header)});
+    return entry;
+  }
+
+ private:
+  test::FencedFrameTestHelper fenced_frame_test_helper_;
+};
+
+IN_PROC_BROWSER_TEST_F(NavigationEarlyHintsFencedFrameTest,
+                       DisallowPreloadInFencedFrame) {
+  EXPECT_TRUE(NavigateToURL(
+      shell(), net::QuicSimpleTestServer::GetFileURL("/title1.html")));
+
+  ResponseEntry entry =
+      CreatePageEntryWithHintedScriptInFencedFrame(net::HTTP_OK);
+  RegisterResponse(entry);
+
+  // Create a fenced frame.
+  RenderFrameHostImpl* fenced_frame_host = static_cast<RenderFrameHostImpl*>(
+      fenced_frame_test_helper().CreateFencedFrame(
+          shell()->web_contents()->GetMainFrame(),
+          net::QuicSimpleTestServer::GetFileURL(kPageWithHintedScriptPath)));
+  EXPECT_NE(fenced_frame_host, nullptr);
+  EXPECT_EQ(fenced_frame_host->early_hints_manager(), nullptr);
+}
+
+class NavigationEarlyHintsPortalTest : public NavigationEarlyHintsTest {
+ public:
+  NavigationEarlyHintsPortalTest() {
+    scoped_feature_list_.InitWithFeatures(
+        /*enabled_features=*/{blink::features::kPortals,
+                              blink::features::kPortalsCrossOrigin},
+        /*disabled_features=*/{});
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(NavigationEarlyHintsPortalTest,
+                       DisallowPreloadInPortal) {
+  EXPECT_TRUE(NavigateToURL(
+      shell(), net::QuicSimpleTestServer::GetFileURL("/title1.html")));
+
+  ResponseEntry entry = CreatePageEntryWithHintedScript(net::HTTP_OK);
+  RegisterResponse(entry);
+
+  GURL portal_url(
+      net::QuicSimpleTestServer::GetFileURL(kPageWithHintedScriptPath));
+  WebContentsAddedObserver contents_observer;
+  TestNavigationObserver portal_nav_observer(portal_url);
+  portal_nav_observer.StartWatchingNewWebContents();
+
+  // Create a portal.
+  EXPECT_TRUE(
+      ExecJs(shell()->web_contents()->GetMainFrame(),
+             JsReplace("{"
+                       "  let portal = document.createElement('portal');"
+                       "  portal.src = $1;"
+                       "  document.body.appendChild(portal);"
+                       "}",
+                       portal_url),
+             EXECUTE_SCRIPT_NO_USER_GESTURE));
+
+  WebContents* portal_web_contents = contents_observer.GetWebContents();
+  EXPECT_NE(portal_web_contents, nullptr);
+  portal_nav_observer.WaitForNavigationFinished();
+
+  EXPECT_EQ(
+      static_cast<RenderFrameHostImpl*>(portal_web_contents->GetMainFrame())
+          ->early_hints_manager(),
+      nullptr);
+}
+
 }  // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 72c6589..81a59cd 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -732,10 +732,13 @@
   DCHECK_NE(early_hints->ip_address_space,
             network::mojom::IPAddressSpace::kUnknown);
 
-  // Allow Early Hints preload only for the main frame. Calculating appropriate
-  // parameters to create URLLoaderFactory for subframes is complicated and not
-  // supported yet.
-  if (!resource_request_->is_main_frame)
+  FrameTreeNode* frame_tree_node =
+      FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
+
+  // Allow Early Hints preload only for outermost main frames. Calculating
+  // appropriate parameters to create URLLoaderFactory for subframes, fenced
+  // frames or portal are complicated and not supported yet.
+  if (frame_tree_node->GetParentOrOuterDocument())
     return;
 
   if (!early_hints_manager_) {
diff --git a/content/browser/media/capture_handle_manager.cc b/content/browser/media/capture_handle_manager.cc
index a60f0ca..7e547cb70 100644
--- a/content/browser/media/capture_handle_manager.cc
+++ b/content/browser/media/capture_handle_manager.cc
@@ -225,12 +225,10 @@
   auto iter = captures_.find(capture_key);
   if (iter == captures_.end()) {
     // Creating a new tracking session.
-    const absl::optional<media::mojom::DisplayMediaInformationPtr>& info =
+    const media::mojom::DisplayMediaInformationPtr& info =
         captured_device.display_media_info;
     media::mojom::CaptureHandlePtr capture_handle =
-        (info.has_value() && info.value())
-            ? info.value()->capture_handle.Clone()
-            : nullptr;
+        info ? info->capture_handle.Clone() : nullptr;
     captures_[capture_key] = std::make_unique<CaptureInfo>(
         std::move(observer), std::move(capture_handle),
         std::move(handle_change_callback));
diff --git a/content/browser/net/cross_origin_embedder_policy_reporter.cc b/content/browser/net/cross_origin_embedder_policy_reporter.cc
index 062c7a3f..8af590c 100644
--- a/content/browser/net/cross_origin_embedder_policy_reporter.cc
+++ b/content/browser/net/cross_origin_embedder_policy_reporter.cc
@@ -17,7 +17,7 @@
 constexpr char kType[] = "coep";
 
 GURL StripUsernameAndPassword(const GURL& url) {
-  url::Replacements<char> replacements;
+  GURL::Replacements replacements;
   replacements.ClearUsername();
   replacements.ClearPassword();
   return url.ReplaceComponents(replacements);
diff --git a/content/browser/network_context_client_base_impl.cc b/content/browser/network_context_client_base_impl.cc
index 6a1bef4..8673a45 100644
--- a/content/browser/network_context_client_base_impl.cc
+++ b/content/browser/network_context_client_base_impl.cc
@@ -128,4 +128,11 @@
   std::move(callback).Run(std::move(response));
 }
 
+void NetworkContextClientBase::OnCanSendSCTAuditingReport(
+    OnCanSendSCTAuditingReportCallback callback) {
+  std::move(callback).Run(false);
+}
+
+void NetworkContextClientBase::OnNewSCTAuditingReportSent() {}
+
 }  // namespace content
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc
index cba6b83a..1efbba1 100644
--- a/content/browser/portal/portal.cc
+++ b/content/browser/portal/portal.cc
@@ -625,6 +625,11 @@
   devtools_instrumentation::PortalActivated(outer_contents->GetMainFrame());
   successor_contents_raw->set_portal(nullptr);
 
+  // It's important we call this before destroying the outer contents'
+  // RenderWidgetHostView, otherwise the dialog may not be cleaned up correctly.
+  // See crbug.com/1292261 for more details.
+  outer_contents->CancelActiveAndPendingDialogs();
+
   std::unique_ptr<WebContents> predecessor_web_contents =
       delegate->ActivatePortalWebContents(outer_contents,
                                           std::move(successor_contents));
diff --git a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
index ab9089f..e030b49 100644
--- a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
+++ b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
@@ -181,8 +181,6 @@
       return ProtoEnum::CACHE_CONTROL_NO_STORE_HTTP_ONLY_COOKIE_MODIFIED;
     case Reason::kNoResponseHead:
       return ProtoEnum::NO_RESPONSE_HEAD;
-    case Reason::kActivationNavigationsDisallowedForBug1234857:
-      return ProtoEnum::ACTIVATION_NAVIGATION_DISALLOWED_FOR_BUG_1234857;
     case Reason::kBlocklistedFeatures:
       return ProtoEnum::BLOCKLISTED_FEATURES;
     case Reason::kUnknown:
@@ -391,10 +389,6 @@
     case Reason::kNoResponseHead:
       return "main RenderFrameHost doesn't have response headers set, probably "
              "due not having successfully committed a navigation.";
-    case Reason::kActivationNavigationsDisallowedForBug1234857:
-      return "Activation navigations are disallowed to avoid bypassing "
-             "PasswordProtectionService as a workaround for "
-             "https://crbug.com/1234857.";
   }
 }
 
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index a61367b..c783a4eb 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -797,17 +797,6 @@
         BackForwardCacheMetrics::NotRestoredReason::kSchemeNotHTTPOrHTTPS);
   }
 
-  // Do not store if activation navigations are disabled by the
-  // NavigatorDelegate as a workaround for the following bug.
-  // TODO(https://crbug.com/1234857): Remove this when the bug is fixed.
-  if (rfh->frame_tree()
-          ->navigator()
-          .GetDelegate()
-          ->IsActivationNavigationDisallowedForBug1234857()) {
-    result.No(BackForwardCacheMetrics::NotRestoredReason::
-                  kActivationNavigationsDisallowedForBug1234857);
-  }
-
   // We should not cache pages with Cache-control: no-store. Note that
   // even though this is categorized as a "feature", we will check this within
   // CanPotentiallyStorePageLater as it's not possible to change the HTTP
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.h b/content/browser/renderer_host/back_forward_cache_metrics.h
index a785419..33205be 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.h
+++ b/content/browser/renderer_host/back_forward_cache_metrics.h
@@ -110,8 +110,8 @@
     kCacheControlNoStoreCookieModified = 54,
     kCacheControlNoStoreHTTPOnlyCookieModified = 55,
     kNoResponseHead = 56,
-    kActivationNavigationsDisallowedForBug1234857 = 57,
-    kMaxValue = kActivationNavigationsDisallowedForBug1234857,
+    // 57: kActivationNavigationsDisallowedForBug1234857 was fixed.
+    kMaxValue = kNoResponseHead,
   };
 
   using NotRestoredReasons =
diff --git a/content/browser/renderer_host/commit_deferring_condition_runner.cc b/content/browser/renderer_host/commit_deferring_condition_runner.cc
index 7ea43832..7caafd8 100644
--- a/content/browser/renderer_host/commit_deferring_condition_runner.cc
+++ b/content/browser/renderer_host/commit_deferring_condition_runner.cc
@@ -57,8 +57,13 @@
   AddCondition(std::move(condition));
 }
 
-bool CommitDeferringConditionRunner::is_deferred_for_testing() const {
-  return is_deferred_;
+CommitDeferringCondition*
+CommitDeferringConditionRunner::GetDeferringConditionForTesting() const {
+  if (!is_deferred_)
+    return nullptr;
+
+  DCHECK(!conditions_.empty());
+  return (*conditions_.begin()).get();
 }
 
 void CommitDeferringConditionRunner::ResumeProcessing() {
diff --git a/content/browser/renderer_host/commit_deferring_condition_runner.h b/content/browser/renderer_host/commit_deferring_condition_runner.h
index ce932689..03003e7 100644
--- a/content/browser/renderer_host/commit_deferring_condition_runner.h
+++ b/content/browser/renderer_host/commit_deferring_condition_runner.h
@@ -109,9 +109,9 @@
   void AddConditionForTesting(
       std::unique_ptr<CommitDeferringCondition> condition);
 
-  // Used in tests to check if CommitDeferringConditionRunner is currently
-  // deferred for the navigation or not.
-  bool is_deferred_for_testing() const;
+  // Returns the condition that's currently causing the navigation commit to be
+  // deferred. If no condition is currently deferred, returns nullptr.
+  CommitDeferringCondition* GetDeferringConditionForTesting() const;
 
  private:
   friend class CommitDeferringConditionRunnerTest;
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc
index aa1f229..c82451b365 100644
--- a/content/browser/renderer_host/cookie_utils.cc
+++ b/content/browser/renderer_host/cookie_utils.cc
@@ -121,12 +121,12 @@
   for (const network::mojom::CookieOrLineWithAccessResultPtr& cookie :
        cookie_details->cookie_list) {
     if (ShouldReportDevToolsIssueForStatus(cookie->access_result.status)) {
-      devtools_instrumentation::ReportSameSiteCookieIssue(
+      devtools_instrumentation::ReportCookieIssue(
           root_frame_host, cookie, cookie_details->url,
           cookie_details->site_for_cookies,
           cookie_details->type == CookieAccessDetails::Type::kRead
-              ? blink::mojom::SameSiteCookieOperation::kReadCookie
-              : blink::mojom::SameSiteCookieOperation::kSetCookie,
+              ? blink::mojom::CookieOperation::kReadCookie
+              : blink::mojom::CookieOperation::kSetCookie,
           cookie_details->devtools_request_id);
     }
 
diff --git a/content/browser/renderer_host/media/capture_handle_manager_unittest.cc b/content/browser/renderer_host/media/capture_handle_manager_unittest.cc
index 25db22b..d5cec917 100644
--- a/content/browser/renderer_host/media/capture_handle_manager_unittest.cc
+++ b/content/browser/renderer_host/media/capture_handle_manager_unittest.cc
@@ -117,7 +117,7 @@
                                        frame->GetRoutingID());
     device.id = id.ToString();
     device.display_media_info = media::mojom::DisplayMediaInformation::New();
-    (*device.display_media_info)->capture_handle = std::move(capture_handle);
+    device.display_media_info->capture_handle = std::move(capture_handle);
 
     return device;
   }
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index df3c48a6..3eca3db 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -271,7 +271,7 @@
     const std::string& label,
     const blink::MediaStreamDevice& device) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(device.display_media_info.has_value());
+  DCHECK(device.display_media_info);
 
   GetMediaStreamDeviceObserver()->OnDeviceCaptureHandleChange(label, device);
 }
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index f29c3c2..0621903 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -3238,13 +3238,13 @@
       continue;
     }
 
-    if (!device.display_media_info.has_value()) {
+    if (!device.display_media_info) {
       DVLOG(1) << "Tab capture without a DisplayMediaInformation (" << label
                << ", " << type << ").";
       continue;
     }
 
-    device.display_media_info.value()->capture_handle = capture_handle.Clone();
+    device.display_media_info->capture_handle = capture_handle.Clone();
 
     if (request->device_capture_handle_change_cb) {
       request->device_capture_handle_change_cb.Run(label, device);
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 74c05b7..88c91e2 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -1009,9 +1009,7 @@
 
   base::WeakPtr<RenderFrameHostImpl> rfh_restored_from_back_forward_cache =
       nullptr;
-  if (entry && !frame_tree_node->navigator()
-                    .GetDelegate()
-                    ->IsActivationNavigationDisallowedForBug1234857()) {
+  if (entry) {
     BackForwardCacheImpl::Entry* restored_entry =
         frame_tree_node->navigator()
             .controller()
@@ -1728,7 +1726,16 @@
 }
 
 bool NavigationRequest::IsCommitDeferringConditionDeferredForTesting() {
-  return commit_deferrer_->is_deferred_for_testing();  // IN-TEST
+  if (!commit_deferrer_)
+    return false;
+  return commit_deferrer_->GetDeferringConditionForTesting();  // IN-TEST
+}
+
+CommitDeferringCondition*
+NavigationRequest::GetCommitDeferringConditionForTesting() {
+  if (!commit_deferrer_)
+    return nullptr;
+  return commit_deferrer_->GetDeferringConditionForTesting();  // IN-TEST
 }
 
 void NavigationRequest::BeginNavigation() {
@@ -1780,9 +1787,6 @@
   if (!blink::features::IsPrerender2Enabled())
     return false;
 
-  if (GetDelegate()->IsActivationNavigationDisallowedForBug1234857())
-    return false;
-
   // Find an available prerendered page for this request. If it's found, this
   // request may activate it instead of loading a page via network.
   int candidate_prerender_frame_tree_node_id =
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h
index 99324f4..33509df 100644
--- a/content/browser/renderer_host/navigation_request.h
+++ b/content/browser/renderer_host/navigation_request.h
@@ -336,6 +336,7 @@
       std::unique_ptr<NavigationThrottle> navigation_throttle) override;
   bool IsDeferredForTesting() override;
   bool IsCommitDeferringConditionDeferredForTesting() override;
+  CommitDeferringCondition* GetCommitDeferringConditionForTesting() override;
   bool WasStartedFromContextMenu() override;
   const GURL& GetSearchableFormURL() override;
   const std::string& GetSearchableFormEncoding() override;
diff --git a/content/browser/renderer_host/navigator_delegate.h b/content/browser/renderer_host/navigator_delegate.h
index 2a45a96..fd06da92 100644
--- a/content/browser/renderer_host/navigator_delegate.h
+++ b/content/browser/renderer_host/navigator_delegate.h
@@ -133,13 +133,6 @@
   virtual void RegisterExistingOriginToPreventOptInIsolation(
       const url::Origin& origin,
       NavigationRequest* navigation_request_to_exclude) = 0;
-
-  // Returns true if activation navigations are disallowed in the
-  // Navigator.
-  // TODO(https://crbug.com/1234857): Remove this. This is a temporary
-  // workaround to avoid breaking features that must be taught to deal with
-  // activation navigations.
-  virtual bool IsActivationNavigationDisallowedForBug1234857() = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index a82a1c0e..da888f19 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1481,6 +1481,8 @@
 }
 
 RenderFrameHostImpl::~RenderFrameHostImpl() {
+  CHECK_EQ(check_if_deleted_request_count_, 0);
+
   // The lifetime of this object has ended, so remove it from the id map before
   // calling any delegates/observers, so that any calls to |FromID| no longer
   // return |this|.
@@ -13130,4 +13132,22 @@
   return o << RenderFrameHostImpl::LifecycleStateImplToString(s);
 }
 
+std::unique_ptr<RenderFrameHostImpl::CheckOnDeleteRef>
+RenderFrameHostImpl::EnableCheckIfDeleted() {
+  // Uses WrapUnique() as constructor is private.
+  return base::WrapUnique(new CheckOnDeleteRef(this));
+}
+
+RenderFrameHostImpl::CheckOnDeleteRef::~CheckOnDeleteRef() {
+  --(host_->check_if_deleted_request_count_);
+  CHECK_GE(host_->check_if_deleted_request_count_, 0);
+}
+
+RenderFrameHostImpl::CheckOnDeleteRef::CheckOnDeleteRef(
+    RenderFrameHostImpl* host)
+    : host_(host) {
+  ++(host_->check_if_deleted_request_count_);
+  CHECK_GT(host_->check_if_deleted_request_count_, 0);
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index c3759bc..c9bdd3d 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2432,6 +2432,23 @@
 
   void DidChangeReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy);
 
+  class CheckOnDeleteRef {
+   public:
+    CheckOnDeleteRef(const CheckOnDeleteRef&) = delete;
+    CheckOnDeleteRef& operator=(const CheckOnDeleteRef&) = delete;
+    ~CheckOnDeleteRef();
+
+   private:
+    friend class RenderFrameHostImpl;
+
+    explicit CheckOnDeleteRef(RenderFrameHostImpl* host);
+
+    RenderFrameHostImpl* host_;
+  };
+
+  // TODO(https://crbug.com/1262098): used to track down crash.
+  std::unique_ptr<CheckOnDeleteRef> EnableCheckIfDeleted();
+
  protected:
   friend class RenderFrameHostFactory;
 
@@ -4126,6 +4143,8 @@
   BackForwardCacheDisablingFeaturesCallback
       back_forward_cache_disabling_features_callback_for_testing_;
 
+  int check_if_deleted_request_count_ = 0;
+
   // WeakPtrFactories are the last members, to ensure they are destroyed before
   // all other fields of `this`.
   base::WeakPtrFactory<RenderFrameHostImpl> weak_ptr_factory_{this};
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 015dcdf..bc432381 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -3398,6 +3398,9 @@
     }
   }
 
+  // TODO(https://crbug.com/1262098): used to track down crash.
+  auto check_on_delete_ref = render_frame_host_->EnableCheckIfDeleted();
+
   // For all main frames, the RenderWidgetHost will not be destroyed when the
   // local frame is detached. https://crbug.com/419087
   //
@@ -3443,7 +3446,9 @@
   // also exist. For a local root frame, they share lifetimes exactly. For
   // another child frame, the RenderWidgetHostView comes from a parent, but if
   // this renderer frame is live its ancestors must be as well.
-  DCHECK(new_view);
+  // TODO(https://crbug.com/1262098): used to track down crash, converted
+  // from DCHECK to CHECK.
+  CHECK(new_view);
 
   if (focus_render_view) {
     if (is_main_frame) {
@@ -3491,6 +3496,8 @@
   delegate_->NotifySwappedFromRenderManager(old_render_frame_host.get(),
                                             render_frame_host_.get());
 
+  check_on_delete_ref.reset();
+
   // Make the new view show the contents of old view until it has something
   // useful to show.
   if (is_main_frame && old_view && old_view != new_view)
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index f127b930..17a6b19 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -167,6 +167,11 @@
 // before clearing previously displayed graphics.
 constexpr base::TimeDelta kNewContentRenderingDelay = base::Seconds(4);
 
+constexpr gfx::Rect kInvalidScreenRect(std::numeric_limits<int>::max(),
+                                       std::numeric_limits<int>::max(),
+                                       0,
+                                       0);
+
 bool g_check_for_pending_visual_properties_ack = true;
 
 bool ShouldDisableHangMonitor() {
@@ -430,6 +435,8 @@
       agent_scheduling_group_(agent_scheduling_group),
       routing_id_(routing_id),
       is_hidden_(hidden),
+      last_view_screen_rect_(kInvalidScreenRect),
+      last_window_screen_rect_(kInvalidScreenRect),
       latency_tracker_(delegate_),
       hung_renderer_delay_(kHungRendererDelay),
       new_content_rendering_delay_(kNewContentRenderingDelay),
@@ -649,6 +656,11 @@
     return;
   }
 
+  if (last_view_screen_rect_ == view_->GetViewBounds() &&
+      last_window_screen_rect_ == view_->GetBoundsInRootWindow()) {
+    return;
+  }
+
   last_view_screen_rect_ = view_->GetViewBounds();
   last_window_screen_rect_ = view_->GetBoundsInRootWindow();
   blink_widget_->UpdateScreenRects(
@@ -2252,6 +2264,7 @@
   // When the RenderWidget was destroyed, the ack may never come back. Don't
   // let that prevent us from speaking to the next RenderWidget.
   waiting_for_screen_rects_ack_ = false;
+  last_view_screen_rect_ = last_window_screen_rect_ = kInvalidScreenRect;
 
   visual_properties_ack_pending_ =
       DoesVisualPropertiesNeedAck(nullptr, initial_props);
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 9d71949..0be83b9 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -2028,6 +2028,12 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1u, widget_.ReceivedScreenRects().size());
 
+  // If screen rects haven't changed, don't send them to the widget.
+  ClearScreenRects();
+  host_->SendScreenRects();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0u, widget_.ReceivedScreenRects().size());
+
   // The RenderWidget has been destroyed in the renderer.
   EXPECT_CALL(mock_owner_delegate_, IsMainFrameActive())
       .WillRepeatedly(Return(false));
@@ -2035,7 +2041,7 @@
   // Still can't send until the RenderWidget is replaced.
   host_->SendScreenRects();
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1u, widget_.ReceivedScreenRects().size());
+  EXPECT_EQ(0u, widget_.ReceivedScreenRects().size());
 
   // Make a new RenderWidget when the renderer is recreated and inform that a
   // RenderWidget is being created.
@@ -2048,7 +2054,7 @@
   // for an ack.
   host_->SendScreenRects();
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(2u, widget_.ReceivedScreenRects().size());
+  EXPECT_EQ(1u, widget_.ReceivedScreenRects().size());
 }
 
 // Regression test for http://crbug.com/401859 and http://crbug.com/522795.
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 4104bde..6cbe5f15 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -2123,6 +2123,16 @@
           callback_key, weak_factory_.GetWeakPtr()));
 }
 
+void StoragePartitionImpl::OnCanSendSCTAuditingReport(
+    OnCanSendSCTAuditingReportCallback callback) {
+  GetContentClient()->browser()->CanSendSCTAuditingReport(browser_context_,
+                                                          std::move(callback));
+}
+
+void StoragePartitionImpl::OnNewSCTAuditingReportSent() {
+  GetContentClient()->browser()->OnNewSCTAuditingReportSent(browser_context_);
+}
+
 void StoragePartitionImpl::ClearDataImpl(
     uint32_t remove_mask,
     uint32_t quota_storage_remove_mask,
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index f273fa7f..fbc340f 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -287,6 +287,9 @@
   void OnTrustTokenIssuanceDivertedToSystem(
       network::mojom::FulfillTrustTokenIssuanceRequestPtr request,
       OnTrustTokenIssuanceDivertedToSystemCallback callback) override;
+  void OnCanSendSCTAuditingReport(
+      OnCanSendSCTAuditingReportCallback callback) override;
+  void OnNewSCTAuditingReportSent() override;
 
   // network::mojom::URLLoaderNetworkServiceObserver interface.
   void OnSSLCertificateError(const GURL& url,
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
index fb11e67..d65ac3b 100644
--- a/content/browser/storage_partition_impl_unittest.cc
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -1985,7 +1985,7 @@
   run_loop.Run();
 
   EXPECT_TRUE(
-      GetAttributionsToReportForTesting(attribution_manager, base::Time::Max())
+      GetAttributionReportsForTesting(attribution_manager, base::Time::Max())
           .empty());
 }
 
@@ -2002,7 +2002,7 @@
   attribution_manager->HandleTrigger(DefaultTrigger());
 
   EXPECT_FALSE(
-      GetAttributionsToReportForTesting(attribution_manager, base::Time::Max())
+      GetAttributionReportsForTesting(attribution_manager, base::Time::Max())
           .empty());
 
   // Arbitrary non-conversions mask.
@@ -2012,7 +2012,7 @@
                        now, run_loop.QuitClosure());
   run_loop.Run();
   EXPECT_FALSE(
-      GetAttributionsToReportForTesting(attribution_manager, base::Time::Max())
+      GetAttributionReportsForTesting(attribution_manager, base::Time::Max())
           .empty());
 }
 
@@ -2041,7 +2041,7 @@
   run_loop.Run();
 
   EXPECT_TRUE(
-      GetAttributionsToReportForTesting(attribution_manager, base::Time::Max())
+      GetAttributionReportsForTesting(attribution_manager, base::Time::Max())
           .empty());
 }
 
@@ -2073,8 +2073,8 @@
             .Build());
   }
 
-  EXPECT_EQ(5u, GetAttributionsToReportForTesting(attribution_manager,
-                                                  base::Time::Max())
+  EXPECT_EQ(5u, GetAttributionReportsForTesting(attribution_manager,
+                                                base::Time::Max())
                     .size());
 
   // Match against enough Origins to delete three of the imp/conv pairs.
@@ -2089,8 +2089,8 @@
   partition->ClearData(StoragePartition::REMOVE_DATA_MASK_CONVERSIONS, 0, func,
                        nullptr, false, now, now, run_loop.QuitClosure());
   run_loop.Run();
-  EXPECT_EQ(2u, GetAttributionsToReportForTesting(attribution_manager,
-                                                  base::Time::Max())
+  EXPECT_EQ(2u, GetAttributionReportsForTesting(attribution_manager,
+                                                base::Time::Max())
                     .size());
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index e2c036f..909eb84 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2318,19 +2318,6 @@
            primary_frame_tree_.root()->frame_tree_node_id());
 }
 
-void WebContentsImpl::DisallowActivationNavigationsForBug1234857() {
-  disallow_activation_navigations_ = true;
-
-  // Flush any inactive frames since they will never be activated.
-  ForEachRenderFrameHost(base::BindRepeating([](RenderFrameHostImpl* rfh) {
-    // Just look at main frames since we only need to call
-    // IsInactiveAndDisallowActivation() on the main frame.
-    if (!rfh->GetParent())
-      rfh->IsInactiveAndDisallowActivation(
-          DisallowActivationReasonId::kBug1234857);
-  }));
-}
-
 const base::Location& WebContentsImpl::GetCreatorLocation() {
   return creator_location_;
 }
@@ -6626,6 +6613,9 @@
   if (old_frame && !new_frame->GetParent()) {
     RenderWidgetHostImpl* old_widget = old_frame->GetRenderWidgetHost();
     RenderWidgetHostImpl* new_widget = new_frame->GetRenderWidgetHost();
+    // TODO(https://crbug.com/1262098): CHECKs are to help track down crash.
+    CHECK(new_widget);
+    CHECK(old_widget);
     new_widget->SetImportance(old_widget->importance());
   }
 #endif
@@ -7467,10 +7457,6 @@
   }
 }
 
-bool WebContentsImpl::IsActivationNavigationDisallowedForBug1234857() {
-  return disallow_activation_navigations_;
-}
-
 void WebContentsImpl::DidChangeName(RenderFrameHostImpl* render_frame_host,
                                     const std::string& name) {
   OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DidChangeName",
@@ -7953,6 +7939,9 @@
   DCHECK_NE(new_frame->lifecycle_state(),
             RenderFrameHostImpl::LifecycleStateImpl::kSpeculative);
 
+  // TODO(https://crbug.com/1262098): CHECKs are to help track down crash.
+  CHECK(new_frame);
+
   // Only fire RenderViewHostChanged if it is related to our FrameTree, as
   // observers can not deal with events coming from non-primary FrameTree.
   // TODO(https://crbug.com/1168562): Update observers to deal with the events,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index cbfb336..5710f87 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -565,7 +565,6 @@
   void SetIgnoreInputEvents(bool ignore_input_events) override;
   bool HasActiveEffectivelyFullscreenVideo() override;
   void WriteIntoTrace(perfetto::TracedValue context) override;
-  void DisallowActivationNavigationsForBug1234857() override;
   const base::Location& GetCreatorLocation() override;
   void UpdateBrowserControlsState(cc::BrowserControlsState constraints,
                                   cc::BrowserControlsState current,
@@ -895,7 +894,6 @@
   void RegisterExistingOriginToPreventOptInIsolation(
       const url::Origin& origin,
       NavigationRequest* navigation_request_to_exclude) override;
-  bool IsActivationNavigationDisallowedForBug1234857() override;
 
   // RenderWidgetHostDelegate --------------------------------------------------
 
@@ -2293,8 +2291,6 @@
   // color or if the page does not set a background color.
   absl::optional<SkColor> page_base_background_color_;
 
-  bool disallow_activation_navigations_ = false;
-
   // TODO(1231679): Remove/reevaluate after the PCScan experiment is finished.
   std::unique_ptr<StarScanLoadObserver> star_scan_load_observer_;
 
diff --git a/content/browser/webui/web_ui_impl.cc b/content/browser/webui/web_ui_impl.cc
index 81a53cb..d8e7829 100644
--- a/content/browser/webui/web_ui_impl.cc
+++ b/content/browser/webui/web_ui_impl.cc
@@ -259,15 +259,20 @@
 }
 
 void WebUIImpl::RegisterMessageCallback(base::StringPiece message,
-                                        DeprecatedMessageCallback2 callback) {
-  deprecated_message_callbacks_2_.emplace(std::string(message),
-                                          std::move(callback));
+                                        MessageCallback callback) {
+  message_callbacks_.emplace(message, std::move(callback));
+}
+
+void WebUIImpl::RegisterDeprecatedMessageCallback2(
+    base::StringPiece message,
+    DeprecatedMessageCallback2 callback) {
+  deprecated_message_callbacks_2_.emplace(message, std::move(callback));
 }
 
 void WebUIImpl::RegisterDeprecatedMessageCallback(
     base::StringPiece message,
     const DeprecatedMessageCallback& callback) {
-  deprecated_message_callbacks_.emplace(std::string(message), callback);
+  deprecated_message_callbacks_.emplace(message, callback);
 }
 
 void WebUIImpl::ProcessWebUIMessage(const GURL& source_url,
@@ -276,11 +281,19 @@
   if (controller_->OverrideHandleWebUIMessage(source_url, message, args))
     return;
 
-  // Look up the callback for this message.
-  auto callback_pair = deprecated_message_callbacks_2_.find(message);
-  if (callback_pair != deprecated_message_callbacks_2_.end()) {
+  auto callback_pair = message_callbacks_.find(message);
+  if (callback_pair != message_callbacks_.end()) {
     // Forward this message and content on.
-    callback_pair->second.Run(args.GetListDeprecated());
+    callback_pair->second.Run(args.GetList());
+    return;
+  }
+
+  // Look up the deprecated callback for this message.
+  auto deprecated_callback_2_pair =
+      deprecated_message_callbacks_2_.find(message);
+  if (deprecated_callback_2_pair != deprecated_message_callbacks_2_.end()) {
+    // Forward this message and content on.
+    deprecated_callback_2_pair->second.Run(args.GetListDeprecated());
     return;
   }
 
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h
index e9150fc..66fcbc49 100644
--- a/content/browser/webui/web_ui_impl.h
+++ b/content/browser/webui/web_ui_impl.h
@@ -74,7 +74,10 @@
   void AddRequestableScheme(const char* scheme) override;
   void AddMessageHandler(std::unique_ptr<WebUIMessageHandler> handler) override;
   void RegisterMessageCallback(base::StringPiece message,
-                               DeprecatedMessageCallback2 callback) override;
+                               MessageCallback callback) override;
+  void RegisterDeprecatedMessageCallback2(
+      base::StringPiece message,
+      DeprecatedMessageCallback2 callback) override;
   void RegisterDeprecatedMessageCallback(
       base::StringPiece message,
       const DeprecatedMessageCallback& callback) override;
@@ -125,10 +128,17 @@
   void DisallowJavascriptOnAllHandlers();
 
   // A map of message name -> message handling callback.
+  std::map<std::string, MessageCallback> message_callbacks_;
+
+  // A map of message name -> message handling callback.
+  // TODO(crbug.com/1300095): Remove once RegisterDeprecatedMessageCallback2()
+  // instances are migrated to RegisterMessageCallback().
   std::map<std::string, DeprecatedMessageCallback2>
       deprecated_message_callbacks_2_;
 
   // A map of message name -> message handling callback.
+  // TODO(crbug.com/1300095): Remove once RegisterDeprecatedMessageCallback()
+  // instances are migrated to RegisterMessageCallback().
   std::map<std::string, DeprecatedMessageCallback>
       deprecated_message_callbacks_;
 
diff --git a/content/common/android/java_templates/ContentSwitches.java.tmpl b/content/common/android/java_templates/ContentSwitches.java.tmpl
index 1da06a1..334fad3d 100644
--- a/content/common/android/java_templates/ContentSwitches.java.tmpl
+++ b/content/common/android/java_templates/ContentSwitches.java.tmpl
@@ -64,9 +64,6 @@
     // Native switch value kNetworkSandbox
     public static final String NETWORK_SANDBOX_TYPE = "network";
 
-    // Native switch kNoneSandbox, only honored on non-public Chromecast builds.
-    public static final String NONE_SANDBOX_TYPE = "none";
-
 {NATIVE_STRINGS}
 
     // Prevent instantiation.
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
index 47d4d0a..a32a86ed 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
@@ -39,7 +39,6 @@
 import org.chromium.base.process_launcher.ChildProcessLauncher;
 import org.chromium.base.process_launcher.FileDescriptorInfo;
 import org.chromium.base.task.PostTask;
-import org.chromium.build.BuildConfig;
 import org.chromium.content.app.SandboxedProcessService;
 import org.chromium.content.common.ContentSwitchUtils;
 import org.chromium.content_public.browser.ChildProcessImportance;
@@ -380,17 +379,9 @@
                 // We only support sandboxed utility processes now.
                 assert ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType);
 
-                String serviceSandboxType = ContentSwitchUtils.getSwitchValue(
-                        commandLine, ContentSwitches.SWITCH_SERVICE_SANDBOX_TYPE);
-
-                // Non-sandboxed utility processes only supported for non-public Chromecast.
-                if (BuildConfig.IS_CHROMECAST_BRANDING_INTERNAL
-                        && ContentSwitches.NONE_SANDBOX_TYPE.equals(serviceSandboxType)) {
-                    sandboxed = false;
-                }
-
                 // Network Service:
-                if (ContentSwitches.NETWORK_SANDBOX_TYPE.equals(serviceSandboxType)) {
+                if (ContentSwitches.NETWORK_SANDBOX_TYPE.equals(ContentSwitchUtils.getSwitchValue(
+                            commandLine, ContentSwitches.SWITCH_SERVICE_SANDBOX_TYPE))) {
                     sandboxed = ChildProcessLauncherHelperImplJni.get().isNetworkSandboxEnabled();
                 }
             }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
index b127d54..ff3e4c0 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -190,6 +190,16 @@
     private static final int EVENTS_DROPPED_HISTOGRAM_MAX_BUCKET = 10000;
     private static final int EVENTS_DROPPED_HISTOGRAM_BUCKET_COUNT = 100;
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public static final String CACHE_MAX_NODES_HISTOGRAM =
+            "Accessibility.Android.Cache.MaxNodesInCache";
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public static final String CACHE_PERCENTAGE_RETRIEVED_FROM_CAHCE_HISTOGRAM =
+            "Accessibility.Android.Cache.PercentageRetrievedFromCache";
+    private static final int CACHE_MAX_NODES_MIN_BUCKET = 1;
+    private static final int CACHE_MAX_NODES_MAX_BUCKET = 3000;
+    private static final int CACHE_MAX_NODES_BUCKET_COUNT = 100;
+
     // Static instances of the two types of extra data keys that can be added to nodes.
     private static final List<String> sTextCharacterLocation =
             Collections.singletonList(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY);
@@ -268,6 +278,12 @@
     private int mTotalEnqueuedEvents;
     private int mTotalDispatchedEvents;
 
+    // These track the usage of the |mNodeInfoCache| to report metrics on the max number of items
+    // that were stored in the cache, and the percentage of requests retrieved from the cache.
+    private int mMaxNodesInCache;
+    private int mNodeWasReturnedFromCache;
+    private int mNodeWasCreatedFromScratch;
+
     // Set of all nodes that have received a request to populate image data. The request only needs
     // to be run once per node, and it completes asynchronously. We track which nodes have already
     // started the async request so that if downstream apps request the same node multiple times
@@ -494,6 +510,11 @@
     }
 
     @VisibleForTesting
+    public void forceRecordCacheUMAHistogramsForTesting() {
+        recordCacheUMAHistograms();
+    }
+
+    @VisibleForTesting
     public void setEventTypeMaskEmptyForTesting() {
         BrowserAccessibilityState.setEventTypeMaskEmptyForTesting();
     }
@@ -525,6 +546,9 @@
         if (ContentFeatureList.isEnabled(ContentFeatureList.ON_DEMAND_ACCESSIBILITY_EVENTS)) {
             recordUMAHistograms();
         }
+
+        // Always track the histograms for cache usage statistics.
+        recordCacheUMAHistograms();
     }
 
     // Helper method to record UMA histograms for OnDemand feature and reset counters.
@@ -582,6 +606,24 @@
         mTotalDispatchedEvents = 0;
     }
 
+    // Helper method to record UMA histograms for cache usage statistics.
+    private void recordCacheUMAHistograms() {
+        RecordHistogram.recordCustomCountHistogram(CACHE_MAX_NODES_HISTOGRAM, mMaxNodesInCache,
+                CACHE_MAX_NODES_MIN_BUCKET, CACHE_MAX_NODES_MAX_BUCKET,
+                CACHE_MAX_NODES_BUCKET_COUNT);
+
+        int totalNodeRequests = mNodeWasReturnedFromCache + mNodeWasCreatedFromScratch;
+        int percentFromCache = (int) (mNodeWasReturnedFromCache * 1.0 / totalNodeRequests * 100.0);
+
+        RecordHistogram.recordPercentageHistogram(
+                CACHE_PERCENTAGE_RETRIEVED_FROM_CAHCE_HISTOGRAM, percentFromCache);
+
+        // Reset counters.
+        mMaxNodesInCache = 0;
+        mNodeWasReturnedFromCache = 0;
+        mNodeWasCreatedFromScratch = 0;
+    }
+
     @Override
     public void onAttachedToWindow() {
         mAccessibilityManager.addAccessibilityStateChangeListener(this);
@@ -695,6 +737,11 @@
     }
 
     @CalledByNative
+    public void updateMaxNodesInCache() {
+        mMaxNodesInCache = Math.max(mMaxNodesInCache, mNodeInfoCache.size());
+    }
+
+    @CalledByNative
     public void clearNodeInfoCacheForGivenId(int virtualViewId) {
         // Recycle and remove the element in our cache for this |virtualViewId|.
         if (mNodeInfoCache.get(virtualViewId) != null) {
@@ -743,6 +790,7 @@
                     cachedNode.addAction(ACTION_ACCESSIBILITY_FOCUS);
                 }
 
+                mNodeWasReturnedFromCache++;
                 return cachedNode;
             } else {
                 // If the node is no longer valid, wipe it from the cache and return null
@@ -765,6 +813,7 @@
                         mNativeObj, WebContentsAccessibilityImpl.this, info, virtualViewId)) {
                 // After successfully populating this node, add it to our cache then return.
                 mNodeInfoCache.put(virtualViewId, AccessibilityNodeInfoCompat.obtain(info));
+                mNodeWasCreatedFromScratch++;
                 return info;
             } else {
                 info.recycle();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java
index 0af3bb9..67fd9798 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java
@@ -46,11 +46,12 @@
     private final long mNavigationId;
 
     @CalledByNative
-    public NavigationHandle(long nativeNavigationHandleProxy, GURL url, GURL referrerUrl,
-            GURL baseUrlForDataUrl, boolean isInPrimaryMainFrame, boolean isSameDocument,
-            boolean isRendererInitiated, Origin initiatorOrigin, ByteBuffer impressionData,
-            @PageTransition int transition, boolean isPost, boolean hasUserGesture,
-            boolean isRedirect, boolean isExternalProtocol, long navigationId) {
+    public NavigationHandle(long nativeNavigationHandleProxy, @NonNull GURL url,
+            @NonNull GURL referrerUrl, @NonNull GURL baseUrlForDataUrl,
+            boolean isInPrimaryMainFrame, boolean isSameDocument, boolean isRendererInitiated,
+            Origin initiatorOrigin, ByteBuffer impressionData, @PageTransition int transition,
+            boolean isPost, boolean hasUserGesture, boolean isRedirect, boolean isExternalProtocol,
+            long navigationId) {
         mNativeNavigationHandleProxy = nativeNavigationHandleProxy;
         mUrl = url;
         mReferrerUrl = referrerUrl;
@@ -111,11 +112,13 @@
      * The URL the frame is navigating to.  This may change during the navigation when encountering
      * a server redirect.
      */
+    @NonNull
     public GURL getUrl() {
         return mUrl;
     }
 
     /** The referrer URL for the navigation. */
+    @NonNull
     public GURL getReferrerUrl() {
         return mReferrerUrl;
     }
@@ -123,6 +126,7 @@
     /**
      * Used for specifying a base URL for pages loaded via data URLs.
      */
+    @NonNull
     public GURL getBaseUrlForDataUrl() {
         return mBaseUrlForDataUrl;
     }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
index ba38144..88475eb 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -45,6 +45,8 @@
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sRangeInfoMatcher;
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sTextMatcher;
 import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sViewIdResourceNameMatcher;
+import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.CACHE_MAX_NODES_HISTOGRAM;
+import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.CACHE_PERCENTAGE_RETRIEVED_FROM_CAHCE_HISTOGRAM;
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EVENTS_DROPPED_HISTOGRAM;
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY;
 import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_CHROME_ROLE;
@@ -535,6 +537,28 @@
     }
 
     /**
+     * Test that UMA histograms are recorded for the cache statistics, including the max number of
+     * nodes stored in the cache, and percentage of requests retrieved from the cache.
+     */
+    @Test
+    @SmallTest
+    public void testUMAHistograms_Cache() throws Throwable {
+        // Build a simple web page with a few nodes to traverse.
+        setupTestWithHTML("<p>This is a test 1</p>\n"
+                + "<p>This is a test 2</p>\n"
+                + "<p>This is a test 3</p>");
+
+        performHistogramActions();
+
+        // Verify results were recorded in histograms.
+        Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1,
+                RecordHistogram.getHistogramTotalCountForTesting(CACHE_MAX_NODES_HISTOGRAM));
+        Assert.assertEquals(UMA_HISTOGRAM_ERROR, 1,
+                RecordHistogram.getHistogramTotalCountForTesting(
+                        CACHE_PERCENTAGE_RETRIEVED_FROM_CAHCE_HISTOGRAM));
+    }
+
+    /**
      * Test that the {resetFocus} method performs as expected with accessibility enabled.
      */
     @Test
@@ -2140,5 +2164,6 @@
 
         // Force recording of UMA histograms.
         mActivityTestRule.mWcax.forceRecordUMAHistogramsForTesting();
+        mActivityTestRule.mWcax.forceRecordCacheUMAHistogramsForTesting();
     }
 }
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 4ee1c6fe..b80600e 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -478,6 +478,12 @@
   return true;
 }
 
+void ContentBrowserClient::CanSendSCTAuditingReport(
+    BrowserContext* browser_context,
+    base::OnceCallback<void(bool)> callback) {
+  std::move(callback).Run(false);
+}
+
 scoped_refptr<QuotaPermissionContext>
 ContentBrowserClient::CreateQuotaPermissionContext() {
   return nullptr;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index ce6c5149..91646637 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -843,6 +843,15 @@
   virtual void OnTrustAnchorUsed(BrowserContext* browser_context) {}
 #endif
 
+  // Allows the embedder to implement policy for whether an SCT auditing report
+  // should be sent.
+  virtual void CanSendSCTAuditingReport(
+      BrowserContext* browser_context,
+      base::OnceCallback<void(bool)> callback);
+
+  // Notification that a new SCT auditing report has been sent.
+  virtual void OnNewSCTAuditingReportSent(BrowserContext* browser_context) {}
+
   // Allows the embedder to override the LocationProvider implementation.
   // Return nullptr to indicate the default one for the platform should be
   // created. This is used by Qt, see
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h
index b03b9ae4..0a0cf34 100644
--- a/content/public/browser/navigation_handle.h
+++ b/content/public/browser/navigation_handle.h
@@ -47,6 +47,7 @@
 }  // namespace net
 
 namespace content {
+class CommitDeferringCondition;
 struct GlobalRenderFrameHostId;
 struct GlobalRequestID;
 class NavigationEntry;
@@ -560,6 +561,11 @@
   // Returns a reference to NavigationHandle Java counterpart.
   virtual const base::android::JavaRef<jobject>& GetJavaNavigationHandle() = 0;
 #endif
+
+  // Returns the CommitDeferringCondition that is currently preventing this
+  // navigation from committing, or nullptr if the navigation isn't currently
+  // blocked on a CommitDeferringCondition.
+  virtual CommitDeferringCondition* GetCommitDeferringConditionForTesting() = 0;
 };
 
 }  // namespace content
diff --git a/content/public/browser/network_context_client_base.h b/content/public/browser/network_context_client_base.h
index 2480f128..d43635b 100644
--- a/content/public/browser/network_context_client_base.h
+++ b/content/public/browser/network_context_client_base.h
@@ -47,6 +47,9 @@
   void OnTrustTokenIssuanceDivertedToSystem(
       network::mojom::FulfillTrustTokenIssuanceRequestPtr request,
       OnTrustTokenIssuanceDivertedToSystemCallback callback) override;
+  void OnCanSendSCTAuditingReport(
+      OnCanSendSCTAuditingReportCallback callback) override;
+  void OnNewSCTAuditingReportSent() override;
 };
 
 }  // namespace content
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index ad5c139..68b521f 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -1313,14 +1313,6 @@
   // Serialise this object into a trace.
   virtual void WriteIntoTrace(perfetto::TracedValue context) = 0;
 
-  // Disallows navigations that activate a prerendered page or a back/forward
-  // cached page in this WebContents. Such pages will be ignored and normal
-  // navigation will occur instead.
-  // TODO(https://crbug.com/1234857): Remove this. This is a temporary
-  // workaround to avoid breaking features that must be taught to deal with
-  // activation navigations.
-  virtual void DisallowActivationNavigationsForBug1234857() = 0;
-
   // Returns the value from CreateParams::creator_location.
   virtual const base::Location& GetCreatorLocation() = 0;
 
diff --git a/content/public/browser/web_ui.h b/content/public/browser/web_ui.h
index 1d7cc91c..c770f73 100644
--- a/content/public/browser/web_ui.h
+++ b/content/public/browser/web_ui.h
@@ -73,26 +73,29 @@
   virtual void AddMessageHandler(
       std::unique_ptr<WebUIMessageHandler> handler) = 0;
 
-  // TODO(crbug.com/1300095): new version of DeprecatedMessageCallback2 that
-  // takes base::Value::List as a parameter needs to be introduced. Afterwards
-  // existing callers of RegisterDeprecatedMessageCallback() should be migrated
-  // to the new RegisterMessageCallback() (not the one below) version.
-  //
   // Used by WebUIMessageHandlers. If the given message is already registered,
   // the call has no effect.
+  using MessageCallback =
+      base::RepeatingCallback<void(const base::Value::List&)>;
+  virtual void RegisterMessageCallback(base::StringPiece message,
+                                       MessageCallback callback) = 0;
+
+  // TODO(crbug.com/1300095): Instances of RegisterDeprecatedMessageCallback2()
+  // should be migrated to RegisterMessageCallback() above if possible.
+  //
+  // Used by WebUIMessageHandlers. If the given message is already registered,
+  // the call has no effect. Use RegisterMessageCallback() above in new code.
   using DeprecatedMessageCallback2 =
       base::RepeatingCallback<void(base::Value::ConstListView)>;
-  virtual void RegisterMessageCallback(base::StringPiece message,
-                                       DeprecatedMessageCallback2 callback) = 0;
+  virtual void RegisterDeprecatedMessageCallback2(
+      base::StringPiece message,
+      DeprecatedMessageCallback2 callback) = 0;
 
-  // TODO(crbug.com/1300095): new version of DeprecatedMessageCallback that
-  // takes base::Value::List as a parameter needs to be introduced. Afterwards
-  // existing callers of RegisterDeprecatedMessageCallback() should be migrated
-  // to the new RegisterMessageCallback() (not the one above) version if
-  // possible.
+  // TODO(crbug.com/1300095): Instances of RegisterDeprecatedMessageCallback()
+  // should be migrated to RegisterMessageCallback() above if possible.
   //
   // Used by WebUIMessageHandlers. If the given message is already registered,
-  // the call has no effect.
+  // the call has no effect. Use RegisterMessageCallback() above in new code.
   using DeprecatedMessageCallback =
       base::RepeatingCallback<void(const base::ListValue*)>;
   virtual void RegisterDeprecatedMessageCallback(
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 7d158699..141b411 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -3387,6 +3387,10 @@
 void TestActivationManager::ResumeActivation() {
   TRACE_EVENT("test", "TestActivationManager::ResumeActivation");
   DCHECK(is_paused());
+
+  // Set desired_state_ to kFinished so the navigation can proceed to finish
+  // unless it yields somewhere and/or the caller calls another WaitFor method.
+  desired_state_ = ActivationState::kFinished;
   std::move(resume_callback_).Run();
 }
 
diff --git a/content/public/test/mock_navigation_handle.h b/content/public/test/mock_navigation_handle.h
index cc0460c..1293706a 100644
--- a/content/public/test/mock_navigation_handle.h
+++ b/content/public/test/mock_navigation_handle.h
@@ -211,6 +211,9 @@
     return weak_factory_.GetSafeRef();
   }
 
+  CommitDeferringCondition* GetCommitDeferringConditionForTesting() override {
+    return nullptr;
+  }
   void set_url(const GURL& url) { url_ = url; }
   void set_previous_main_frame_url(const GURL& previous_main_frame_url) {
     previous_main_frame_url_ = previous_main_frame_url;
diff --git a/content/public/test/test_web_ui.cc b/content/public/test/test_web_ui.cc
index f97dc9e..d55b8248 100644
--- a/content/public/test/test_web_ui.cc
+++ b/content/public/test/test_web_ui.cc
@@ -27,14 +27,25 @@
 
 void TestWebUI::HandleReceivedMessage(const std::string& handler_name,
                                       const base::ListValue* args) {
-  const auto callbacks_map_it =
+  const auto callbacks_map_it = message_callbacks_.find(handler_name);
+  if (callbacks_map_it != message_callbacks_.end()) {
+    // Create a copy of the callbacks before running them. Without this, it
+    // could be possible for the callback's handler to register a new message
+    // handler during iteration of the vector, resulting in undefined behavior.
+    std::vector<MessageCallback> callbacks_to_run = callbacks_map_it->second;
+    for (auto& callback : callbacks_to_run)
+      callback.Run(args->GetList());
+    return;
+  }
+
+  const auto deprecated_callbacks_2_map_it =
       deprecated_message_callbacks_2_.find(handler_name);
-  if (callbacks_map_it != deprecated_message_callbacks_2_.end()) {
+  if (deprecated_callbacks_2_map_it != deprecated_message_callbacks_2_.end()) {
     // Create a copy of the callbacks before running them. Without this, it
     // could be possible for the callback's handler to register a new message
     // handler during iteration of the vector, resulting in undefined behavior.
     std::vector<DeprecatedMessageCallback2> callbacks_to_run =
-        callbacks_map_it->second;
+        deprecated_callbacks_2_map_it->second;
     for (auto& callback : callbacks_to_run)
       callback.Run(args->GetListDeprecated());
     return;
@@ -99,15 +110,23 @@
 }
 
 void TestWebUI::RegisterMessageCallback(base::StringPiece message,
-                                        DeprecatedMessageCallback2 callback) {
-  deprecated_message_callbacks_2_[std::string(message)].push_back(
+                                        MessageCallback callback) {
+  message_callbacks_[static_cast<std::string>(message)].push_back(
+      std::move(callback));
+}
+
+void TestWebUI::RegisterDeprecatedMessageCallback2(
+    base::StringPiece message,
+    DeprecatedMessageCallback2 callback) {
+  deprecated_message_callbacks_2_[static_cast<std::string>(message)].push_back(
       std::move(callback));
 }
 
 void TestWebUI::RegisterDeprecatedMessageCallback(
     base::StringPiece message,
     const DeprecatedMessageCallback& callback) {
-  deprecated_message_callbacks_[std::string(message)].push_back(callback);
+  deprecated_message_callbacks_[static_cast<std::string>(message)].push_back(
+      callback);
 }
 
 bool TestWebUI::CanCallJavascript() {
diff --git a/content/public/test/test_web_ui.h b/content/public/test/test_web_ui.h
index a33cc9a..5db8140 100644
--- a/content/public/test/test_web_ui.h
+++ b/content/public/test/test_web_ui.h
@@ -48,7 +48,10 @@
   void AddRequestableScheme(const char* scheme) override;
   void AddMessageHandler(std::unique_ptr<WebUIMessageHandler> handler) override;
   void RegisterMessageCallback(base::StringPiece message,
-                               DeprecatedMessageCallback2 callback) override;
+                               MessageCallback callback) override;
+  void RegisterDeprecatedMessageCallback2(
+      base::StringPiece message,
+      DeprecatedMessageCallback2 callback) override;
   void RegisterDeprecatedMessageCallback(
       base::StringPiece message,
       const DeprecatedMessageCallback& callback) override;
@@ -122,6 +125,7 @@
  private:
   void OnJavascriptCall(const CallData& call_data);
 
+  base::flat_map<std::string, std::vector<MessageCallback>> message_callbacks_;
   base::flat_map<std::string, std::vector<DeprecatedMessageCallback2>>
       deprecated_message_callbacks_2_;
   base::flat_map<std::string, std::vector<DeprecatedMessageCallback>>
diff --git a/content/renderer/accessibility/ax_image_annotator.cc b/content/renderer/accessibility/ax_image_annotator.cc
index dbcc7c4..737361e 100644
--- a/content/renderer/accessibility/ax_image_annotator.cc
+++ b/content/renderer/accessibility/ax_image_annotator.cc
@@ -18,8 +18,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "content/public/common/content_client.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/accessibility/ax_image_stopwords.h"
-#include "content/renderer/render_frame_impl.h"
 #include "crypto/sha2.h"
 #include "services/metrics/public/cpp/mojo_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
diff --git a/content/renderer/browser_exposed_renderer_interfaces.cc b/content/renderer/browser_exposed_renderer_interfaces.cc
index 02a05d0..f115fdf 100644
--- a/content/renderer/browser_exposed_renderer_interfaces.cc
+++ b/content/renderer/browser_exposed_renderer_interfaces.cc
@@ -23,7 +23,6 @@
 #include "content/public/common/resource_usage_reporter.mojom.h"
 #include "content/public/common/resource_usage_reporter_type_converters.h"
 #include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/render_frame_impl.h"
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
 #include "content/renderer/worker/shared_worker_factory_impl.h"
diff --git a/content/renderer/dom_automation_controller.cc b/content/renderer/dom_automation_controller.cc
index 1c09f3fb..06f752a6 100644
--- a/content/renderer/dom_automation_controller.cc
+++ b/content/renderer/dom_automation_controller.cc
@@ -6,11 +6,12 @@
 
 #include "base/json/json_string_value_serializer.h"
 #include "base/strings/string_util.h"
-#include "content/renderer/render_frame_impl.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/v8_value_converter_impl.h"
 #include "gin/handle.h"
 #include "gin/object_template_builder.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc
index f032a93..1bf3478 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -17,7 +17,6 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
-#include "content/renderer/render_frame_impl.h"
 #include "media/base/audio_timestamp_helper.h"
 #include "media/base/limits.h"
 #include "media/base/silent_sink_suspender.h"
diff --git a/content/renderer/pepper/host_dispatcher_wrapper.cc b/content/renderer/pepper/host_dispatcher_wrapper.cc
index bf877e5..dae3b38 100644
--- a/content/renderer/pepper/host_dispatcher_wrapper.cc
+++ b/content/renderer/pepper/host_dispatcher_wrapper.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "build/build_config.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/pepper/pepper_browser_connection.h"
 #include "content/renderer/pepper/pepper_hung_plugin_filter.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
@@ -14,7 +15,6 @@
 #include "content/renderer/pepper/plugin_module.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
 #include "content/renderer/pepper/renderer_restrict_dispatch_group.h"
-#include "content/renderer/render_frame_impl.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_plugin_container.h"
diff --git a/content/renderer/pepper/pepper_audio_controller.cc b/content/renderer/pepper/pepper_audio_controller.cc
index 5daa189f..73fc62c 100644
--- a/content/renderer/pepper/pepper_audio_controller.cc
+++ b/content/renderer/pepper/pepper_audio_controller.cc
@@ -7,7 +7,6 @@
 #include "content/renderer/pepper/pepper_audio_output_host.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/ppb_audio_impl.h"
-#include "content/renderer/render_frame_impl.h"
 
 namespace content {
 
diff --git a/content/renderer/pepper/pepper_audio_input_host.cc b/content/renderer/pepper/pepper_audio_input_host.cc
index 6e183116..1993a7e 100644
--- a/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/content/renderer/pepper/pepper_audio_input_host.cc
@@ -7,11 +7,11 @@
 #include "base/notreached.h"
 #include "build/build_config.h"
 #include "content/common/pepper_file_util.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/pepper/pepper_media_device_manager.h"
 #include "content/renderer/pepper/pepper_platform_audio_input.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_frame_impl.h"
 #include "ipc/ipc_message.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
diff --git a/content/renderer/pepper/pepper_audio_output_host.cc b/content/renderer/pepper/pepper_audio_output_host.cc
index 46cff19..032c6ac 100644
--- a/content/renderer/pepper/pepper_audio_output_host.cc
+++ b/content/renderer/pepper/pepper_audio_output_host.cc
@@ -8,12 +8,12 @@
 #include "base/notreached.h"
 #include "build/build_config.h"
 #include "content/common/pepper_file_util.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/pepper/pepper_audio_controller.h"
 #include "content/renderer/pepper/pepper_media_device_manager.h"
 #include "content/renderer/pepper/pepper_platform_audio_output_dev.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_frame_impl.h"
 #include "ipc/ipc_message.h"
 #include "ppapi/c/pp_errors.h"
 #include "ppapi/host/dispatch_host_message.h"
diff --git a/content/renderer/pepper/pepper_camera_device_host.cc b/content/renderer/pepper/pepper_camera_device_host.cc
index 48c40b4..a4d51ec9 100644
--- a/content/renderer/pepper/pepper_camera_device_host.cc
+++ b/content/renderer/pepper/pepper_camera_device_host.cc
@@ -6,9 +6,9 @@
 
 #include <memory>
 
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/pepper/pepper_platform_camera_device.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_frame_impl.h"
 #include "ppapi/host/dispatch_host_message.h"
 #include "ppapi/proxy/ppapi_messages.h"
 
diff --git a/content/renderer/pepper/pepper_in_process_router.cc b/content/renderer/pepper/pepper_in_process_router.cc
index fb76e18..734d6ed8 100644
--- a/content/renderer/pepper/pepper_in_process_router.cc
+++ b/content/renderer/pepper/pepper_in_process_router.cc
@@ -10,9 +10,9 @@
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_frame_impl.h"
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_sender.h"
 #include "ppapi/proxy/ppapi_messages.h"
diff --git a/content/renderer/pepper/pepper_video_capture_host.cc b/content/renderer/pepper/pepper_video_capture_host.cc
index a53d27a8..7574d4f 100644
--- a/content/renderer/pepper/pepper_video_capture_host.cc
+++ b/content/renderer/pepper/pepper_video_capture_host.cc
@@ -7,12 +7,12 @@
 #include <memory>
 
 #include "base/cxx17_backports.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/renderer/pepper/host_globals.h"
 #include "content/renderer/pepper/pepper_media_device_manager.h"
 #include "content/renderer/pepper/pepper_platform_video_capture.h"
 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "content/renderer/render_frame_impl.h"
 #include "media/base/limits.h"
 #include "media/base/video_frame.h"
 #include "media/base/video_util.h"
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 678fa48b..2284f1c8 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -704,8 +704,8 @@
   }
 }
 
-# Fuchsia gpu integration tests use web_engine and a browser like shell
-# instead of an actual browser, so Fuchsia needs a separate target.
+# Fuchsia gpu integration tests on smart displays use web_engine and a browser
+# like shell instead of an actual browser, so Fuchsia needs a separate target.
 if (is_fuchsia) {
   group("fuchsia_telemetry_gpu_integration_test") {
     testonly = true
@@ -731,6 +731,7 @@
     testonly = true
     data = [ "//content/test/gpu/fuchsia_util.py" ]
     data_deps = [
+      "//chrome/app:chrome_fuchsia",
       "//fuchsia/engine:web_engine_shell",
       "//fuchsia/engine:web_engine_with_webui_installer",
     ]
diff --git a/content/test/attribution_simulator_impl.cc b/content/test/attribution_simulator_impl.cc
index d30ff788..e2259df0 100644
--- a/content/test/attribution_simulator_impl.cc
+++ b/content/test/attribution_simulator_impl.cc
@@ -100,6 +100,12 @@
   // AttributionManagerImpl::NetworkSender:
   void SendReport(AttributionReport report,
                   ReportSentCallback sent_callback) override {
+    // TODO(linnan): Support aggregatable reports in the simulator.
+    if (!absl::holds_alternative<AttributionReport::EventLevelData>(
+            report.data())) {
+      return;
+    }
+
     base::Value report_body = report.ReportBody();
     if (remove_report_ids_)
       report_body.RemoveKey("report_id");
diff --git a/content/test/attribution_simulator_input_parser.cc b/content/test/attribution_simulator_input_parser.cc
index e2bc110..5a699fc 100644
--- a/content/test/attribution_simulator_input_parser.cc
+++ b/content/test/attribution_simulator_input_parser.cc
@@ -155,7 +155,8 @@
     uint64_t event_source_trigger_data =
         ParseOptionalUint64(*cfg, "event_source_trigger_data").value_or(0);
     absl::optional<uint64_t> debug_key = ParseOptionalUint64(*cfg, "debug_key");
-    absl::optional<uint64_t> dedup_key = ParseOptionalUint64(*cfg, "dedup_key");
+    absl::optional<uint64_t> dedup_key =
+        ParseOptionalUint64(*cfg, "deduplication_key");
     int64_t priority = ParseOptionalInt64(*cfg, "priority").value_or(0);
 
     if (has_error_)
@@ -163,13 +164,10 @@
 
     events_.emplace_back(
         AttributionTriggerAndTime{
-            .trigger = AttributionTrigger(
-                SanitizeTriggerData(trigger_data,
-                                    CommonSourceInfo::SourceType::kNavigation),
-                std::move(destination), std::move(reporting_origin),
-                SanitizeTriggerData(event_source_trigger_data,
-                                    CommonSourceInfo::SourceType::kEvent),
-                priority, dedup_key, debug_key),
+            .trigger = AttributionTrigger(trigger_data, std::move(destination),
+                                          std::move(reporting_origin),
+                                          event_source_trigger_data, priority,
+                                          dedup_key, debug_key),
             .time = trigger_time,
         },
         std::move(trigger));
diff --git a/content/test/attribution_simulator_input_parser_unittest.cc b/content/test/attribution_simulator_input_parser_unittest.cc
index 46cbb46..4b9bc4d 100644
--- a/content/test/attribution_simulator_input_parser_unittest.cc
+++ b/content/test/attribution_simulator_input_parser_unittest.cc
@@ -163,7 +163,7 @@
         "trigger_data": "10",
         "event_source_trigger_data": "3",
         "priority": "-5",
-        "dedup_key": "123",
+        "deduplication_key": "123",
         "debug_key": "14"
       }
     },
@@ -189,8 +189,8 @@
                               url::Origin::Create(GURL("https://a.r.test")))
                           .SetConversionDestination(net::SchemefulSite(
                               url::Origin::Create(GURL("https://a.d1.test"))))
-                          .SetTriggerData(2)             // sanitized to 3 bits
-                          .SetEventSourceTriggerData(1)  // sanitized to 1 bit
+                          .SetTriggerData(10)
+                          .SetEventSourceTriggerData(3)
                           .SetPriority(-5)
                           .SetDedupKey(123)
                           .SetDebugKey(14)
diff --git a/content/test/data/accessibility/aria/aria-mismatched-table-attr-expected-uia-win.txt b/content/test/data/accessibility/aria/aria-mismatched-table-attr-expected-uia-win.txt
index 054fa6e4..50ce513a 100644
--- a/content/test/data/accessibility/aria/aria-mismatched-table-attr-expected-uia-win.txt
+++ b/content/test/data/accessibility/aria/aria-mismatched-table-attr-expected-uia-win.txt
@@ -1,18 +1,18 @@
 Document
 ++DataGrid Grid.ColumnCount=3 Grid.RowCount=3 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Column 1' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Column 1' IsControlElement=false
 ++++++DataItem Name='Column 2' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Column 2' IsControlElement=false
 ++++++DataItem Name='Column 3' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Column 3' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Cell A2' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Cell A2' IsControlElement=false
 ++++++DataItem Name='Cell A3' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Cell A3' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Cell B1' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++Text Name='Cell B1' IsControlElement=false
 ++++++DataItem Name='Cell B2' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/aria/table-column-hidden-expected-uia-win.txt b/content/test/data/accessibility/aria/table-column-hidden-expected-uia-win.txt
index d4ff0a97..c6ed12d 100644
--- a/content/test/data/accessibility/aria/table-column-hidden-expected-uia-win.txt
+++ b/content/test/data/accessibility/aria/table-column-hidden-expected-uia-win.txt
@@ -1,20 +1,20 @@
 Document
 ++DataGrid Grid.ColumnCount=5 Grid.RowCount=4 Selection.CanSelectMultiple=false Selection.IsSelectionRequired=false Table.RowOrColumnMajor='RowMajor'
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Month' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Month' IsControlElement=false
 ++++++DataItem Name='Day' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Day' IsControlElement=false
 ++++++DataItem Name='Weather' GridItem.Column=4 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Weather' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='January' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++Text Name='January' IsControlElement=false
 ++++++DataItem Name='01' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++Text Name='01' IsControlElement=false
 ++++++DataItem Name='Sunny' GridItem.Column=4 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++Text Name='Sunny' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='January' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
 ++++++++Text Name='January' IsControlElement=false
 ++++++DataItem Name='02' GridItem.Column=2 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/event/add-alert-content-expected-uia-win.txt b/content/test/data/accessibility/event/add-alert-content-expected-uia-win.txt
index 6b9e6fa..2aa360ca 100644
--- a/content/test/data/accessibility/event/add-alert-content-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/add-alert-content-expected-uia-win.txt
@@ -1,14 +1,5 @@
-LiveRegionChanged on role=alert, name=Bar
-LiveRegionChanged on role=alert, name=Baz
-LiveRegionChanged on role=alert, name=Foo
 LiveRegionChanged on role=alert, name=Foo
 === Start Continuation ===
 LiveRegionChanged on role=alert, name=Bar
-LiveRegionChanged on role=alert, name=Bar
-LiveRegionChanged on role=alert, name=Baz
-LiveRegionChanged on role=alert, name=Foo
 === Start Continuation ===
-LiveRegionChanged on role=alert, name=Bar
 LiveRegionChanged on role=alert, name=Baz
-LiveRegionChanged on role=alert, name=Baz
-LiveRegionChanged on role=alert, name=Foo
diff --git a/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt b/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt
index 8d033423..d377859b 100644
--- a/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt
+++ b/content/test/data/accessibility/event/live-region-change-expected-uia-win.txt
@@ -1,3 +1,2 @@
 LiveRegionChanged on role=group
-LiveRegionChanged on role=group
 Text_TextChanged on role=description, name=After
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
index 123eab8..e4850bb8 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-expected-uia-win.txt
@@ -10,7 +10,7 @@
 ++++++Button Name='Button'
 ++++++Text Name='.'
 ++++Table Grid.ColumnCount=1 Grid.RowCount=1 Table.RowOrColumnMajor='RowMajor'
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='Always expose editable tables as tables.' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++Text Name='Always expose editable tables as tables.' IsControlElement=false
 ++++List
diff --git a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
index 62c325c..62575a08 100644
--- a/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/contenteditable-descendants-with-selection-expected-uia-win.txt
@@ -10,7 +10,7 @@
 ++++++Button Name='Button'
 ++++++Text Name='.'
 ++++Table Grid.ColumnCount=1 Grid.RowCount=1 Table.RowOrColumnMajor='RowMajor'
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='Always expose editable tables as tables.' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++Text Name='Always expose editable tables as tables.' IsControlElement=false
 ++++List
diff --git a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
index 7710b401..cb461e17 100644
--- a/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-focusable-sections-expected-uia-win.txt
@@ -1,24 +1,24 @@
 Document Name='Table example - focusable thead, tbody, tfoot'
 ++Table Grid.ColumnCount=2 Grid.RowCount=4 Table.RowOrColumnMajor='RowMajor'
 ++++Group
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='Sum' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++Text Name='Sum' IsControlElement=false
 ++++++++DataItem Name='Subtraction' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++++Text Name='Subtraction' IsControlElement=false
 ++++Group
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='10' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++++Text Name='10' IsControlElement=false
 ++++++++DataItem Name='7' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++++Text Name='7' IsControlElement=false
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='2' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++++Text Name='2' IsControlElement=false
 ++++++++DataItem Name='4' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=2 GridItem.RowSpan=1
 ++++++++++Text Name='4' IsControlElement=false
 ++++Group
-++++++DataItem IsControlElement=false
+++++++DataItem
 ++++++++DataItem Name='12' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
 ++++++++++Text Name='12' IsControlElement=false
 ++++++++DataItem Name='3' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=3 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
index 111b354..2a8e0d1 100644
--- a/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-th-colheader-expected-uia-win.txt
@@ -1,11 +1,11 @@
 Document
 ++Table Grid.ColumnCount=2 Grid.RowCount=2 Table.RowOrColumnMajor='RowMajor'
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Firstname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Firstname' IsControlElement=false
 ++++++DataItem Name='Lastname' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Lastname' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Jill' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Jill' IsControlElement=false
 ++++++DataItem Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
diff --git a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
index e6d6bee..57b240d 100644
--- a/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
+++ b/content/test/data/accessibility/html/table-th-rowheader-expected-uia-win.txt
@@ -1,11 +1,11 @@
 Document Name='Table example - th rowheader'
 ++Table Grid.ColumnCount=2 Grid.RowCount=2 Table.RowOrColumnMajor='RowMajor'
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Firstname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Firstname' IsControlElement=false
 ++++++DataItem Name='Jill' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=0 GridItem.RowSpan=1
 ++++++++Text Name='Jill' IsControlElement=false
-++++DataItem IsControlElement=false
+++++DataItem
 ++++++DataItem Name='Lastname' GridItem.Column=0 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
 ++++++++Text Name='Lastname' IsControlElement=false
 ++++++DataItem Name='Smith' GridItem.Column=1 GridItem.ColumnSpan=1 GridItem.Row=1 GridItem.RowSpan=1
diff --git a/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json b/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json
index 5111318..b619391 100644
--- a/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json
+++ b/content/test/data/attribution_reporting/simulator/rejected_triggers.input.json
@@ -26,7 +26,7 @@
       "destination": "https://d.test",
       "registration_config": {
         "trigger_data": "2",
-	"dedup_key": "22"
+	"deduplication_key": "22"
       }
     },
     {
@@ -35,7 +35,7 @@
       "destination": "https://d.test",
       "registration_config": {
         "trigger_data": "3",
-	"dedup_key": "22"
+	"deduplication_key": "22"
       }
     },
     {
diff --git a/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json b/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json
index a8a18f1..eea1d4d6 100644
--- a/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json
+++ b/content/test/data/attribution_reporting/simulator/rejected_triggers.output.json
@@ -19,7 +19,7 @@
         "destination": "https://d.test",
         "registration_config": {
           "trigger_data": "3",
-          "dedup_key": "22"
+          "deduplication_key": "22"
         }
       }
     },
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 213e5da..b5c5a5d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -333,7 +333,6 @@
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance/extensions/s3tc-and-rgtc.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance/extensions/webgl-compressed-texture-s3tc-srgb.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ]
-crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance/ogles/GL/build/build_017_to_024.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/sub.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal ] deqp/functional/gles3/fboinvalidate/whole.html [ Failure ]
@@ -410,8 +409,6 @@
 crbug.com/angleproject/6430 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/texturespecification/basic_copyteximage2d.html [ Failure ]
 crbug.com/angleproject/6430 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html [ Failure ]
 # Post Python 3 conversion: crbug.com/1266604
-# conformance/ogles/GL/* are too flaky to be retried.
-crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/ogles/GL/* [ Failure ]
 crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
 crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/clipping.html [ Failure ]
 crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] deqp/functional/gles3/fborender/shared_colorbuffer_00.html [ Failure ]
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 76e4755..b5da88a 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
@@ -517,7 +517,6 @@
 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/angleproject/6489 [ mac angle-metal passthrough ] conformance/ogles/GL/build/build_009_to_016.html [ Failure ]
-crbug.com/angleproject/6489 [ mac angle-metal passthrough ] conformance/ogles/GL/build/build_017_to_024.html [ Failure ]
 crbug.com/angleproject/6486 [ mac angle-metal passthrough ] conformance/glsl/misc/shader-with-non-reserved-words.html [ Failure ]
 
 # Mac / Passthrough command decoder / Metal / Intel
@@ -539,8 +538,6 @@
 # TODO(crbug.com/1276153) uncomment after fix for updated part of test applies
 # crbug.com/angleproject/5505 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
 crbug.com/angleproject/5505 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/rendering/multisample-corruption.html [ Failure ]
-# After converting to Python 3: crbug.com/1266604
-crbug.com/1271941 [ mac passthrough angle-metal apple-angle-metal-renderer:-apple-m1 ] conformance/ogles/GL/* [ RetryOnFailure ]
 
 ####################
 # Linux failures   #
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc
index e35af9f..a996e20 100644
--- a/content/web_test/renderer/test_runner.cc
+++ b/content/web_test/renderer/test_runner.cc
@@ -1025,7 +1025,7 @@
   if (invalid_)
     return;
   GetWebFrame()->AddInspectorIssue(
-      blink::mojom::InspectorIssueCode::kSameSiteCookieIssue);
+      blink::mojom::InspectorIssueCode::kCookieIssue);
 }
 
 bool TestRunnerBindings::IsCommandEnabled(const std::string& command) {
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index 2f676da..3b24454 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -11,7 +11,6 @@
 
 #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/task/single_thread_task_runner.h"
@@ -305,7 +304,7 @@
 TEST_F(EndToEndAsyncTest, EchoThreeTimes) {
   const char* kMessages[] = { "foo", "bar", "baz" };
 
-  for (size_t i = 0; i < base::size(kMessages); ++i) {
+  for (size_t i = 0; i < std::size(kMessages); ++i) {
     // Create the method call.
     MethodCall method_call("org.chromium.TestInterface", "Echo");
     MessageWriter writer(&method_call);
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc
index 871b76f..38c8b53 100644
--- a/dbus/property_unittest.cc
+++ b/dbus/property_unittest.cc
@@ -12,7 +12,6 @@
 #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/strings/string_number_conversions.h"
@@ -329,7 +328,7 @@
   writer.OpenVariant("a{ss}", &variant_writer);
   variant_writer.OpenArray("{ss}", &variant_array_writer);
   const char* items[] = {"One", "Two", "Three", "Four"};
-  for (unsigned i = 0; i < base::size(items); ++i) {
+  for (unsigned i = 0; i < std::size(items); ++i) {
     variant_array_writer.OpenDictEntry(&struct_entry_writer);
     struct_entry_writer.AppendString(items[i]);
     struct_entry_writer.AppendString(base::NumberToString(i + 1));
@@ -379,7 +378,7 @@
   for (uint16_t i = 0; i < 5; ++i) {
     variant_array_writer.OpenStruct(&struct_entry_writer);
     ip_bytes[4] = 0x30 + i;
-    struct_entry_writer.AppendArrayOfBytes(ip_bytes, base::size(ip_bytes));
+    struct_entry_writer.AppendArrayOfBytes(ip_bytes, std::size(ip_bytes));
     struct_entry_writer.AppendUint16(i);
     variant_array_writer.CloseContainer(&struct_entry_writer);
   }
@@ -407,7 +406,7 @@
   uint8_t ip_bytes[] = {0x54, 0x65, 0x73, 0x74, 0x30};
   for (uint16_t i = 0; i < 5; ++i) {
     ip_bytes[4] = 0x30 + i;
-    std::vector<uint8_t> bytes(ip_bytes, ip_bytes + base::size(ip_bytes));
+    std::vector<uint8_t> bytes(ip_bytes, ip_bytes + std::size(ip_bytes));
     test_list.push_back(make_pair(bytes, 16));
   }
 
@@ -434,7 +433,7 @@
 
   const char* keys[] = {"One", "Two", "Three", "Four"};
   const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
-  for (unsigned i = 0; i < base::size(keys); ++i) {
+  for (unsigned i = 0; i < std::size(keys); ++i) {
     MessageWriter entry_writer(nullptr);
     dict_writer.OpenDictEntry(&entry_writer);
 
@@ -455,8 +454,8 @@
   Property<std::map<std::string, std::vector<uint8_t>>> test_property;
   EXPECT_TRUE(test_property.PopValueFromReader(&reader));
 
-  ASSERT_EQ(base::size(keys), test_property.value().size());
-  for (unsigned i = 0; i < base::size(keys); ++i)
+  ASSERT_EQ(std::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < std::size(keys); ++i)
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
@@ -471,7 +470,7 @@
 
   const char* keys[] = {"One", "Two", "Three", "Four"};
   const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
-  for (unsigned i = 0; i < base::size(keys); ++i) {
+  for (unsigned i = 0; i < std::size(keys); ++i) {
     MessageWriter entry_writer(nullptr);
     dict_writer.OpenDictEntry(&entry_writer);
 
@@ -488,8 +487,8 @@
   Property<std::map<std::string, std::vector<uint8_t>>> test_property;
   EXPECT_TRUE(test_property.PopValueFromReader(&reader));
 
-  ASSERT_EQ(base::size(keys), test_property.value().size());
-  for (unsigned i = 0; i < base::size(keys); ++i)
+  ASSERT_EQ(std::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < std::size(keys); ++i)
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
@@ -522,7 +521,7 @@
 
   const uint16_t keys[] = {11, 12, 13, 14};
   const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
-  for (unsigned i = 0; i < base::size(keys); ++i) {
+  for (unsigned i = 0; i < std::size(keys); ++i) {
     MessageWriter entry_writer(nullptr);
     dict_writer.OpenDictEntry(&entry_writer);
 
@@ -543,8 +542,8 @@
   Property<std::map<uint16_t, std::vector<uint8_t>>> test_property;
   EXPECT_TRUE(test_property.PopValueFromReader(&reader));
 
-  ASSERT_EQ(base::size(keys), test_property.value().size());
-  for (unsigned i = 0; i < base::size(keys); ++i)
+  ASSERT_EQ(std::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < std::size(keys); ++i)
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
@@ -559,7 +558,7 @@
 
   const uint16_t keys[] = {11, 12, 13, 14};
   const std::vector<uint8_t> values[] = {{1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}};
-  for (unsigned i = 0; i < base::size(keys); ++i) {
+  for (unsigned i = 0; i < std::size(keys); ++i) {
     MessageWriter entry_writer(nullptr);
     dict_writer.OpenDictEntry(&entry_writer);
 
@@ -576,8 +575,8 @@
   Property<std::map<uint16_t, std::vector<uint8_t>>> test_property;
   EXPECT_TRUE(test_property.PopValueFromReader(&reader));
 
-  ASSERT_EQ(base::size(keys), test_property.value().size());
-  for (unsigned i = 0; i < base::size(keys); ++i)
+  ASSERT_EQ(std::size(keys), test_property.value().size());
+  for (unsigned i = 0; i < std::size(keys); ++i)
     EXPECT_EQ(values[i], test_property.value().at(keys[i]));
 }
 
diff --git a/dbus/values_util_unittest.cc b/dbus/values_util_unittest.cc
index 0b16a7d..a27b2510 100644
--- a/dbus/values_util_unittest.cc
+++ b/dbus/values_util_unittest.cc
@@ -12,7 +12,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_writer.h"
 #include "base/values.h"
 #include "dbus/message.h"
@@ -330,7 +329,7 @@
 TEST(ValuesUtilTest, PopDoubleToIntDictionary) {
   // Create test data.
   const int32_t kValues[] = {0, 1, 1, 2, 3, 5, 8, 13, 21};
-  const std::vector<int32_t> values(kValues, kValues + base::size(kValues));
+  const std::vector<int32_t> values(kValues, kValues + std::size(kValues));
   std::vector<double> keys(values.size());
   for (size_t i = 0; i != values.size(); ++i)
     keys[i] = std::sqrt(values[i]);
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md
index 70a161e..6cc429f7 100644
--- a/docs/adding_to_third_party.md
+++ b/docs/adding_to_third_party.md
@@ -21,10 +21,14 @@
 ## Before you start
 
 To make sure the inclusion of a new third_party project makes sense for the
-Chromium project, you should first obtain Chrome Eng Review approval.
-Googlers should see go/chrome-eng-review and review existing topics in
-g/chrome-eng-review. Please include information about the additional checkout
-size, build times, and binary size increase of
+Chromium project, you should first obtain
+[Chrome Eng Review](../ENG_REVIEW_OWNERS) approval. Googlers should see
+[go/chrome-eng-review](https://goto.google.com/chrome-eng-review) and review
+existing topics in g/chrome-eng-review, and can also come to office hours to ask
+questions.
+
+Please include information about the additional checkout size, build times,
+and binary size increase of
 [official](https://www.chromium.org/developers/gn-build-configuration) builds
 on Android and one desktop platform. Please also make sure that the motivation
 for your project is clear, e.g., a design doc has been circulated.
diff --git a/docs/android_build_instructions.md b/docs/android_build_instructions.md
index 734cd7e..1a6cc66 100644
--- a/docs/android_build_instructions.md
+++ b/docs/android_build_instructions.md
@@ -419,9 +419,9 @@
 incremental_install = true
 ```
 
-Some APKs (e.g. WebView) do not work with incremental install, and are
-blacklisted from being built as such (via `never_incremental = true`), so are
-build as normal APKs even when `incremental_install = true`.
+Some APKs (e.g. WebView) do not work with `incremental install = true` and are
+always built as normal APKs. This behavior is controlled via
+`never_incremental = true`.
 
 ## Installing and Running Chromium on an Emulator
 
diff --git a/docs/webui_explainer.md b/docs/webui_explainer.md
index a3b010da..ddbed2e 100644
--- a/docs/webui_explainer.md
+++ b/docs/webui_explainer.md
@@ -258,7 +258,7 @@
                           base::Unretained(this)));
 }
 
-void OvenHandler::HandleBakeDonuts(base::Value::ConstListView args) {
+void OvenHandler::HandleBakeDonuts(const base::Value::List& args) {
   AllowJavascript();
 
   // IMPORTANT: Fully validate `args`.
diff --git a/extensions/browser/api/alarms/alarms_api_unittest.cc b/extensions/browser/api/alarms/alarms_api_unittest.cc
index 8eb2625..abf261f70 100644
--- a/extensions/browser/api/alarms/alarms_api_unittest.cc
+++ b/extensions/browser/api/alarms/alarms_api_unittest.cc
@@ -4,6 +4,8 @@
 
 // This file tests the chrome.alarms extension API.
 
+#include "extensions/browser/api/alarms/alarms_api.h"
+
 #include <stddef.h>
 
 #include <memory>
@@ -11,7 +13,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -20,7 +21,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/fake_local_frame.h"
 #include "extensions/browser/api/alarms/alarm_manager.h"
-#include "extensions/browser/api/alarms/alarms_api.h"
 #include "extensions/browser/api/alarms/alarms_api_constants.h"
 #include "extensions/browser/api_unittest.h"
 #include "extensions/common/extension_builder.h"
@@ -695,7 +695,7 @@
   };
 
   // Test once for unpacked and once for crx extension.
-  for (size_t i = 0; i < base::size(test_data); ++i) {
+  for (size_t i = 0; i < std::size(test_data); ++i) {
     test_clock_.SetNow(base::Time::FromDoubleT(10));
 
     // Mimic retrieving an alarm from StateStore.
diff --git a/extensions/browser/api/app_window/app_window_api.cc b/extensions/browser/api/app_window/app_window_api.cc
index 3696fb7..fc589a8a 100644
--- a/extensions/browser/api/app_window/app_window_api.cc
+++ b/extensions/browser/api/app_window/app_window_api.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
@@ -286,7 +285,7 @@
       };
       if (AppWindowClient::Get()->IsCurrentChannelOlderThanDev() &&
           !SimpleFeature::IsIdInArray(extension_id(), kAllowlist,
-                                      base::size(kAllowlist))) {
+                                      std::size(kAllowlist))) {
         return RespondNow(
             Error(app_window_constants::kAlphaEnabledWrongChannel));
       }
diff --git a/extensions/browser/api/content_settings/content_settings_unittest.cc b/extensions/browser/api/content_settings/content_settings_unittest.cc
index b8bdd58..a4469dd 100644
--- a/extensions/browser/api/content_settings/content_settings_unittest.cc
+++ b/extensions/browser/api/content_settings/content_settings_unittest.cc
@@ -4,7 +4,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "extensions/browser/api/content_settings/content_settings_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -24,7 +23,7 @@
     { "https://*/*", "https://*" },
     { "file:///foo/bar/baz", "file:///foo/bar/baz" },
   };
-  for (size_t i = 0; i < base::size(kTestPatterns); ++i) {
+  for (size_t i = 0; i < std::size(kTestPatterns); ++i) {
     std::string error;
     std::string pattern_str = helpers::ParseExtensionPattern(
         kTestPatterns[i].extension_pattern, &error).ToString();
@@ -41,7 +40,7 @@
     { "file:///foo/bar/*",
       "Path wildcards in file URL patterns are not allowed." },
   };
-  for (size_t i = 0; i < base::size(kInvalidTestPatterns); ++i) {
+  for (size_t i = 0; i < std::size(kInvalidTestPatterns); ++i) {
     std::string error;
     ContentSettingsPattern pattern = helpers::ParseExtensionPattern(
         kInvalidTestPatterns[i].extension_pattern, &error);
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
index b6dea67..af05d12 100644
--- a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
+++ b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
@@ -524,7 +524,7 @@
       {"http://nomatch.com", PageAccess::kWithheld, false, absl::nullopt},
   };
 
-  for (size_t i = 0; i < base::size(cases); i++) {
+  for (size_t i = 0; i < std::size(cases); i++) {
     SCOPED_TRACE(base::StringPrintf("Testing case %zu", i));
 
     GURL url(cases[i].url);
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule.cc b/extensions/browser/api/declarative_net_request/indexed_rule.cc
index 62ca5bd..40669d9 100644
--- a/extensions/browser/api/declarative_net_request/indexed_rule.cc
+++ b/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -9,7 +9,6 @@
 
 #include "base/check_op.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
@@ -363,7 +362,7 @@
   if (!scheme)
     return true;
 
-  for (size_t i = 0; i < base::size(kAllowedTransformSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kAllowedTransformSchemes); ++i) {
     if (*scheme == kAllowedTransformSchemes[i])
       return true;
   }
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
index babd5d4..32fb9ff 100644
--- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
+++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/containers/flat_set.h"
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/json/json_reader.h"
 #include "base/numerics/safe_conversions.h"
@@ -60,7 +59,7 @@
       {kMinValidID, ParseResult::SUCCESS},
       {kMinValidID + 1, ParseResult::SUCCESS},
   };
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.id = cases[i].id;
@@ -108,7 +107,7 @@
        kMinValidPriority},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.priority = std::move(cases[i].priority);
@@ -151,7 +150,7 @@
            flat_rule::OptionFlag_IS_CASE_INSENSITIVE},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.condition.domain_type = cases[i].domain_type;
@@ -217,7 +216,7 @@
        ParseResult::SUCCESS, flat_rule::ElementType_SCRIPT},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.condition.resource_types = std::move(cases[i].resource_types);
@@ -291,7 +290,7 @@
        flat_rule::UrlPatternType_WILDCARDED, flat_rule::AnchorType_SUBDOMAIN,
        flat_rule::AnchorType_NONE, "", ParseResult::ERROR_INVALID_URL_FILTER}};
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.condition.url_filter = std::move(cases[i].input_url_filter);
@@ -380,7 +379,7 @@
        {}},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule initiator_domains_rule = CreateGenericParsedRule();
     dnr_api::Rule request_domains_rule = CreateGenericParsedRule();
@@ -460,7 +459,7 @@
       {"/relative/url?q=1", ParseResult::ERROR_INVALID_REDIRECT_URL, ""},
       {"abc", ParseResult::ERROR_INVALID_REDIRECT_URL, ""}};
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.action.redirect = MakeRedirectUrl(cases[i].redirect_url);
@@ -598,7 +597,7 @@
   };
   // clang-format on
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.action.type = dnr_api::RULE_ACTION_TYPE_REDIRECT;
@@ -785,7 +784,7 @@
        flat_rule::ElementType_MAIN_FRAME},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
 
@@ -891,7 +890,7 @@
        ParseResult::SUCCESS},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.action.type = dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS;
@@ -975,7 +974,7 @@
        ParseResult::ERROR_EMPTY_REQUEST_METHODS_LIST,
        flat_rule::RequestMethod_NONE}};
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     rule.condition.request_methods = std::move(cases[i].request_methods);
@@ -1028,7 +1027,7 @@
        ParseResult::ERROR_TAB_IDS_ON_NON_SESSION_RULE},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
     dnr_api::Rule rule = CreateGenericParsedRule();
     if (cases[i].tab_ids) {
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
index 38849fc..31053b9 100644
--- a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
+++ b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
@@ -769,7 +769,7 @@
     test_cases.push_back(std::move(test_case));
   }
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Case number-%" PRIuS " url-%s", i,
                                     test_cases[i].url));
 
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index 0d19166..9bee8c5 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h"
 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
@@ -160,7 +159,7 @@
 
   // Check that exactly all active stages are considered in this test.
   unsigned int covered_stages = 0;
-  for (size_t i = 0; i < base::size(active_stages); ++i)
+  for (size_t i = 0; i < std::size(active_stages); ++i)
     covered_stages |= active_stages[i].first;
   EXPECT_EQ(kActiveStages, covered_stages);
 
@@ -178,7 +177,7 @@
 
   // Create an attribute with all possible applicable stages.
   base::Value all_stages(base::Value::Type::LIST);
-  for (size_t i = 0; i < base::size(active_stages); ++i)
+  for (size_t i = 0; i < std::size(active_stages); ++i)
     all_stages.Append(active_stages[i].second);
   scoped_refptr<const WebRequestConditionAttribute> attribute_with_all =
       WebRequestConditionAttribute::Create(keys::kStagesKey,
@@ -192,7 +191,7 @@
   std::vector<scoped_refptr<const WebRequestConditionAttribute> >
       one_stage_attributes;
 
-  for (size_t i = 0; i < base::size(active_stages); ++i) {
+  for (size_t i = 0; i < std::size(active_stages); ++i) {
     base::Value single_stage_list(base::Value::Type::LIST);
     single_stage_list.Append(active_stages[i].second);
     one_stage_attributes.push_back(
@@ -205,7 +204,7 @@
 
   WebRequestInfo request_info(WebRequestInfoInitParams{});
 
-  for (size_t i = 0; i < base::size(active_stages); ++i) {
+  for (size_t i = 0; i < std::size(active_stages); ++i) {
     EXPECT_FALSE(empty_attribute->IsFulfilled(
         WebRequestData(&request_info, active_stages[i].first)));
 
@@ -332,7 +331,7 @@
     keys::kValueSuffixKey, "alue",
     keys::kValuePrefixKey, "custom/value"
   };
-  const size_t kPassingConditionSizes[] = {base::size(kPassingCondition)};
+  const size_t kPassingConditionSizes[] = {std::size(kPassingCondition)};
   GetArrayAsVector(kPassingCondition, kPassingConditionSizes, 1u, &tests);
   // Positive filter, passing (conjunction of tests).
   MatchAndCheck(tests, keys::kRequestHeadersKey, stage, request_info, &result);
@@ -419,7 +418,7 @@
     keys::kValueContainsKey, "alu",
     keys::kValueEqualsKey, "custom/value"
   };
-  const size_t kPassingConditionSizes[] = {base::size(kPassingCondition)};
+  const size_t kPassingConditionSizes[] = {std::size(kPassingCondition)};
   GetArrayAsVector(kPassingCondition, kPassingConditionSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -441,7 +440,7 @@
     keys::kNameSuffixKey, "Header-B",
     keys::kValueEqualsKey, "custom/value"
   };
-  const size_t kMixingConditionSizes[] = {base::size(kMixingCondition)};
+  const size_t kMixingConditionSizes[] = {std::size(kMixingCondition)};
   GetArrayAsVector(kMixingCondition, kMixingConditionSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_FALSE(result);
@@ -451,7 +450,7 @@
     keys::kNameEqualsKey, "Custom-header-b",
     keys::kValueEqualsKey, "valueA"
   };
-  const size_t kMoreValues1Sizes[] = {base::size(kMoreValues1)};
+  const size_t kMoreValues1Sizes[] = {std::size(kMoreValues1)};
   GetArrayAsVector(kMoreValues1, kMoreValues1Sizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -459,7 +458,7 @@
     keys::kNameEqualsKey, "Custom-header-b",
     keys::kValueEqualsKey, "valueB"
   };
-  const size_t kMoreValues2Sizes[] = {base::size(kMoreValues2)};
+  const size_t kMoreValues2Sizes[] = {std::size(kMoreValues2)};
   GetArrayAsVector(kMoreValues2, kMoreValues2Sizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -475,7 +474,7 @@
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
   // Then conjunction, conflict.
-  const size_t kConflictSizes[] = {base::size(kConflict)};
+  const size_t kConflictSizes[] = {std::size(kConflict)};
   GetArrayAsVector(kConflict, kConflictSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_FALSE(result);
@@ -485,7 +484,7 @@
     keys::kNameSuffixKey, "Header-C",
     keys::kValueEqualsKey, "valueC, valueD"
   };
-  const size_t kCommaSizes[] = {base::size(kComma)};
+  const size_t kCommaSizes[] = {std::size(kComma)};
   GetArrayAsVector(kComma, kCommaSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -495,7 +494,7 @@
     keys::kNameEqualsKey, "custom-header-d",
     keys::kValueEqualsKey, ""
   };
-  const size_t kEmptySizes[] = {base::size(kEmpty)};
+  const size_t kEmptySizes[] = {std::size(kEmpty)};
   GetArrayAsVector(kEmpty, kEmptySizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -523,7 +522,7 @@
     keys::kNameEqualsKey, "CUSTOM-HEADER-B",
     keys::kNameContainsKey, "CUSTOM-HEADER-B"
   };
-  const size_t kUppercaseSizes[] = {base::size(kUppercase)};  // Conjunction.
+  const size_t kUppercaseSizes[] = {std::size(kUppercase)};  // Conjunction.
   GetArrayAsVector(kUppercase, kUppercaseSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kResponseHeadersKey, stage, request_info, &result);
   EXPECT_TRUE(result);
@@ -545,7 +544,7 @@
     keys::kNameEqualsKey, "Non-existing",
     keys::kValueEqualsKey, "void"
   };
-  const size_t kNonExistentSizes[] = {base::size(kNonExistent)};
+  const size_t kNonExistentSizes[] = {std::size(kNonExistent)};
   GetArrayAsVector(kNonExistent, kNonExistentSizes, 1u, &tests);
   MatchAndCheck(tests, keys::kExcludeResponseHeadersKey, stage, request_info,
                 &result);
@@ -556,7 +555,7 @@
     keys::kNameEqualsKey, "custom-header-b",
     keys::kValueEqualsKey, "valueB"
   };
-  const size_t kExistingSize[] = {base::size(kExisting)};
+  const size_t kExistingSize[] = {std::size(kExisting)};
   GetArrayAsVector(kExisting, kExistingSize, 1u, &tests);
   MatchAndCheck(tests, keys::kExcludeResponseHeadersKey, stage, request_info,
                 &result);
@@ -582,7 +581,7 @@
   bool result;
   const RequestStage stage = ON_HEADERS_RECEIVED;
   const std::string kCondition[] = {keys::kValueEqualsKey, "custom/value"};
-  const size_t kConditionSizes[] = {base::size(kCondition)};
+  const size_t kConditionSizes[] = {std::size(kCondition)};
   GetArrayAsVector(kCondition, kConditionSizes, 1u, &tests);
 
   {
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.cc b/extensions/browser/api/feedback_private/feedback_private_api.cc
index 341ab8b..c7049053 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api.cc
+++ b/extensions/browser/api/feedback_private/feedback_private_api.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/memory/weak_ptr.h"
 #include "base/metrics/histogram_base.h"
@@ -71,7 +70,7 @@
   constexpr char kFakePathStr[] = "C:\\fakepath\\";
   if (base::StartsWith(path, kFakePathStr,
                        base::CompareCase::INSENSITIVE_ASCII))
-    return path.substr(base::size(kFakePathStr) - 1);
+    return path.substr(std::size(kFakePathStr) - 1);
   return path;
 }
 
diff --git a/extensions/browser/api/file_system/file_system_api.cc b/extensions/browser/api/file_system/file_system_api.cc
index fdda80a7..c96e205 100644
--- a/extensions/browser/api/file_system/file_system_api.cc
+++ b/extensions/browser/api/file_system/file_system_api.cc
@@ -14,7 +14,6 @@
 
 #include "base/bind.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/values_util.h"
@@ -612,7 +611,7 @@
     return;
   }
 
-  for (size_t i = 0; i < base::size(kGraylistedPaths); i++) {
+  for (size_t i = 0; i < std::size(kGraylistedPaths); i++) {
     base::FilePath graylisted_path;
     if (!base::PathService::Get(kGraylistedPaths[i], &graylisted_path))
       continue;
diff --git a/extensions/browser/api/networking_private/networking_private_api.cc b/extensions/browser/api/networking_private/networking_private_api.cc
index 2593823f..8f4c6e4db 100644
--- a/extensions/browser/api/networking_private/networking_private_api.cc
+++ b/extensions/browser/api/networking_private/networking_private_api.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
@@ -81,10 +80,10 @@
   size_t filter_size = 0;
   if (type == PropertiesType::GET) {
     filter = kPrivatePropertyPathsForGet;
-    filter_size = base::size(kPrivatePropertyPathsForGet);
+    filter_size = std::size(kPrivatePropertyPathsForGet);
   } else {
     filter = kPrivatePropertyPathsForSet;
-    filter_size = base::size(kPrivatePropertyPathsForSet);
+    filter_size = std::size(kPrivatePropertyPathsForSet);
   }
 
   std::vector<std::string> removed_properties;
diff --git a/extensions/browser/api/storage/storage_frontend.cc b/extensions/browser/api/storage/storage_frontend.cc
index 34a7b1634..1ebd2137 100644
--- a/extensions/browser/api/storage/storage_frontend.cc
+++ b/extensions/browser/api/storage/storage_frontend.cc
@@ -76,7 +76,7 @@
     constexpr size_t kExtensionsIdLength = 32;
     char extension_id_str[kExtensionsIdLength + 1];
     base::strlcpy(extension_id_str, extension_id.c_str(),
-                  base::size(extension_id_str));
+                  std::size(extension_id_str));
     base::debug::Alias(extension_id_str);
 
     const std::string namespace_string = StorageAreaToString(storage_area);
diff --git a/extensions/browser/api/system_storage/system_storage_apitest.cc b/extensions/browser/api/system_storage/system_storage_apitest.cc
index fff356d..27f3acbf 100644
--- a/extensions/browser/api/system_storage/system_storage_apitest.cc
+++ b/extensions/browser/api/system_storage/system_storage_apitest.cc
@@ -7,7 +7,6 @@
 #include <atomic>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
@@ -102,7 +101,7 @@
   }
 
   void SetUpAllMockStorageDevices() {
-    for (size_t i = 0; i < base::size(kTestingData); ++i) {
+    for (size_t i = 0; i < std::size(kTestingData); ++i) {
       AttachRemovableStorage(kTestingData[i]);
     }
   }
@@ -122,7 +121,7 @@
 IN_PROC_BROWSER_TEST_F(SystemStorageApiTest, Storage) {
   SetUpAllMockStorageDevices();
   auto provider = base::MakeRefCounted<TestStorageInfoProvider>(
-      kTestingData, base::size(kTestingData));
+      kTestingData, std::size(kTestingData));
   extensions::StorageInfoProvider::InitializeForTesting(provider);
   std::vector<std::unique_ptr<ExtensionTestMessageListener>>
       device_ids_listeners;
diff --git a/extensions/browser/api/web_request/form_data_parser.cc b/extensions/browser/api/web_request/form_data_parser.cc
index c67b4a3..a3afebd 100644
--- a/extensions/browser/api/web_request/form_data_parser.cc
+++ b/extensions/browser/api/web_request/form_data_parser.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
@@ -30,7 +29,7 @@
 namespace {
 
 const char kContentDisposition[] = "content-disposition:";
-const size_t kContentDispositionLength = base::size(kContentDisposition) - 1;
+const size_t kContentDispositionLength = std::size(kContentDisposition) - 1;
 // kCharacterPattern is an allowed character in a URL encoding. Definition is
 // from RFC 1738, end of section 2.2.
 const char kCharacterPattern[] =
diff --git a/extensions/browser/api/web_request/form_data_parser_unittest.cc b/extensions/browser/api/web_request/form_data_parser_unittest.cc
index c91563f..84c86110 100644
--- a/extensions/browser/api/web_request/form_data_parser_unittest.cc
+++ b/extensions/browser/api/web_request/form_data_parser_unittest.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "extensions/browser/api/web_request/form_data_parser.h"
+
 #include <stddef.h>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
-#include "extensions/browser/api/web_request/form_data_parser.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace extensions {
@@ -189,7 +189,7 @@
                           "binary",
                           ("\u0420\u043e\u0434\u0436\u0435\u0440 "
                            "\u0416\u0435\u043b\u044f\u0437\u043d\u044b")};
-  const std::vector<std::string> kExpected(kPairs, kPairs + base::size(kPairs));
+  const std::vector<std::string> kExpected(kPairs, kPairs + std::size(kPairs));
 
   std::vector<const base::StringPiece*> input;
   std::vector<std::string> output;
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index da5d3e8..f8ce976d 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -15,7 +15,6 @@
 #include "base/callback_helpers.h"
 #include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
 #include "base/memory/raw_ptr.h"
@@ -216,7 +215,7 @@
             ExtensionWebRequestEventRouter::kOnErrorOccurred},
            {keys::kOnCompleted, ExtensionWebRequestEventRouter::kOnCompleted}});
 
-  DCHECK_EQ(kRequestStageMap->size(), base::size(kWebRequestEvents));
+  DCHECK_EQ(kRequestStageMap->size(), std::size(kWebRequestEvents));
 
   static const size_t kWebRequestEventPrefixLen =
       strlen(kWebRequestEventPrefix);
@@ -395,7 +394,7 @@
       {events::WEB_REQUEST_ON_AUTH_REQUIRED, keys::kOnAuthRequiredEvent},
       {events::WEB_REQUEST_ON_RESPONSE_STARTED, keys::kOnResponseStartedEvent},
       {events::WEB_REQUEST_ON_HEADERS_RECEIVED, keys::kOnHeadersReceivedEvent}};
-  static_assert(base::size(kWebRequestEvents) == base::size(values_and_names),
+  static_assert(std::size(kWebRequestEvents) == std::size(values_and_names),
                 "kWebRequestEvents and values_and_names must be the same");
   for (const ValueAndName& value_and_name : values_and_names) {
     if (value_and_name.event_name == event_name)
@@ -629,7 +628,7 @@
       proxies_(std::make_unique<ProxySet>()),
       may_have_proxies_(MayHaveProxies()) {
   EventRouter* event_router = EventRouter::Get(browser_context_);
-  for (size_t i = 0; i < base::size(kWebRequestEvents); ++i) {
+  for (size_t i = 0; i < std::size(kWebRequestEvents); ++i) {
     // Observe the webRequest event.
     std::string event_name = kWebRequestEvents[i];
     event_router->RegisterObserver(this, event_name);
diff --git a/extensions/browser/api/web_request/web_request_info.cc b/extensions/browser/api/web_request/web_request_info.cc
index 5fe1ab78..ef82984 100644
--- a/extensions/browser/api/web_request/web_request_info.cc
+++ b/extensions/browser/api/web_request/web_request_info.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/values.h"
 #include "content/public/browser/render_frame_host.h"
@@ -133,7 +132,7 @@
                                       keys::kRequestBodyRawKey};
   bool some_succeeded = false;
   if (!data_sources.empty()) {
-    for (size_t i = 0; i < base::size(presenters); ++i) {
+    for (size_t i = 0; i < std::size(presenters); ++i) {
       for (auto& source : data_sources)
         source->FeedToPresenter(presenters[i]);
       if (presenters[i]->Succeeded()) {
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc
index c5a9bce..e68d012 100644
--- a/extensions/browser/api/web_request/web_request_permissions.cc
+++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/browser/api/web_request/web_request_permissions.h"
 
-#include "base/cxx17_backports.h"
 #include "base/debug/crash_logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_piece.h"
@@ -200,8 +199,8 @@
   // PermissionsData::CanAccessPage into one function.
   static constexpr char kGoogleCom[] = "google.com";
   static constexpr char kClient[] = "clients";
-  constexpr size_t kGoogleComLength = base::size(kGoogleCom) - 1;
-  constexpr size_t kClientLength = base::size(kClient) - 1;
+  constexpr size_t kGoogleComLength = std::size(kGoogleCom) - 1;
+  constexpr size_t kClientLength = std::size(kClient) - 1;
 
   if (!url.DomainIs(kGoogleCom))
     return false;
diff --git a/extensions/browser/api/web_request/web_request_resource_type.cc b/extensions/browser/api/web_request/web_request_resource_type.cc
index ec7ff75..02e352e 100644
--- a/extensions/browser/api/web_request/web_request_resource_type.cc
+++ b/extensions/browser/api/web_request/web_request_resource_type.cc
@@ -5,7 +5,6 @@
 #include "extensions/browser/api/web_request/web_request_resource_type.h"
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
 #include "extensions/browser/api/web_request/web_request_info.h"
@@ -37,7 +36,7 @@
     {"other", WebRequestResourceType::OTHER},
 };
 
-constexpr size_t kResourceTypesLength = base::size(kResourceTypes);
+constexpr size_t kResourceTypesLength = std::size(kResourceTypes);
 
 static_assert(kResourceTypesLength ==
                   base::strict_cast<size_t>(WebRequestResourceType::OTHER) + 1,
diff --git a/extensions/browser/api/webcam_private/v4l2_webcam.cc b/extensions/browser/api/webcam_private/v4l2_webcam.cc
index ac2e11cc..a14f502 100644
--- a/extensions/browser/api/webcam_private/v4l2_webcam.cc
+++ b/extensions/browser/api/webcam_private/v4l2_webcam.cc
@@ -12,7 +12,6 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 
@@ -93,7 +92,7 @@
     V4L2_CTRL_TYPE_MENU,
     UVC_CTRL_DATA_TYPE_ENUM,
     const_cast<uvc_menu_info*>(&kLogitechCmdMenu[0]),
-    base::size(kLogitechCmdMenu),
+    std::size(kLogitechCmdMenu),
 };
 
 const uvc_xu_control_mapping kLogitechPanAbsoluteMapping = {
@@ -128,7 +127,7 @@
     V4L2_CTRL_TYPE_MENU,
     UVC_CTRL_DATA_TYPE_ENUM,
     const_cast<uvc_menu_info*>(kAverPresetMenu),
-    base::size(kAverPresetMenu),
+    std::size(kAverPresetMenu),
 };
 
 }  // namespace
diff --git a/extensions/browser/api/webcam_private/visca_webcam.cc b/extensions/browser/api/webcam_private/visca_webcam.cc
index 4f7edd9..d7638f14 100644
--- a/extensions/browser/api/webcam_private/visca_webcam.cc
+++ b/extensions/browser/api/webcam_private/visca_webcam.cc
@@ -11,7 +11,6 @@
 #include <memory>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 
 using content::BrowserThread;
 
@@ -113,7 +112,7 @@
 
 #define CHAR_VECTOR_FROM_ARRAY(array)                     \
   std::vector<char>(reinterpret_cast<const char*>(array), \
-                    reinterpret_cast<const char*>(array + base::size(array)))
+                    reinterpret_cast<const char*>(array + std::size(array)))
 
 int ShiftResponseLowerBits(char c, size_t shift) {
   return static_cast<int>(c & 0x0F) << shift;
diff --git a/extensions/browser/computed_hashes.cc b/extensions/browser/computed_hashes.cc
index 11134b7..84d21e7e 100644
--- a/extensions/browser/computed_hashes.cc
+++ b/extensions/browser/computed_hashes.cc
@@ -309,7 +309,7 @@
 
     std::string buffer;
     buffer.resize(crypto::kSHA256Length);
-    hash->Finish(base::data(buffer), buffer.size());
+    hash->Finish(std::data(buffer), buffer.size());
     hashes.push_back(std::move(buffer));
 
     // If |contents| is empty, then we want to just exit here.
diff --git a/extensions/browser/content_hash_tree.cc b/extensions/browser/content_hash_tree.cc
index 5df4677..2ceb0ca 100644
--- a/extensions/browser/content_hash_tree.cc
+++ b/extensions/browser/content_hash_tree.cc
@@ -40,7 +40,7 @@
         ++i;
       }
       parent_nodes.push_back(std::string(crypto::kSHA256Length, 0));
-      hash->Finish(base::data(parent_nodes.back()), crypto::kSHA256Length);
+      hash->Finish(std::data(parent_nodes.back()), crypto::kSHA256Length);
     }
     current_nodes.swap(parent_nodes);
     parent_nodes.clear();
diff --git a/extensions/browser/content_hash_tree_unittest.cc b/extensions/browser/content_hash_tree_unittest.cc
index 2b7d22b..bec3dae 100644
--- a/extensions/browser/content_hash_tree_unittest.cc
+++ b/extensions/browser/content_hash_tree_unittest.cc
@@ -42,7 +42,7 @@
   std::unique_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256));
   hash->Update(node1.data(), node1.size());
   hash->Update(node2.data(), node2.size());
-  hash->Finish(base::data(expected), expected.size());
+  hash->Finish(std::data(expected), expected.size());
   EXPECT_EQ(expected, ComputeTreeHashRoot(nodes, 16));
 }
 
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc
index 533c17ea..bcbec8d 100644
--- a/extensions/browser/content_verify_job.cc
+++ b/extensions/browser/content_verify_job.cc
@@ -199,7 +199,7 @@
     current_hash_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
   }
   std::string final(crypto::kSHA256Length, 0);
-  current_hash_->Finish(base::data(final), final.size());
+  current_hash_->Finish(std::data(final), final.size());
   current_hash_.reset();
   current_hash_byte_count_ = 0;
 
@@ -257,7 +257,7 @@
   if (!queue_.empty()) {
     std::string tmp;
     queue_.swap(tmp);
-    ReadImpl(base::data(tmp), tmp.size(), MOJO_RESULT_OK);
+    ReadImpl(std::data(tmp), tmp.size(), MOJO_RESULT_OK);
     if (failed_)
       return;
   }
diff --git a/extensions/browser/content_verify_job_unittest.cc b/extensions/browser/content_verify_job_unittest.cc
index fff575da..b36e8fa 100644
--- a/extensions/browser/content_verify_job_unittest.cc
+++ b/extensions/browser/content_verify_job_unittest.cc
@@ -141,8 +141,8 @@
     auto run_content_read_step = [](ContentVerifyJob* verify_job,
                                     std::string* resource_contents) {
       // Simulate serving |resource_contents| from |resource_path|.
-      verify_job->Read(base::data(*resource_contents),
-                       resource_contents->size(), MOJO_RESULT_OK);
+      verify_job->Read(std::data(*resource_contents), resource_contents->size(),
+                       MOJO_RESULT_OK);
       verify_job->Done();
     };
 
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc
index fb71ee7..ae37063d 100644
--- a/extensions/browser/event_router_unittest.cc
+++ b/extensions/browser/event_router_unittest.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/values.h"
 #include "content/public/browser/browser_context.h"
@@ -444,7 +443,7 @@
         absl::make_optional<ServiceWorkerIdentifier>(std::move(identifier));
   }
   std::vector<std::unique_ptr<DictionaryValue>> filters;
-  for (size_t i = 0; i < base::size(kHostSuffixes); ++i) {
+  for (size_t i = 0; i < std::size(kHostSuffixes); ++i) {
     std::unique_ptr<base::DictionaryValue> filter =
         CreateHostSuffixFilter(kHostSuffixes[i]);
     event_router()->AddFilteredEventListener(kEventName, render_process_host(),
diff --git a/extensions/browser/extension_creator_filter_unittest.cc b/extensions/browser/extension_creator_filter_unittest.cc
index 775ba2d..07045ad0 100644
--- a/extensions/browser/extension_creator_filter_unittest.cc
+++ b/extensions/browser/extension_creator_filter_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "build/build_config.h"
@@ -84,7 +83,7 @@
       {FILE_PATH_LITERAL("Thumbs.db"), false},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     base::FilePath input(cases[i].input);
     base::FilePath test_file(CreateTestFile(input));
     bool observed = filter_->ShouldPackageFile(test_file);
@@ -104,7 +103,7 @@
   };
 
   // Create and test the filepaths.
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     base::FilePath test_file =
         CreateRelativeFilePath(base::FilePath(cases[i].input));
     bool observed = filter_->ShouldPackageFile(test_file);
@@ -122,7 +121,7 @@
       {FILE_PATH_LITERAL("abc/_metadata"), true},
       {FILE_PATH_LITERAL("xyz"), true},
   };
-  for (size_t i = 0; i < base::size(directory_cases); ++i) {
+  for (size_t i = 0; i < std::size(directory_cases); ++i) {
     base::FilePath directory = extension_dir_.Append(directory_cases[i].input);
     bool observed = filter_->ShouldPackageFile(directory);
 
@@ -148,7 +147,7 @@
       {FILE_PATH_LITERAL("index.js"), FILE_PATH_LITERAL("scripts"), true},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     base::FilePath test_file(
         CreateTestFileInDir(cases[i].file_name, cases[i].dir));
     bool observed = filter_->ShouldPackageFile(test_file);
@@ -174,7 +173,7 @@
       {FILE_PATH_LITERAL("a-file-that-we-have-not-set-to-hidden"), false, true},
   };
 
-  for (size_t i = 0; i < base::size(cases); ++i) {
+  for (size_t i = 0; i < std::size(cases); ++i) {
     base::FilePath input(cases[i].input_char);
     bool should_hide = cases[i].input_bool;
     base::FilePath test_file(CreateTestFile(input));
diff --git a/extensions/browser/image_loader_unittest.cc b/extensions/browser/image_loader_unittest.cc
index d277504..e8d15e7 100644
--- a/extensions/browser/image_loader_unittest.cc
+++ b/extensions/browser/image_loader_unittest.cc
@@ -7,7 +7,6 @@
 #include <stddef.h>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/path_service.h"
@@ -185,7 +184,7 @@
   std::vector<ImageLoader::ImageRepresentation> info_list;
   int sizes[] = {extension_misc::EXTENSION_ICON_BITTY,
                  extension_misc::EXTENSION_ICON_SMALLISH, };
-  for (size_t i = 0; i < base::size(sizes); ++i) {
+  for (size_t i = 0; i < std::size(sizes); ++i) {
     ExtensionResource resource = IconsInfo::GetIconResource(
         extension.get(), sizes[i], ExtensionIconSet::MATCH_EXACTLY);
     info_list.push_back(ImageLoader::ImageRepresentation(
@@ -228,7 +227,7 @@
   std::vector<ImageLoader::ImageRepresentation> info_list;
   int sizes[] = {extension_misc::EXTENSION_ICON_BITTY,
                  extension_misc::EXTENSION_ICON_SMALLISH, };
-  for (size_t i = 0; i < base::size(sizes); ++i) {
+  for (size_t i = 0; i < std::size(sizes); ++i) {
     ExtensionResource resource = IconsInfo::GetIconResource(
         extension.get(), sizes[i], ExtensionIconSet::MATCH_EXACTLY);
     info_list.push_back(ImageLoader::ImageRepresentation(
@@ -263,7 +262,7 @@
   EXPECT_EQ(1, image_loaded_count());
 
   // Check that all images were loaded.
-  for (size_t i = 0; i < base::size(sizes); ++i) {
+  for (size_t i = 0; i < std::size(sizes); ++i) {
     const gfx::Image* image = image_family_.GetBest(sizes[i], sizes[i]);
     EXPECT_EQ(sizes[i], image->Width());
   }
diff --git a/extensions/common/api/sockets/sockets_manifest_permission_unittest.cc b/extensions/common/api/sockets/sockets_manifest_permission_unittest.cc
index aecbd35..6c16935 100644
--- a/extensions/common/api/sockets/sockets_manifest_permission_unittest.cc
+++ b/extensions/common/api/sockets/sockets_manifest_permission_unittest.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "extensions/common/api/sockets/sockets_manifest_permission.h"
+
 #include <set>
 #include <tuple>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/values.h"
-#include "extensions/common/api/sockets/sockets_manifest_permission.h"
 #include "extensions/common/manifest_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -119,7 +119,7 @@
                                             const CheckFormatEntry& op1) {
   CheckFormatEntry entries[] = {op1};
   return CheckFormat(
-      std::multiset<CheckFormatEntry>(entries, entries + base::size(entries)),
+      std::multiset<CheckFormatEntry>(entries, entries + std::size(entries)),
       json);
 }
 
@@ -128,7 +128,7 @@
                                             const CheckFormatEntry& op2) {
   CheckFormatEntry entries[] = {op1, op2};
   return CheckFormat(
-      std::multiset<CheckFormatEntry>(entries, entries + base::size(entries)),
+      std::multiset<CheckFormatEntry>(entries, entries + std::size(entries)),
       json);
 }
 
@@ -144,7 +144,7 @@
                                             const CheckFormatEntry& op9) {
   CheckFormatEntry entries[] = {op1, op2, op3, op4, op5, op6, op7, op8, op9};
   return CheckFormat(
-      std::multiset<CheckFormatEntry>(entries, entries + base::size(entries)),
+      std::multiset<CheckFormatEntry>(entries, entries + std::size(entries)),
       json);
 }
 
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index 3cfb5b5..7a36a04 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/common/constants.h"
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
 #include "build/build_config.h"
 #include "build/chromecast_buildflags.h"
@@ -105,7 +104,7 @@
     0xcd, 0x02, 0x03, 0x01, 0x00, 0x01};
 
 const size_t kWebstoreSignaturesPublicKeySize =
-    base::size(kWebstoreSignaturesPublicKey);
+    std::size(kWebstoreSignaturesPublicKey);
 
 const char kUpdateURLData[] = "update_url_data";
 
diff --git a/extensions/common/csp_validator.cc b/extensions/common/csp_validator.cc
index 803bcf19..dd06650b 100644
--- a/extensions/common/csp_validator.cc
+++ b/extensions/common/csp_validator.cc
@@ -16,7 +16,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/string_piece.h"
@@ -87,8 +86,8 @@
   constexpr char kLocalHostIP[] = "http://127.0.0.1";
 
   // Subtracting 1 to exclude the null terminator '\0'.
-  constexpr size_t kLocalHostLen = base::size(kLocalHost) - 1;
-  constexpr size_t kLocalHostIPLen = base::size(kLocalHostIP) - 1;
+  constexpr size_t kLocalHostLen = std::size(kLocalHost) - 1;
+  constexpr size_t kLocalHostIPLen = std::size(kLocalHostIP) - 1;
 
   if (base::StartsWith(source_lower, kLocalHost,
                        base::CompareCase::SENSITIVE)) {
@@ -531,7 +530,7 @@
   // representing the content security policy as an HTTP header.
   const char kBadChars[] = {',', '\r', '\n', '\0'};
 
-  return policy.find_first_of(kBadChars, 0, base::size(kBadChars)) ==
+  return policy.find_first_of(kBadChars, 0, std::size(kBadChars)) ==
          std::string::npos;
 }
 
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc
index b53b7a9f..c6acb25 100644
--- a/extensions/common/extension_api.cc
+++ b/extensions/common/extension_api.cc
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/lazy_instance.h"
@@ -43,7 +42,7 @@
 
   // Tracking down http://crbug.com/121424
   char buf[128];
-  base::snprintf(buf, base::size(buf), "%s: (%d) '%s'", name.c_str(),
+  base::snprintf(buf, std::size(buf), "%s: (%d) '%s'", name.c_str(),
                  result.value ? static_cast<int>(result.value->type()) : -1,
                  result.error_message.c_str());
 
@@ -72,7 +71,7 @@
     const base::DictionaryValue* schema_node,
     const std::string& child_name) {
   const base::DictionaryValue* child_node = NULL;
-  for (size_t i = 0; i < base::size(kChildKinds); ++i) {
+  for (size_t i = 0; i < std::size(kChildKinds); ++i) {
     const base::ListValue* list_node = NULL;
     if (!schema_node->GetList(kChildKinds[i], &list_node))
       continue;
diff --git a/extensions/common/features/feature_provider.cc b/extensions/common/features/feature_provider.cc
index 1e3b6233..4c604851 100644
--- a/extensions/common/features/feature_provider.cc
+++ b/extensions/common/features/feature_provider.cc
@@ -34,14 +34,14 @@
 // This is provided in feature_util because for some reason features are prone
 // to mysterious crashes in named map lookups. For example see crbug.com/365192
 // and crbug.com/461915.
-#define CRASH_WITH_MINIDUMP(message)                                  \
-  {                                                                   \
-    std::string message_copy(message);                                \
-    char minidump[BUFSIZ];                                            \
-    base::debug::Alias(&minidump);                                    \
-    base::snprintf(minidump, base::size(minidump), "e::%s:%d:\"%s\"", \
-                   __FILE__, __LINE__, message_copy.c_str());         \
-    LOG(FATAL) << message_copy;                                       \
+#define CRASH_WITH_MINIDUMP(message)                                           \
+  {                                                                            \
+    std::string message_copy(message);                                         \
+    char minidump[BUFSIZ];                                                     \
+    base::debug::Alias(&minidump);                                             \
+    base::snprintf(minidump, std::size(minidump), "e::%s:%d:\"%s\"", __FILE__, \
+                   __LINE__, message_copy.c_str());                            \
+    LOG(FATAL) << message_copy;                                                \
   }
 
 class FeatureProviderStatic {
diff --git a/extensions/common/features/simple_feature_unittest.cc b/extensions/common/features/simple_feature_unittest.cc
index 6491bf3..c648495 100644
--- a/extensions/common/features/simple_feature_unittest.cc
+++ b/extensions/common/features/simple_feature_unittest.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_command_line.h"
 #include "base/test/scoped_feature_list.h"
@@ -119,7 +118,7 @@
        Feature::IS_AVAILABLE}};
 
   SimpleFeature feature;
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     const IsAvailableTestData& test = tests[i];
     EXPECT_EQ(test.expected_result,
               feature
@@ -547,7 +546,7 @@
        mojom::FeatureSessionType::kAutolaunchedKiosk,
        {mojom::FeatureSessionType::kKiosk}}};
 
-  for (size_t i = 0; i < base::size(kTestData); ++i) {
+  for (size_t i = 0; i < std::size(kTestData); ++i) {
     std::unique_ptr<base::AutoReset<mojom::FeatureSessionType>> current_session(
         ScopedCurrentFeatureSessionType(kTestData[i].current_session_type));
 
@@ -789,13 +788,13 @@
     // aaaabbbbccccddddeeeeffffgggghhhh
     "9A0417016F345C934A1A88F55CA17C05014EEEBA"
   };
-  EXPECT_FALSE(SimpleFeature::IsIdInArray("", kIdArray, base::size(kIdArray)));
+  EXPECT_FALSE(SimpleFeature::IsIdInArray("", kIdArray, std::size(kIdArray)));
   EXPECT_FALSE(SimpleFeature::IsIdInArray("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-                                          kIdArray, base::size(kIdArray)));
+                                          kIdArray, std::size(kIdArray)));
   EXPECT_TRUE(SimpleFeature::IsIdInArray("bbbbccccdddddddddeeeeeeffffgghhh",
-                                         kIdArray, base::size(kIdArray)));
+                                         kIdArray, std::size(kIdArray)));
   EXPECT_TRUE(SimpleFeature::IsIdInArray("aaaabbbbccccddddeeeeffffgggghhhh",
-                                         kIdArray, base::size(kIdArray)));
+                                         kIdArray, std::size(kIdArray)));
 }
 
 // Tests that all combinations of feature channel and Chrome channel correctly
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc
index 7d118b8..f3d975c 100644
--- a/extensions/common/file_util_unittest.cc
+++ b/extensions/common/file_util_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_string_value_serializer.h"
@@ -259,7 +258,7 @@
   static const base::FilePath::CharType* const folders[] = {
       kLocaleFolder, kPlatformSpecificFolder};
 
-  for (size_t i = 0; i < base::size(folders); i++) {
+  for (size_t i = 0; i < std::size(folders); i++) {
     base::FilePath src_path = temp.GetPath().Append(folders[i]);
     ASSERT_TRUE(base::CreateDirectory(src_path));
   }
@@ -443,20 +442,20 @@
   base::FilePath src_path = temp.GetPath().AppendASCII("some_dir");
   ASSERT_TRUE(base::CreateDirectory(src_path));
 
-  ASSERT_EQ(static_cast<int>(base::size(private_key)),
+  ASSERT_EQ(static_cast<int>(std::size(private_key)),
             base::WriteFile(src_path.AppendASCII("a_key.pem"), private_key,
-                            base::size(private_key)));
-  ASSERT_EQ(static_cast<int>(base::size(private_key)),
+                            std::size(private_key)));
+  ASSERT_EQ(static_cast<int>(std::size(private_key)),
             base::WriteFile(src_path.AppendASCII("second_key.pem"), private_key,
-                            base::size(private_key)));
+                            std::size(private_key)));
   // Shouldn't find a key with a different extension.
-  ASSERT_EQ(static_cast<int>(base::size(private_key)),
+  ASSERT_EQ(static_cast<int>(std::size(private_key)),
             base::WriteFile(src_path.AppendASCII("key.diff_ext"), private_key,
-                            base::size(private_key)));
+                            std::size(private_key)));
   // Shouldn't find a key that isn't parsable.
-  ASSERT_EQ(static_cast<int>(base::size(private_key)) - 30,
+  ASSERT_EQ(static_cast<int>(std::size(private_key)) - 30,
             base::WriteFile(src_path.AppendASCII("unparsable_key.pem"),
-                            private_key, base::size(private_key) - 30));
+                            private_key, std::size(private_key) - 30));
   std::vector<base::FilePath> private_keys =
       file_util::FindPrivateKeyFiles(temp.GetPath());
   EXPECT_EQ(2U, private_keys.size());
@@ -637,7 +636,7 @@
   };
 #undef URL_PREFIX
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     GURL url(test_cases[i].url);
     base::FilePath expected_path =
         base::FilePath::FromUTF8Unsafe(test_cases[i].expected_relative_path);
diff --git a/extensions/common/manifest_handlers/csp_info_unittest.cc b/extensions/common/manifest_handlers/csp_info_unittest.cc
index c798022..fa6ef68 100644
--- a/extensions/common/manifest_handlers/csp_info_unittest.cc
+++ b/extensions/common/manifest_handlers/csp_info_unittest.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "extensions/common/manifest_handlers/csp_info.h"
-#include "base/cxx17_backports.h"
+
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/version_info/channel.h"
@@ -103,7 +103,7 @@
                GetInvalidManifestKeyError(keys::kSandboxedPagesCSP)),
       Testcase("sandboxed_pages_invalid_5.json",
                GetInvalidManifestKeyError(keys::kSandboxedPagesCSP))};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(CSPInfoUnitTest, CSPStringKey) {
@@ -169,7 +169,7 @@
                    keys::kContentSecurityPolicy_ExtensionPagesPath,
                    "'wasm-unsafe-eval'", "worker-src")),
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(CSPInfoUnitTest, AllowWasmInMV3) {
@@ -239,7 +239,7 @@
       {"unsandboxed_csp.json",
        GetInvalidManifestKeyError(
            keys::kContentSecurityPolicy_SandboxedPagesPath)}};
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 // Ensures that using a dictionary for the keys::kContentSecurityPolicy manifest
diff --git a/extensions/common/manifest_handlers/externally_connectable_unittest.cc b/extensions/common/manifest_handlers/externally_connectable_unittest.cc
index d1640a4..93a1570 100644
--- a/extensions/common/manifest_handlers/externally_connectable_unittest.cc
+++ b/extensions/common/manifest_handlers/externally_connectable_unittest.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "extensions/common/manifest_handlers/externally_connectable.h"
+
 #include <stddef.h>
 
 #include <algorithm>
 
-#include "base/cxx17_backports.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/manifest_constants.h"
-#include "extensions/common/manifest_handlers/externally_connectable.h"
 #include "extensions/common/manifest_test.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -195,7 +195,7 @@
   // Not in order to test that ExternallyConnectableInfo sorts it.
   std::string matches_ids_array[] = {"g", "h", "c", "i", "a", "z", "b"};
   std::vector<std::string> matches_ids(
-      matches_ids_array, matches_ids_array + base::size(matches_ids_array));
+      matches_ids_array, matches_ids_array + std::size(matches_ids_array));
 
   std::string nomatches_ids_array[] = {"2", "3", "1"};
 
@@ -204,7 +204,7 @@
     ExternallyConnectableInfo info(URLPatternSet(), matches_ids, false, false);
     for (size_t i = 0; i < matches_ids.size(); ++i)
       EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
-    for (size_t i = 0; i < base::size(nomatches_ids_array); ++i)
+    for (size_t i = 0; i < std::size(nomatches_ids_array); ++i)
       EXPECT_FALSE(info.IdCanConnect(nomatches_ids_array[i]));
   }
 
@@ -213,7 +213,7 @@
     ExternallyConnectableInfo info(URLPatternSet(), matches_ids, true, false);
     for (size_t i = 0; i < matches_ids.size(); ++i)
       EXPECT_TRUE(info.IdCanConnect(matches_ids[i]));
-    for (size_t i = 0; i < base::size(nomatches_ids_array); ++i)
+    for (size_t i = 0; i < std::size(nomatches_ids_array); ++i)
       EXPECT_TRUE(info.IdCanConnect(nomatches_ids_array[i]));
   }
 }
diff --git a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
index 8d86703..1d6b56a 100644
--- a/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
+++ b/extensions/common/manifest_handlers/file_handler_manifest_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "components/services/app_service/public/cpp/file_handler_info.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_handlers/file_handler_info.h"
@@ -36,7 +35,7 @@
       Testcase("file_handlers_invalid_verb.json",
                errors::kInvalidFileHandlerVerb),
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(FileHandlersManifestTest, ValidFileHandlers) {
diff --git a/extensions/common/manifest_handlers/mime_types_handler.cc b/extensions/common/manifest_handlers/mime_types_handler.cc
index 6ece498..bdeff4a 100644
--- a/extensions/common/manifest_handlers/mime_types_handler.cc
+++ b/extensions/common/manifest_handlers/mime_types_handler.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/no_destructor.h"
 #include "base/strings/string_util.h"
@@ -47,7 +46,7 @@
 };
 
 static_assert(
-    base::size(kMIMETypeHandlersAllowlist) ==
+    std::size(kMIMETypeHandlersAllowlist) ==
         static_cast<size_t>(MimeHandlerType::kMaxValue) + 1,
     "MimeHandlerType enum is not in sync with kMIMETypeHandlersAllowlist.");
 
diff --git a/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc b/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
index bc28fb9f..4466b4f 100644
--- a/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
+++ b/extensions/common/manifest_handlers/shared_module_manifest_unittest.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/cxx17_backports.h"
 #include "base/version.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/manifest_handlers/shared_module_info.h"
@@ -80,7 +79,7 @@
                "Error at key 'export.allowlist'. Type is invalid. Expected "
                "list, found string."),
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 TEST_F(SharedModuleManifestTest, SharedModuleStaticFunctions) {
@@ -128,7 +127,7 @@
       Testcase("shared_module_import_invalid_version.json",
                "Invalid value for 'import[0].minimum_version'."),
   };
-  RunTestcases(testcases, base::size(testcases), EXPECT_TYPE_ERROR);
+  RunTestcases(testcases, std::size(testcases), EXPECT_TYPE_ERROR);
 }
 
 }  // namespace extensions
diff --git a/extensions/common/message_bundle_unittest.cc b/extensions/common/message_bundle_unittest.cc
index 956c468..3c13b54 100644
--- a/extensions/common/message_bundle_unittest.cc
+++ b/extensions/common/message_bundle_unittest.cc
@@ -11,7 +11,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -382,7 +381,7 @@
   messages.insert(std::make_pair("bad name", "Doesn't matter"));
   messages.insert(std::make_pair("d1g1ts_are_ok", "I are d1g1t"));
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     std::string text = test_cases[i].original;
     std::string error;
     EXPECT_EQ(test_cases[i].pass,
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc
index 2975e0a..c5339d3 100644
--- a/extensions/common/url_pattern.cc
+++ b/extensions/common/url_pattern.cc
@@ -8,7 +8,6 @@
 
 #include <ostream>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/pattern.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
@@ -49,7 +48,7 @@
     URLPattern::SCHEME_URN,        URLPattern::SCHEME_UUID_IN_PACKAGE,
 };
 
-static_assert(base::size(kValidSchemes) == base::size(kValidSchemeMasks),
+static_assert(std::size(kValidSchemes) == std::size(kValidSchemeMasks),
               "must keep these arrays in sync");
 
 const char kParseSuccess[] = "Success.";
@@ -76,7 +75,7 @@
 };
 
 static_assert(static_cast<int>(URLPattern::ParseResult::kNumParseResults) ==
-                  base::size(kParseResultMessages),
+                  std::size(kParseResultMessages),
               "must add message for each parse result");
 
 const char kPathSeparator[] = "/";
@@ -130,7 +129,7 @@
 
 // static
 bool URLPattern::IsValidSchemeForExtensions(base::StringPiece scheme) {
-  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kValidSchemes); ++i) {
     if (scheme == kValidSchemes[i])
       return true;
   }
@@ -140,7 +139,7 @@
 // static
 int URLPattern::GetValidSchemeMaskForExtensions() {
   int result = 0;
-  for (size_t i = 0; i < base::size(kValidSchemeMasks); ++i)
+  for (size_t i = 0; i < std::size(kValidSchemeMasks); ++i)
     result |= kValidSchemeMasks[i];
   return result;
 }
@@ -387,7 +386,7 @@
   if (valid_schemes_ == SCHEME_ALL)
     return true;
 
-  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kValidSchemes); ++i) {
     if (scheme == kValidSchemes[i] && (valid_schemes_ & kValidSchemeMasks[i]))
       return true;
   }
@@ -774,7 +773,7 @@
     return result;
   }
 
-  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
+  for (size_t i = 0; i < std::size(kValidSchemes); ++i) {
     if (MatchesScheme(kValidSchemes[i])) {
       result.push_back(kValidSchemes[i]);
     }
diff --git a/extensions/common/url_pattern_unittest.cc b/extensions/common/url_pattern_unittest.cc
index 00d41d6..9d98f9e 100644
--- a/extensions/common/url_pattern_unittest.cc
+++ b/extensions/common/url_pattern_unittest.cc
@@ -8,7 +8,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/test_utils.h"
@@ -48,7 +47,7 @@
       {"http://bar", URLPattern::ParseResult::kEmptyPath},
       {"http://foo.*/bar", URLPattern::ParseResult::kInvalidHostWildcard}};
 
-  for (size_t i = 0; i < base::size(kInvalidPatterns); ++i) {
+  for (size_t i = 0; i < std::size(kInvalidPatterns); ++i) {
     URLPattern pattern(URLPattern::SCHEME_ALL);
     EXPECT_EQ(kInvalidPatterns[i].expected_result,
               pattern.Parse(kInvalidPatterns[i].pattern))
@@ -91,7 +90,7 @@
       {"http://*.foo/bar:1234", URLPattern::ParseResult::kSuccess, "*"},
       {"http://foo/bar:1234/path", URLPattern::ParseResult::kSuccess, "*"}};
 
-  for (size_t i = 0; i < base::size(kTestPatterns); ++i) {
+  for (size_t i = 0; i < std::size(kTestPatterns); ++i) {
     URLPattern pattern(URLPattern::SCHEME_ALL);
     EXPECT_EQ(kTestPatterns[i].expected_result,
               pattern.Parse(kTestPatterns[i].pattern))
@@ -412,7 +411,7 @@
 
 // SCHEME_ALL and specific schemes.
 TEST(ExtensionURLPatternTest, Match13) {
-  for (size_t i = 0; i < base::size(kMatch13UrlPatternTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kMatch13UrlPatternTestCases); ++i) {
     URLPattern pattern(URLPattern::SCHEME_ALL);
     EXPECT_EQ(URLPattern::ParseResult::kSuccess,
               pattern.Parse(kMatch13UrlPatternTestCases[i].pattern))
@@ -555,7 +554,7 @@
 };
 
 TEST(ExtensionURLPatternTest, GetAsString) {
-  for (size_t i = 0; i < base::size(kGetAsStringTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kGetAsStringTestCases); ++i) {
     URLPattern pattern(URLPattern::SCHEME_ALL);
     EXPECT_EQ(URLPattern::ParseResult::kSuccess,
               pattern.Parse(kGetAsStringTestCases[i].pattern))
@@ -774,7 +773,7 @@
     }
   };
 
-  for (size_t i = 0; i < base::size(kEqualsTestCases); ++i) {
+  for (size_t i = 0; i < std::size(kEqualsTestCases); ++i) {
     std::string message = kEqualsTestCases[i].pattern1;
     message += " ";
     message += kEqualsTestCases[i].pattern2;
diff --git a/extensions/renderer/binding_generating_native_handler.cc b/extensions/renderer/binding_generating_native_handler.cc
index 34fab61..75a71036 100644
--- a/extensions/renderer/binding_generating_native_handler.cc
+++ b/extensions/renderer/binding_generating_native_handler.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/renderer/binding_generating_native_handler.h"
 
-#include "base/cxx17_backports.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/v8_helpers.h"
 #include "gin/data_object_builder.h"
@@ -87,7 +86,7 @@
         v8_context->GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks);
     // TODO(devlin): We should not be using v8::Function::Call() directly here.
     // Instead, we should use JSRunner once it's used outside native bindings.
-    if (!create_binding->Call(v8_context, binding, base::size(argv), argv)
+    if (!create_binding->Call(v8_context, binding, std::size(argv), argv)
              .ToLocal(&binding_instance_value) ||
         !binding_instance_value->ToObject(v8_context)
              .ToLocal(&binding_instance)) {
diff --git a/extensions/renderer/bindings/api_binding_bridge.cc b/extensions/renderer/bindings/api_binding_bridge.cc
index 52c8b61..f781993 100644
--- a/extensions/renderer/bindings/api_binding_bridge.cc
+++ b/extensions/renderer/bindings/api_binding_bridge.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/renderer/bindings/api_binding_bridge.h"
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "extensions/renderer/bindings/api_binding_hooks.h"
 #include "extensions/renderer/bindings/api_binding_util.h"
@@ -104,7 +103,7 @@
   // This CHECK is helping to track down https://crbug.com/819968, and should be
   // removed when that's fixed.
   CHECK(binding::IsContextValid(context));
-  JSRunner::Get(context)->RunJSFunction(function, context, base::size(args),
+  JSRunner::Get(context)->RunJSFunction(function, context, std::size(args),
                                         args);
 }
 
diff --git a/extensions/renderer/bindings/api_binding_bridge_unittest.cc b/extensions/renderer/bindings/api_binding_bridge_unittest.cc
index 81ba9e3..874961a 100644
--- a/extensions/renderer/bindings/api_binding_bridge_unittest.cc
+++ b/extensions/renderer/bindings/api_binding_bridge_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/renderer/bindings/api_binding_bridge.h"
 
-#include "base/cxx17_backports.h"
 #include "extensions/renderer/bindings/api_binding_hooks.h"
 #include "extensions/renderer/bindings/api_binding_test.h"
 #include "extensions/renderer/bindings/api_binding_test_util.h"
@@ -38,7 +37,7 @@
   v8::Local<v8::Function> function = FunctionFromString(
       context, "(function(obj) { obj.registerCustomHook(function() {}); })");
   v8::Local<v8::Value> args[] = {bridge_object};
-  RunFunctionAndExpectError(function, context, base::size(args), args,
+  RunFunctionAndExpectError(function, context, std::size(args), args,
                             "Uncaught Error: Extension context invalidated.");
 }
 
diff --git a/extensions/renderer/bindings/api_binding_js_util_unittest.cc b/extensions/renderer/bindings/api_binding_js_util_unittest.cc
index be11a41..0c7a12c 100644
--- a/extensions/renderer/bindings/api_binding_js_util_unittest.cc
+++ b/extensions/renderer/bindings/api_binding_js_util_unittest.cc
@@ -5,7 +5,6 @@
 #include "extensions/renderer/bindings/api_binding_js_util.h"
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "extensions/renderer/bindings/api_binding_test_util.h"
 #include "extensions/renderer/bindings/api_bindings_system.h"
 #include "extensions/renderer/bindings/api_bindings_system_unittest.h"
@@ -279,7 +278,7 @@
       context,
       "(function(util, handler) { util.setExceptionHandler(handler); })");
   v8::Local<v8::Value> args[] = {v8_util, v8_handler};
-  RunFunction(add_handler, context, base::size(args), args);
+  RunFunction(add_handler, context, std::size(args), args);
 
   CallFunctionOnObject(context, v8_util, kHandleException);
   // The error should not have been reported to the console since we have a
@@ -302,10 +301,10 @@
     v8::Local<v8::Function> v8_function = FunctionFromString(context, function);
     v8::Local<v8::Value> args[] = {v8_util};
     if (expected_error) {
-      RunFunctionAndExpectError(v8_function, context, base::size(args), args,
+      RunFunctionAndExpectError(v8_function, context, std::size(args), args,
                                 *expected_error);
     } else {
-      RunFunction(v8_function, context, base::size(args), args);
+      RunFunction(v8_function, context, std::size(args), args);
     }
   };
 
@@ -350,7 +349,7 @@
     v8::Local<v8::Function> add_signature =
         FunctionFromString(context, kAddSignature);
     v8::Local<v8::Value> args[] = {v8_util};
-    RunFunction(add_signature, context, base::size(args), args);
+    RunFunction(add_signature, context, std::size(args), args);
   }
 
   EXPECT_TRUE(bindings_system()->type_reference_map()->GetCustomSignature(
@@ -363,10 +362,10 @@
             FunctionFromString(context, function);
         v8::Local<v8::Value> args[] = {v8_util};
         if (expected_error) {
-          RunFunctionAndExpectError(v8_function, context, base::size(args),
-                                    args, *expected_error);
+          RunFunctionAndExpectError(v8_function, context, std::size(args), args,
+                                    *expected_error);
         } else {
-          RunFunction(v8_function, context, base::size(args), args);
+          RunFunction(v8_function, context, std::size(args), args);
         }
       };
 
diff --git a/extensions/renderer/bindings/api_binding_unittest.cc b/extensions/renderer/bindings/api_binding_unittest.cc
index e3c429a0..2fb9bbca 100644
--- a/extensions/renderer/bindings/api_binding_unittest.cc
+++ b/extensions/renderer/bindings/api_binding_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/auto_reset.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
 #include "base/values.h"
@@ -281,10 +280,10 @@
           FunctionFromString(context, register_hook);
       if (!additional_arg.IsEmpty()) {
         v8::Local<v8::Value> args[] = {js_hooks, additional_arg};
-        RunFunctionOnGlobal(function, context, base::size(args), args);
+        RunFunctionOnGlobal(function, context, std::size(args), args);
       } else {
         v8::Local<v8::Value> args[] = {js_hooks};
-        RunFunctionOnGlobal(function, context, base::size(args), args);
+        RunFunctionOnGlobal(function, context, std::size(args), args);
       }
     }
     SetHooks(std::move(hooks));
@@ -710,10 +709,10 @@
       context, "(function(e) { e.addListener(function() {}); })");
   v8::Local<v8::Value> args[] = {
       GetPropertyFromObject(binding_object, context, "onBaz")};
-  RunFunction(add_listener, context, base::size(args), args);
+  RunFunction(add_listener, context, std::size(args), args);
   EXPECT_EQ(1u, event_handler()->GetNumEventListenersForTesting("test.onBaz",
                                                                 context));
-  RunFunctionAndExpectError(add_listener, context, base::size(args), args,
+  RunFunctionAndExpectError(add_listener, context, std::size(args), args,
                             "Uncaught TypeError: Too many listeners.");
   EXPECT_EQ(1u, event_handler()->GetNumEventListenersForTesting("test.onBaz",
                                                                 context));
@@ -853,7 +852,7 @@
   v8::Local<v8::Value> argv[] = {binding_object};
   DisposeContext(context);
 
-  RunFunctionAndExpectError(func, context, base::size(argv), argv,
+  RunFunctionAndExpectError(func, context, std::size(argv), argv,
                             "Uncaught Error: Extension context invalidated.");
 
   EXPECT_FALSE(HandlerWasInvoked());
@@ -875,7 +874,7 @@
   v8::Local<v8::Value> argv[] = {binding_object};
   binding::InvalidateContext(context);
 
-  RunFunctionAndExpectError(func, context, base::size(argv), argv,
+  RunFunctionAndExpectError(func, context, std::size(argv), argv,
                             "Uncaught Error: Extension context invalidated.");
 
   EXPECT_FALSE(HandlerWasInvoked());
@@ -1050,7 +1049,7 @@
   {
     TestJSRunner::AllowErrors allow_errors;
     RunFunctionAndExpectError(function, context, v8::Undefined(isolate()),
-                              base::size(args), args,
+                              std::size(args), args,
                               "Uncaught Error: Custom Hook Error");
   }
 
@@ -1082,7 +1081,7 @@
                          "(function(obj) { return obj.oneString('ping'); })");
   v8::Local<v8::Value> args[] = {binding_object};
   v8::Local<v8::Value> result =
-      RunFunction(function, context, base::size(args), args);
+      RunFunction(function, context, std::size(args), args);
   ASSERT_FALSE(result.IsEmpty());
   std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context);
   ASSERT_TRUE(json_result);
@@ -1125,7 +1124,7 @@
     v8::Local<v8::Value> args[] = {binding_object};
 
     auto result = RunFunction(function, context, v8::Undefined(isolate()),
-                              base::size(args), args);
+                              std::size(args), args);
 
     ASSERT_FALSE(result.IsEmpty());
     EXPECT_TRUE(result->IsUndefined());
@@ -1142,7 +1141,7 @@
     v8::Local<v8::Value> callback_arguments[] = {
         gin::StringToV8(isolate(), "foo")};
     RunFunctionOnGlobal(resolve_callback, context,
-                        base::size(callback_arguments), callback_arguments);
+                        std::size(callback_arguments), callback_arguments);
     EXPECT_EQ(R"("foo")", GetStringPropertyFromObject(
                               context->Global(), context, "sentToCallback"));
   }
@@ -1156,7 +1155,7 @@
     v8::Local<v8::Value> args[] = {binding_object};
 
     v8::Local<v8::Value> result = RunFunction(
-        function, context, v8::Undefined(isolate()), base::size(args), args);
+        function, context, v8::Undefined(isolate()), std::size(args), args);
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetValueAs(result, &promise));
 
@@ -1173,7 +1172,7 @@
     v8::Local<v8::Value> callback_arguments[] = {
         gin::StringToV8(isolate(), "bar")};
     RunFunctionOnGlobal(resolve_callback, context,
-                        base::size(callback_arguments), callback_arguments);
+                        std::size(callback_arguments), callback_arguments);
     EXPECT_EQ(v8::Promise::kFulfilled, promise->State());
     EXPECT_EQ(R"("bar")", V8ToString(promise->Result(), context));
   }
@@ -1190,7 +1189,7 @@
         api_errors::InvocationError("test.supportsPromises",
                                     "integer int, function callback",
                                     api_errors::NoMatchingSignature());
-    RunFunctionAndExpectError(function, context, base::size(args), args,
+    RunFunctionAndExpectError(function, context, std::size(args), args,
                               expected_error);
   }
 }
@@ -1220,7 +1219,7 @@
 
   TestJSRunner::AllowErrors allow_errors;
   RunFunctionAndExpectError(function, context, v8::Undefined(isolate()),
-                            base::size(args), args,
+                            std::size(args), args,
                             "Uncaught Error: Custom Hook Error");
 }
 
@@ -1266,7 +1265,7 @@
     v8::Local<v8::Value> args[] = {binding_object};
 
     v8::Local<v8::Value> result = RunFunction(
-        function, context, v8::Undefined(isolate()), base::size(args), args);
+        function, context, v8::Undefined(isolate()), std::size(args), args);
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetValueAs(result, &promise));
     EXPECT_EQ(v8::Promise::kFulfilled, promise->State());
@@ -1281,7 +1280,7 @@
     v8::Local<v8::Value> args[] = {binding_object};
 
     v8::Local<v8::Value> result = RunFunction(
-        function, context, v8::Undefined(isolate()), base::size(args), args);
+        function, context, v8::Undefined(isolate()), std::size(args), args);
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetValueAs(result, &promise));
     EXPECT_EQ(v8::Promise::kRejected, promise->State());
@@ -1307,7 +1306,7 @@
         FunctionFromString(context, kFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object, last_error_parent};
 
-    RunFunction(function, context, v8::Undefined(isolate()), base::size(args),
+    RunFunction(function, context, v8::Undefined(isolate()), std::size(args),
                 args);
 
     // In the case of errors, callbacks are not passed any arguments.
@@ -1335,7 +1334,7 @@
         FunctionFromString(context, kFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object, last_error_parent};
 
-    RunFunction(function, context, v8::Undefined(isolate()), base::size(args),
+    RunFunction(function, context, v8::Undefined(isolate()), std::size(args),
                 args);
     ASSERT_EQ(1u, console_errors().size());
     EXPECT_THAT(console_errors()[0],
@@ -1386,12 +1385,12 @@
   EXPECT_DEATH(
       {
         RunFunction(function, context, v8::Undefined(isolate()),
-                    base::size(args), args);
+                    std::size(args), args);
       },
       "Check failed: false. No callback found for the specified request ID.");
 #else
   v8::Local<v8::Value> result = RunFunction(
-      function, context, v8::Undefined(isolate()), base::size(args), args);
+      function, context, v8::Undefined(isolate()), std::size(args), args);
   v8::Local<v8::Promise> promise;
   ASSERT_TRUE(GetValueAs(result, &promise));
   EXPECT_EQ(v8::Promise::kFulfilled, promise->State());
@@ -1435,7 +1434,7 @@
       context, "(function(obj) { return obj.oneString('ping'); })");
   v8::Local<v8::Value> args[] = {binding_object};
 
-  RunFunction(function, context, v8::Undefined(isolate()), base::size(args),
+  RunFunction(function, context, v8::Undefined(isolate()), std::size(args),
               args);
 
   // The context should be properly invalidated, and the second hook (which
@@ -1492,7 +1491,7 @@
             context, "(function(obj) { return obj.oneString('throw'); })");
     v8::Local<v8::Value> args[] = {binding_object};
     RunFunctionAndExpectError(function, context, v8::Undefined(isolate()),
-                              base::size(args), args,
+                              std::size(args), args,
                               "Uncaught Error: Custom Hook Error");
   }
 
@@ -1503,7 +1502,7 @@
                            "(function(obj) { return obj.oneString('ping'); })");
     v8::Local<v8::Value> args[] = {binding_object};
     v8::Local<v8::Value> result =
-        RunFunction(function, context, base::size(args), args);
+        RunFunction(function, context, std::size(args), args);
     ASSERT_FALSE(result.IsEmpty());
     std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context);
     ASSERT_TRUE(json_result);
@@ -1590,13 +1589,13 @@
 
   v8::Local<v8::Value> argv[] = {binding_object};
 
-  RunFunction(function, context, base::size(argv), argv);
+  RunFunction(function, context, std::size(argv), argv);
   ASSERT_TRUE(last_request());
   EXPECT_FALSE(last_request()->has_user_gesture);
   reset_last_request();
 
   ScopedTestUserActivation test_user_activation;
-  RunFunction(function, context, base::size(argv), argv);
+  RunFunction(function, context, std::size(argv), argv);
   ASSERT_TRUE(last_request());
   EXPECT_TRUE(last_request()->has_user_gesture);
 
@@ -1652,10 +1651,10 @@
         GetPropertyFromObject(binding_object, context, name);
     v8::Local<v8::Value> args[] = {event};
     if (expect_supports) {
-      RunFunction(function, context, context->Global(), base::size(args), args);
+      RunFunction(function, context, context->Global(), std::size(args), args);
     } else {
       RunFunctionAndExpectError(
-          function, context, context->Global(), base::size(args), args,
+          function, context, context->Global(), std::size(args), args,
           "Uncaught TypeError: This event does not support filters");
     }
   };
@@ -1870,7 +1869,7 @@
     v8::TryCatch try_catch(context->GetIsolate());
     // The throwException call will throw an exception; ignore it.
     std::ignore = call->Call(context, v8::Undefined(context->GetIsolate()),
-                             base::size(args), args);
+                             std::size(args), args);
   };
 
   call_api_method("modifyArgs", "");
@@ -1994,7 +1993,7 @@
   binding::InvalidateContext(context);
 
   v8::Local<v8::Value> argv[] = {binding_object};
-  RunFunctionAndExpectError(function, context, base::size(argv), argv,
+  RunFunctionAndExpectError(function, context, std::size(argv), argv,
                             "Uncaught Error: Extension context invalidated.");
 }
 
@@ -2081,7 +2080,7 @@
     v8::Local<v8::Function> promise_api_call =
         FunctionFromString(context, kFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object};
-    RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+    RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetPropertyFromObjectAs(context->Global(), context, "apiResult",
@@ -2109,7 +2108,7 @@
     v8::Local<v8::Function> promise_api_call =
         FunctionFromString(context, kFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object};
-    RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+    RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     ASSERT_TRUE(last_request());
     request_handler()->CompleteRequest(last_request()->request_id,
@@ -2135,7 +2134,7 @@
         api_errors::InvocationError("test.supportsPromises",
                                     "integer int, function callback",
                                     api_errors::NoMatchingSignature());
-    RunFunctionAndExpectError(promise_api_call, context, base::size(args), args,
+    RunFunctionAndExpectError(promise_api_call, context, std::size(args), args,
                               expected_error);
   }
   // Test that required callbacks still work when the context doesn't support
@@ -2150,7 +2149,7 @@
     v8::Local<v8::Function> promise_api_call =
         FunctionFromString(context, kFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object};
-    RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+    RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     ASSERT_TRUE(last_request());
     request_handler()->CompleteRequest(last_request()->request_id,
@@ -2170,7 +2169,7 @@
     v8::Local<v8::Function> promise_api_call =
         FunctionFromString(context, kCallbackOptionalFunctionCall);
     v8::Local<v8::Value> args[] = {binding_object};
-    RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+    RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     ASSERT_TRUE(last_request());
 
@@ -2212,7 +2211,7 @@
         context, "(function(api) { return api.supportsPromises(1); });");
     v8::Local<v8::Value> args[] = {binding_object};
     v8::Local<v8::Value> api_result =
-        RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+        RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetValueAs(api_result, &promise));
@@ -2232,7 +2231,7 @@
     EXPECT_EQ(R"("foo")", V8ToString(callback_arguments[0], context));
 
     RunFunctionOnGlobal(resolve_callback, context,
-                        base::size(callback_arguments), callback_arguments);
+                        std::size(callback_arguments), callback_arguments);
 
     EXPECT_EQ(v8::Promise::kFulfilled, promise->State());
     EXPECT_EQ(R"("foo")", V8ToString(promise->Result(), context));
@@ -2245,7 +2244,7 @@
         context, "(function(api) { return api.supportsPromises(2); });");
     v8::Local<v8::Value> args[] = {binding_object};
     v8::Local<v8::Value> api_result =
-        RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+        RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     v8::Local<v8::Promise> promise;
     ASSERT_TRUE(GetValueAs(api_result, &promise));
@@ -2266,7 +2265,7 @@
         context, "(function(api) { return api.supportsPromises(3) });");
     v8::Local<v8::Value> args[] = {binding_object};
     v8::Local<v8::Value> api_result =
-        RunFunctionOnGlobal(promise_api_call, context, base::size(args), args);
+        RunFunctionOnGlobal(promise_api_call, context, std::size(args), args);
 
     v8::Local<v8::Promise> promise = api_result.As<v8::Promise>();
     ASSERT_FALSE(api_result.IsEmpty());
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.cc b/extensions/renderer/bindings/api_bindings_system_unittest.cc
index 93511d7..29dab4d 100644
--- a/extensions/renderer/bindings/api_bindings_system_unittest.cc
+++ b/extensions/renderer/bindings/api_bindings_system_unittest.cc
@@ -2,12 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/renderer/bindings/api_bindings_system.h"
+#include "extensions/renderer/bindings/api_bindings_system_unittest.h"
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/containers/contains.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "extensions/common/mojom/event_dispatcher.mojom.h"
@@ -16,7 +15,7 @@
 #include "extensions/renderer/bindings/api_binding_hooks_test_delegate.h"
 #include "extensions/renderer/bindings/api_binding_test_util.h"
 #include "extensions/renderer/bindings/api_binding_types.h"
-#include "extensions/renderer/bindings/api_bindings_system_unittest.h"
+#include "extensions/renderer/bindings/api_bindings_system.h"
 #include "extensions/renderer/bindings/api_invocation_errors.h"
 #include "extensions/renderer/bindings/test_interaction_provider.h"
 #include "gin/arguments.h"
@@ -304,7 +303,7 @@
     v8::Local<v8::Function> function = FunctionFromString(context, kTestCall);
     v8::Local<v8::Value> args[] = {alpha_api};
     RunFunctionAndExpectError(
-        function, context, base::size(args), args,
+        function, context, std::size(args), args,
         "Uncaught TypeError: " +
             api_errors::InvocationError(
                 "alpha.functionWithEnum", "alpha.enumRef e",
@@ -414,7 +413,7 @@
   v8::Local<v8::Function> function =
       FunctionFromString(context, kCustomCallbackHook);
   v8::Local<v8::Value> args[] = {js_hooks};
-  RunFunctionOnGlobal(function, context, base::size(args), args);
+  RunFunctionOnGlobal(function, context, std::size(args), args);
 
   const char kTestCall[] = R"(
       obj.functionWithCallback('foo', function() {
@@ -460,7 +459,7 @@
   v8::Local<v8::Function> function =
       FunctionFromString(context, kCustomCallbackHook);
   v8::Local<v8::Value> args[] = {js_hooks};
-  RunFunctionOnGlobal(function, context, base::size(args), args);
+  RunFunctionOnGlobal(function, context, std::size(args), args);
 
   const char kTestCall[] = R"(return obj.functionWithCallback('bar');)";
   v8::Local<v8::Value> result =
@@ -497,7 +496,7 @@
   v8::Local<v8::Function> function =
       FunctionFromString(context, kCustomCallbackThrowHook);
   v8::Local<v8::Value> args[] = {js_hooks};
-  RunFunctionOnGlobal(function, context, base::size(args), args);
+  RunFunctionOnGlobal(function, context, std::size(args), args);
 
   const char kTestCall[] = R"(
       obj.functionWithCallback('baz', function() {
@@ -539,7 +538,7 @@
   v8::Local<v8::Function> function =
       FunctionFromString(context, kCustomCallbackThrowHook);
   v8::Local<v8::Value> args[] = {js_hooks};
-  RunFunctionOnGlobal(function, context, base::size(args), args);
+  RunFunctionOnGlobal(function, context, std::size(args), args);
 
   const char kTestCall[] = R"(return obj.functionWithCallback('boz');)";
   v8::Local<v8::Value> result =
diff --git a/extensions/renderer/bindings/api_event_handler.cc b/extensions/renderer/bindings/api_event_handler.cc
index ce35091..e853405 100644
--- a/extensions/renderer/bindings/api_event_handler.cc
+++ b/extensions/renderer/bindings/api_event_handler.cc
@@ -13,7 +13,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/supports_user_data.h"
 #include "base/values.h"
@@ -292,7 +291,7 @@
 
     v8::Local<v8::Value> massager_args[] = {args_array, dispatch_event};
     JSRunner::Get(context)->RunJSFunction(
-        massager, context, base::size(massager_args), massager_args);
+        massager, context, std::size(massager_args), massager_args);
   }
 }
 
diff --git a/extensions/renderer/bindings/api_event_handler_unittest.cc b/extensions/renderer/bindings/api_event_handler_unittest.cc
index 576f02a..e4c2c44 100644
--- a/extensions/renderer/bindings/api_event_handler_unittest.cc
+++ b/extensions/renderer/bindings/api_event_handler_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/mock_callback.h"
@@ -46,7 +45,7 @@
   v8::Local<v8::Function> add_listener =
       FunctionFromString(context, kAddListenerFunction);
   v8::Local<v8::Value> argv[] = {event, listener};
-  RunFunction(add_listener, context, base::size(argv), argv);
+  RunFunction(add_listener, context, std::size(argv), argv);
 }
 
 void RemoveListener(v8::Local<v8::Context> context,
@@ -55,7 +54,7 @@
   v8::Local<v8::Function> remove_listener =
       FunctionFromString(context, kRemoveListenerFunction);
   v8::Local<v8::Value> argv[] = {event, listener};
-  RunFunction(remove_listener, context, base::size(argv), argv);
+  RunFunction(remove_listener, context, std::size(argv), argv);
 }
 
 class APIEventHandlerTest : public APIBindingTest {
@@ -130,7 +129,7 @@
   {
     v8::Local<v8::Value> argv[] = {event, listener_function};
     v8::Local<v8::Value> result =
-        RunFunction(has_listener_function, context, base::size(argv), argv);
+        RunFunction(has_listener_function, context, std::size(argv), argv);
     bool has_listener = false;
     EXPECT_TRUE(gin::Converter<bool>::FromV8(isolate(), result, &has_listener));
     EXPECT_TRUE(has_listener);
@@ -142,7 +141,7 @@
         FunctionFromString(context, "(function() {})");
     v8::Local<v8::Value> argv[] = {event, not_a_listener};
     v8::Local<v8::Value> result =
-        RunFunction(has_listener_function, context, base::size(argv), argv);
+        RunFunction(has_listener_function, context, std::size(argv), argv);
     bool has_listener = false;
     EXPECT_TRUE(gin::Converter<bool>::FromV8(isolate(), result, &has_listener));
     EXPECT_FALSE(has_listener);
@@ -156,7 +155,7 @@
   {
     v8::Local<v8::Value> argv[] = {event};
     v8::Local<v8::Value> result =
-        RunFunction(has_listeners_function, context, base::size(argv), argv);
+        RunFunction(has_listeners_function, context, std::size(argv), argv);
     bool has_listeners = false;
     EXPECT_TRUE(
         gin::Converter<bool>::FromV8(isolate(), result, &has_listeners));
@@ -169,7 +168,7 @@
   {
     v8::Local<v8::Value> argv[] = {event};
     v8::Local<v8::Value> result =
-        RunFunction(has_listeners_function, context, base::size(argv), argv);
+        RunFunction(has_listeners_function, context, std::size(argv), argv);
     bool has_listeners = false;
     EXPECT_TRUE(
         gin::Converter<bool>::FromV8(isolate(), result, &has_listeners));
@@ -433,7 +432,7 @@
           "(function(event) { event.dispatch(42, 'foo', {bar: 'baz'}); })");
   {
     v8::Local<v8::Value> argv[] = {event};
-    RunFunctionOnGlobal(fire_event_function, context, base::size(argv), argv);
+    RunFunctionOnGlobal(fire_event_function, context, std::size(argv), argv);
   }
 
   EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]",
@@ -457,7 +456,7 @@
             context,
            "(function(event) { this.testEvent = event; })");
     v8::Local<v8::Value> args[] = {event};
-    RunFunctionOnGlobal(set_event_on_global, context, base::size(args), args);
+    RunFunctionOnGlobal(set_event_on_global, context, std::size(args), args);
     EXPECT_EQ(event,
               GetPropertyFromObject(context->Global(), context, "testEvent"));
   }
@@ -767,7 +766,7 @@
       V8ValueFromScriptSource(context, "['primary', 'secondary']"),
   };
   RunFunction(dispatch_value.As<v8::Function>(), context,
-              base::size(dispatch_args), dispatch_args);
+              std::size(dispatch_args), dispatch_args);
 
   EXPECT_EQ(
       "[\"primary\",\"secondary\"]",
@@ -873,7 +872,7 @@
       FunctionFromString(context, kDispatchEventFunction);
 
   v8::Local<v8::Value> dispatch_argv[] = {event};
-  RunFunction(dispatch_function, context, base::size(dispatch_argv),
+  RunFunction(dispatch_function, context, std::size(dispatch_argv),
               dispatch_argv);
 
   EXPECT_EQ("[1,2,3]", GetStringPropertyFromObject(context->Global(), context,
@@ -886,7 +885,7 @@
 
   // Invalidate the event and try dispatching again. Nothing should happen.
   handler.InvalidateCustomEvent(context, event);
-  RunFunction(dispatch_function, context, base::size(dispatch_argv),
+  RunFunction(dispatch_function, context, std::size(dispatch_argv),
               dispatch_argv);
   EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(), context,
                                                      "eventArgs"));
@@ -910,7 +909,7 @@
       "})";
   v8::Local<v8::Value> add_listener_argv[] = {event};
   RunFunction(FunctionFromString(context, kLocalAddListenerFunction), context,
-              base::size(add_listener_argv), add_listener_argv);
+              std::size(add_listener_argv), add_listener_argv);
 
   DisposeContext(context);
 }
@@ -1136,7 +1135,7 @@
       v8::Local<v8::Value> argv[] = {event, listener1};
       // Note: Use JSRunner() so that script suspension is respected.
       JSRunner::Get(context)->RunJSFunction(remove_listener_function, context,
-                                            base::size(argv), argv);
+                                            std::size(argv), argv);
     }
 
     // Since script has been suspended, there should still be two listeners, and
diff --git a/extensions/renderer/bindings/declarative_event_unittest.cc b/extensions/renderer/bindings/declarative_event_unittest.cc
index 35897e85..3816b1b2 100644
--- a/extensions/renderer/bindings/declarative_event_unittest.cc
+++ b/extensions/renderer/bindings/declarative_event_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "extensions/common/extension_api.h"
@@ -145,7 +144,7 @@
     v8::Local<v8::Function> function =
         FunctionFromString(context, base::StringPrintf(kAddRules, kGoodRules));
     v8::Local<v8::Value> args[] = {emitter_value};
-    RunFunctionOnGlobal(function, context, base::size(args), args);
+    RunFunctionOnGlobal(function, context, std::size(args), args);
 
     EXPECT_TRUE(last_request());
     reset_last_request();
@@ -172,7 +171,7 @@
       v8::Local<v8::Function> function =
           FunctionFromString(context, base::StringPrintf(kAddRules, rules));
       v8::Local<v8::Value> args[] = {emitter_value};
-      RunFunctionAndExpectError(function, context, base::size(args), args,
+      RunFunctionAndExpectError(function, context, std::size(args), args,
                                 "Uncaught TypeError: Invalid invocation");
       EXPECT_FALSE(last_request()) << rules;
       reset_last_request();
@@ -225,7 +224,7 @@
              }))";
     v8::Local<v8::Function> add_rules_func =
         FunctionFromString(context, kAddRules);
-    RunFunctionOnGlobal(add_rules_func, context, base::size(args), args);
+    RunFunctionOnGlobal(add_rules_func, context, std::size(args), args);
     ValidateLastRequest("events.addRules",
                         "['alpha.declarativeEvent',0,"
                         "[{'actions':['cat'],"
@@ -241,7 +240,7 @@
         "})";
     v8::Local<v8::Function> remove_rules =
         FunctionFromString(context, kRemoveRules);
-    RunFunctionOnGlobal(remove_rules, context, base::size(args), args);
+    RunFunctionOnGlobal(remove_rules, context, std::size(args), args);
     ValidateLastRequest("events.removeRules",
                         "['alpha.declarativeEvent',0,['rule']]");
     reset_last_request();
@@ -254,7 +253,7 @@
         "})";
     v8::Local<v8::Function> remove_rules =
         FunctionFromString(context, kGetRules);
-    RunFunctionOnGlobal(remove_rules, context, base::size(args), args);
+    RunFunctionOnGlobal(remove_rules, context, std::size(args), args);
     ValidateLastRequest("events.getRules", "['alpha.declarativeEvent',0,null]");
     reset_last_request();
   }
diff --git a/extensions/renderer/bindings/event_emitter_unittest.cc b/extensions/renderer/bindings/event_emitter_unittest.cc
index e7cfa365..7b29961 100644
--- a/extensions/renderer/bindings/event_emitter_unittest.cc
+++ b/extensions/renderer/bindings/event_emitter_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "extensions/common/mojom/event_dispatcher.mojom.h"
 #include "extensions/renderer/bindings/api_binding_test.h"
@@ -80,7 +79,7 @@
     v8::Local<v8::Function> listener_function =
         FunctionFromString(context, listener);
     v8::Local<v8::Value> args[] = {v8_event, listener_function};
-    RunFunction(add_listener_function, context, base::size(args), args);
+    RunFunction(add_listener_function, context, std::size(args), args);
   };
 
   const char kListener1[] =
@@ -119,7 +118,7 @@
   TestJSRunner::AllowErrors allow_errors;
   v8::Local<v8::Value> dispatch_result =
       RunFunctionOnGlobal(FunctionFromString(context, kDispatch), context,
-                          base::size(dispatch_args), dispatch_args);
+                          std::size(dispatch_args), dispatch_args);
 
   const char kExpectedEventArgs[] = "[\"arg1\",2]";
   for (const char* property :
@@ -181,7 +180,7 @@
                           v8::External::New(isolate(), &closure_data))
             .ToLocalChecked();
     v8::Local<v8::Value> args[] = {v8_event, listener};
-    RunFunction(add_listener_function, context, base::size(args), args);
+    RunFunction(add_listener_function, context, std::size(args), args);
   }
 
   EXPECT_EQ(kNumListeners, event->GetNumListeners());
diff --git a/extensions/renderer/bindings/exception_handler.cc b/extensions/renderer/bindings/exception_handler.cc
index 65d6625..aa8587a4 100644
--- a/extensions/renderer/bindings/exception_handler.cc
+++ b/extensions/renderer/bindings/exception_handler.cc
@@ -5,7 +5,6 @@
 #include "extensions/renderer/bindings/exception_handler.h"
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/supports_user_data.h"
 #include "extensions/renderer/bindings/api_binding_util.h"
@@ -104,7 +103,7 @@
     v8::TryCatch handler_try_catch(isolate);
     handler_try_catch.SetVerbose(true);
     JSRunner::Get(context)->RunJSFunction(handler, context,
-                                          base::size(arguments), arguments);
+                                          std::size(arguments), arguments);
   } else {
     add_console_error_.Run(context, full_message);
   }
diff --git a/extensions/renderer/declarative_content_hooks_delegate.cc b/extensions/renderer/declarative_content_hooks_delegate.cc
index 2b9e213..34d2c1b 100644
--- a/extensions/renderer/declarative_content_hooks_delegate.cc
+++ b/extensions/renderer/declarative_content_hooks_delegate.cc
@@ -5,7 +5,6 @@
 #include "extensions/renderer/declarative_content_hooks_delegate.h"
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "extensions/common/api/declarative/declarative_constants.h"
 #include "extensions/renderer/bindings/api_type_reference_map.h"
 #include "extensions/renderer/bindings/argument_spec.h"
@@ -182,7 +181,7 @@
       {declarative_content_constants::kRequestContentScript,
        "RequestContentScript"},
   };
-  callbacks_.reserve(base::size(kTypes));
+  callbacks_.reserve(std::size(kTypes));
   for (const auto& type : kTypes) {
     const ArgumentSpec* spec = type_refs.GetSpec(type.full_name);
     DCHECK(spec);
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 4cec3648..22bf85b 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -13,7 +13,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/debug/alias.h"
 #include "base/feature_list.h"
 #include "base/lazy_instance.h"
@@ -622,7 +621,7 @@
       // The logging module.
       logging->NewInstance(),
   };
-  context->SafeCallFunction(main_function, base::size(args), args);
+  context->SafeCallFunction(main_function, std::size(args), args);
 
   const base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
   UMA_HISTOGRAM_TIMES(
@@ -1023,7 +1022,7 @@
     std::string& error = extension_load_errors_[extension_id];
     char minidump[256];
     base::debug::Alias(&minidump);
-    base::snprintf(minidump, base::size(minidump), "e::dispatcher:%s:%s",
+    base::snprintf(minidump, std::size(minidump), "e::dispatcher:%s:%s",
                    extension_id.c_str(), error.c_str());
     LOG(FATAL) << extension_id << " was never loaded: " << error;
   }
diff --git a/extensions/renderer/extension_throttle_simulation_unittest.cc b/extensions/renderer/extension_throttle_simulation_unittest.cc
index d54c35c..3a35c028 100644
--- a/extensions/renderer/extension_throttle_simulation_unittest.cc
+++ b/extensions/renderer/extension_throttle_simulation_unittest.cc
@@ -676,7 +676,7 @@
   // If things don't converge by the time we've done 100K trials, then
   // clearly one or more of the expected intervals are wrong.
   while (global_stats.num_runs < 100000) {
-    for (size_t i = 0; i < base::size(trials); ++i) {
+    for (size_t i = 0; i < std::size(trials); ++i) {
       ++global_stats.num_runs;
       ++trials[i].stats.num_runs;
       double ratio_unprotected = SimulateDowntime(
@@ -704,7 +704,7 @@
 
   // Print individual trial results for optional manual evaluation.
   double max_increase_ratio = 0.0;
-  for (size_t i = 0; i < base::size(trials); ++i) {
+  for (size_t i = 0; i < std::size(trials); ++i) {
     double increase_ratio;
     trials[i].stats.DidConverge(&increase_ratio);
     max_increase_ratio = std::max(max_increase_ratio, increase_ratio);
diff --git a/extensions/renderer/extension_throttle_unittest.cc b/extensions/renderer/extension_throttle_unittest.cc
index b40bfeaa..f41bd1b4 100644
--- a/extensions/renderer/extension_throttle_unittest.cc
+++ b/extensions/renderer/extension_throttle_unittest.cc
@@ -4,7 +4,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "extensions/renderer/extension_throttle_entry.h"
@@ -217,7 +216,7 @@
       TimeAndBool(now_ - lifetime, true, __LINE__),
       TimeAndBool(now_ - (lifetime + kFiveMs), true, __LINE__)};
 
-  for (unsigned int i = 0; i < base::size(test_values); ++i) {
+  for (unsigned int i = 0; i < std::size(test_values); ++i) {
     entry_->set_exponential_backoff_release_time(test_values[i].time);
     EXPECT_EQ(entry_->IsEntryOutdated(), test_values[i].result)
         << "Test case #" << i << " line " << test_values[i].line << " failed";
@@ -301,7 +300,7 @@
       GurlAndString(GURL("http://www.example.com:1234/"),
                     std::string("http://www.example.com:1234/"), __LINE__)};
 
-  for (unsigned int i = 0; i < base::size(test_values); ++i) {
+  for (unsigned int i = 0; i < std::size(test_values); ++i) {
     std::string temp = manager.GetIdFromUrl(test_values[i].url);
     EXPECT_EQ(temp, test_values[i].result)
         << "Test case #" << i << " line " << test_values[i].line << " failed";
diff --git a/extensions/renderer/gin_port_unittest.cc b/extensions/renderer/gin_port_unittest.cc
index 26db87d..840ea1ff 100644
--- a/extensions/renderer/gin_port_unittest.cc
+++ b/extensions/renderer/gin_port_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "content/public/common/content_features.h"
 #include "extensions/common/api/messaging/message.h"
@@ -150,7 +149,7 @@
   v8::Local<v8::Function> test_function =
       FunctionFromString(context, kTestFunction);
   v8::Local<v8::Value> args[] = {port_obj};
-  RunFunctionOnGlobal(test_function, context, base::size(args), args);
+  RunFunctionOnGlobal(test_function, context, std::size(args), args);
 
   port->DispatchOnMessage(
       context, Message(R"({"foo":42})", SerializationFormat::kJson, false));
@@ -183,7 +182,7 @@
     v8::Local<v8::Value> args[] = {port_obj};
 
     if (expected_port_id) {
-      RunFunction(v8_function, context, base::size(args), args);
+      RunFunction(v8_function, context, std::size(args), args);
       ASSERT_TRUE(delegate()->last_port_id());
       EXPECT_EQ(*expected_port_id, delegate()->last_port_id());
       ASSERT_TRUE(delegate()->last_message());
@@ -191,7 +190,7 @@
       EXPECT_EQ(expected_message->user_gesture,
                 delegate()->last_message()->user_gesture);
     } else {
-      RunFunctionAndExpectError(v8_function, context, base::size(args), args,
+      RunFunctionAndExpectError(v8_function, context, std::size(args), args,
                                 "Uncaught Error: Could not serialize message.");
       EXPECT_FALSE(delegate()->last_port_id());
       EXPECT_FALSE(delegate()->last_message())
@@ -256,7 +255,7 @@
     v8::Local<v8::Function> function = FunctionFromString(context, kFunction);
     v8::Local<v8::Value> args[] = {port_obj};
     RunFunctionAndExpectError(
-        function, context, base::size(args), args,
+        function, context, std::size(args), args,
         "Uncaught Error: Attempting to use a disconnected port object");
 
     EXPECT_FALSE(delegate()->last_port_id());
@@ -287,7 +286,7 @@
   v8::Local<v8::Function> test_function =
       FunctionFromString(context, kTestFunction);
   v8::Local<v8::Value> args[] = {port_obj};
-  RunFunctionOnGlobal(test_function, context, base::size(args), args);
+  RunFunctionOnGlobal(test_function, context, std::size(args), args);
 
   port->DispatchOnDisconnect(context);
   EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context,
@@ -311,7 +310,7 @@
   const char kFunction[] = "(function(port) { port.disconnect(); })";
   v8::Local<v8::Function> function = FunctionFromString(context, kFunction);
   v8::Local<v8::Value> args[] = {port_obj};
-  RunFunction(function, context, base::size(args), args);
+  RunFunction(function, context, std::size(args), args);
   ::testing::Mock::VerifyAndClearExpectations(delegate());
   EXPECT_TRUE(port->is_closed_for_testing());
 }
@@ -337,7 +336,7 @@
   v8::Local<v8::Function> test_function =
       FunctionFromString(context, kTestFunction);
   v8::Local<v8::Value> args[] = {port_obj};
-  RunFunctionOnGlobal(test_function, context, base::size(args), args);
+  RunFunctionOnGlobal(test_function, context, std::size(args), args);
 
   port->DispatchOnDisconnect(context);
   EXPECT_TRUE(port->is_closed_for_testing());
@@ -368,7 +367,7 @@
   v8::Local<v8::Function> test_function =
       FunctionFromString(context, kTestFunction);
   v8::Local<v8::Value> args[] = {port_obj};
-  RunFunctionOnGlobal(test_function, context, base::size(args), args);
+  RunFunctionOnGlobal(test_function, context, std::size(args), args);
 
   port->DispatchOnDisconnect(context);
   EXPECT_EQ(
@@ -441,7 +440,7 @@
         get_on_disconnect_function}) {
     SCOPED_TRACE(gin::V8ToString(isolate(),
                                  function->ToString(context).ToLocalChecked()));
-    RunFunctionAndExpectError(function, context, base::size(function_args),
+    RunFunctionAndExpectError(function, context, std::size(function_args),
                               function_args,
                               "Uncaught Error: Extension context invalidated.");
   }
@@ -462,7 +461,7 @@
 
   v8::Local<v8::Value> args[] = {port_obj};
   v8::Local<v8::Value> result =
-      RunFunction(change_port_name, context, base::size(args), args);
+      RunFunction(change_port_name, context, std::size(args), args);
   EXPECT_EQ(R"("foo")", V8ToString(result, context));
 }
 
diff --git a/extensions/renderer/guest_view/mime_handler_view/post_message_support.cc b/extensions/renderer/guest_view/mime_handler_view/post_message_support.cc
index 74b6a77..87841a5d 100644
--- a/extensions/renderer/guest_view/mime_handler_view/post_message_support.cc
+++ b/extensions/renderer/guest_view/mime_handler_view/post_message_support.cc
@@ -151,7 +151,7 @@
       // should already know what is embedded.
       gin::StringToV8(isolate, "*")};
   delegate_->GetSourceFrame()->CallFunctionEvenIfScriptDisabled(
-      post_message.As<v8::Function>(), target_window_proxy, base::size(args),
+      post_message.As<v8::Function>(), target_window_proxy, std::size(args),
       args);
 }
 
diff --git a/extensions/renderer/i18n_hooks_delegate.cc b/extensions/renderer/i18n_hooks_delegate.cc
index 840dc27..648a206 100644
--- a/extensions/renderer/i18n_hooks_delegate.cc
+++ b/extensions/renderer/i18n_hooks_delegate.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/i18n/rtl.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
@@ -332,7 +331,7 @@
     DCHECK(arguments[1]->IsFunction());
     JSRunner::Get(v8_context)
         ->RunJSFunction(arguments[1].As<v8::Function>(), v8_context,
-                        base::size(response_args), response_args);
+                        std::size(response_args), response_args);
   } else {
     DCHECK_EQ(binding::AsyncResponseType::kPromise, parse_result.async_type);
     auto promise_resolver =
diff --git a/extensions/renderer/messaging_util_unittest.cc b/extensions/renderer/messaging_util_unittest.cc
index 73b2132d..f8481bab 100644
--- a/extensions/renderer/messaging_util_unittest.cc
+++ b/extensions/renderer/messaging_util_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "extensions/common/api/messaging/message.h"
 #include "extensions/common/api/messaging/serialization_format.h"
@@ -100,7 +99,7 @@
       {gin::StringToV8(isolate(), "invalid id"), base::StringPiece(), false},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Test Case: %d", static_cast<int>(i)));
     const auto& test_case = test_cases[i];
     std::string target;
@@ -135,7 +134,7 @@
       {gin::StringToV8(isolate(), "invalid id"), base::StringPiece(), false},
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     SCOPED_TRACE(base::StringPrintf("Test Case: %d", static_cast<int>(i)));
     const auto& test_case = test_cases[i];
     std::string target;
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc
index 4d39cee..814f811 100644
--- a/extensions/renderer/module_system.cc
+++ b/extensions/renderer/module_system.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -770,7 +769,7 @@
   {
     v8::TryCatch try_catch(GetIsolate());
     try_catch.SetCaptureMessage(true);
-    context_->SafeCallFunction(func, base::size(args), args);
+    context_->SafeCallFunction(func, std::size(args), args);
     if (try_catch.HasCaught()) {
       HandleException(try_catch);
       return v8::Undefined(GetIsolate());
diff --git a/extensions/renderer/native_extension_bindings_system_unittest.cc b/extensions/renderer/native_extension_bindings_system_unittest.cc
index f31816f..55b5393 100644
--- a/extensions/renderer/native_extension_bindings_system_unittest.cc
+++ b/extensions/renderer/native_extension_bindings_system_unittest.cc
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/renderer/native_extension_bindings_system_test_base.h"
+#include "extensions/renderer/native_extension_bindings_system.h"
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/bind.h"
 #include "build/build_config.h"
@@ -20,7 +19,7 @@
 #include "extensions/renderer/bindings/api_response_validator.h"
 #include "extensions/renderer/bindings/test_js_runner.h"
 #include "extensions/renderer/message_target.h"
-#include "extensions/renderer/native_extension_bindings_system.h"
+#include "extensions/renderer/native_extension_bindings_system_test_base.h"
 #include "extensions/renderer/script_context.h"
 #include "extensions/renderer/script_context_set.h"
 
@@ -431,7 +430,7 @@
               SendAddUnfilteredEventListenerIPC(script_context, kEventName))
       .Times(1);
   v8::Local<v8::Value> argv[] = {listener};
-  RunFunction(add_listener, context, base::size(argv), argv);
+  RunFunction(add_listener, context, std::size(argv), argv);
   ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
   EXPECT_TRUE(bindings_system()->HasEventListenerInContext(
       "idle.onStateChanged", script_context));
@@ -446,7 +445,7 @@
       .Times(1);
   v8::Local<v8::Function> remove_listener =
       FunctionFromString(context, kRemoveListener);
-  RunFunction(remove_listener, context, base::size(argv), argv);
+  RunFunction(remove_listener, context, std::size(argv), argv);
   ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
   EXPECT_FALSE(bindings_system()->HasEventListenerInContext(
       "idle.onStateChanged", script_context));
@@ -852,7 +851,7 @@
     // Trying to run a chrome.idle function should fail.
     v8::Local<v8::Value> args[] = {initial_idle};
     RunFunctionAndExpectError(
-        run_idle, context, base::size(args), args,
+        run_idle, context, std::size(args), args,
         "Uncaught Error: 'idle.queryState' is not available in this context.");
     EXPECT_FALSE(has_last_params());
   }
@@ -886,7 +885,7 @@
   {
     // Trying to run a chrome.idle function should now succeed.
     v8::Local<v8::Value> args[] = {initial_idle};
-    RunFunction(run_idle, context, base::size(args), args);
+    RunFunction(run_idle, context, std::size(args), args);
     EXPECT_EQ("idle.queryState", last_params().name);
   }
 }
@@ -1123,7 +1122,7 @@
 
     v8::Context::Scope context_scope(second_context);
     v8::Local<v8::Value> args[] = {chrome};
-    RunFunction(get_idle, second_context, base::size(args), args);
+    RunFunction(get_idle, second_context, std::size(args), args);
   }
 
   // The apiBridge should have been created in the owning (original) context,
diff --git a/extensions/renderer/native_renderer_messaging_service_unittest.cc b/extensions/renderer/native_renderer_messaging_service_unittest.cc
index 7cf2356a..37728ae 100644
--- a/extensions/renderer/native_renderer_messaging_service_unittest.cc
+++ b/extensions/renderer/native_renderer_messaging_service_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "components/crx_file/id_util.h"
 #include "content/public/common/child_process_host.h"
@@ -186,14 +185,14 @@
     v8::Local<v8::Function> add_on_message_listener = FunctionFromString(
         context, base::StringPrintf(kOnMessageListenerTemplate, kPort1Message));
     v8::Local<v8::Value> args[] = {port1.ToV8()};
-    RunFunctionOnGlobal(add_on_message_listener, context, base::size(args),
+    RunFunctionOnGlobal(add_on_message_listener, context, std::size(args),
                         args);
   }
   {
     v8::Local<v8::Function> add_on_message_listener = FunctionFromString(
         context, base::StringPrintf(kOnMessageListenerTemplate, kPort2Message));
     v8::Local<v8::Value> args[] = {port2.ToV8()};
-    RunFunctionOnGlobal(add_on_message_listener, context, base::size(args),
+    RunFunctionOnGlobal(add_on_message_listener, context, std::size(args),
                         args);
   }
 
@@ -244,7 +243,7 @@
         context,
         base::StringPrintf(kOnDisconnectListenerTemplate, kPort1Disconnect));
     v8::Local<v8::Value> args[] = {port1.ToV8()};
-    RunFunctionOnGlobal(add_on_disconnect_listener, context, base::size(args),
+    RunFunctionOnGlobal(add_on_disconnect_listener, context, std::size(args),
                         args);
   }
   {
@@ -252,7 +251,7 @@
         context,
         base::StringPrintf(kOnDisconnectListenerTemplate, kPort2Disconnect));
     v8::Local<v8::Value> args[] = {port2.ToV8()};
-    RunFunctionOnGlobal(add_on_disconnect_listener, context, base::size(args),
+    RunFunctionOnGlobal(add_on_disconnect_listener, context, std::size(args),
                         args);
   }
 
@@ -294,7 +293,7 @@
               SendPostMessageToPort(
                   port_id, Message(R"({"data":"hello"})",
                                    SerializationFormat::kJson, false)));
-  RunFunctionOnGlobal(post_message, context, base::size(args), args);
+  RunFunctionOnGlobal(post_message, context, std::size(args), args);
   ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
 }
 
@@ -319,7 +318,7 @@
 
   EXPECT_CALL(*ipc_message_sender(),
               SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true));
-  RunFunctionOnGlobal(post_message, context, base::size(args), args);
+  RunFunctionOnGlobal(post_message, context, std::size(args), args);
   ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
 }
 
diff --git a/extensions/renderer/one_time_message_handler_unittest.cc b/extensions/renderer/one_time_message_handler_unittest.cc
index 721df972..7544347 100644
--- a/extensions/renderer/one_time_message_handler_unittest.cc
+++ b/extensions/renderer/one_time_message_handler_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "extensions/common/api/messaging/message.h"
@@ -421,13 +420,13 @@
           port_id, Message("\"hi\"", SerializationFormat::kJson, false)));
   EXPECT_CALL(*ipc_message_sender(),
               SendCloseMessagePort(MSG_ROUTING_NONE, port_id, true));
-  RunFunction(reply.As<v8::Function>(), context, base::size(args), args);
+  RunFunction(reply.As<v8::Function>(), context, std::size(args), args);
   ::testing::Mock::VerifyAndClearExpectations(ipc_message_sender());
   EXPECT_FALSE(message_handler()->HasPort(script_context(), port_id));
 
   // Running the reply function a second time shouldn't do anything.
   // TODO(devlin): Add an error message.
-  RunFunction(reply.As<v8::Function>(), context, base::size(args), args);
+  RunFunction(reply.As<v8::Function>(), context, std::size(args), args);
   EXPECT_FALSE(message_handler()->HasPort(script_context(), port_id));
 }
 
diff --git a/extensions/renderer/render_frame_observer_natives.cc b/extensions/renderer/render_frame_observer_natives.cc
index dcaef88..80ea1a4 100644
--- a/extensions/renderer/render_frame_observer_natives.cc
+++ b/extensions/renderer/render_frame_observer_natives.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -113,7 +112,7 @@
   v8::HandleScope handle_scope(isolate);
   v8::Local<v8::Value> args[] = {v8::Boolean::New(isolate, succeeded)};
   context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, callback),
-                              base::size(args), args);
+                              std::size(args), args);
 }
 
 }  // namespace extensions
diff --git a/extensions/renderer/runtime_hooks_delegate.cc b/extensions/renderer/runtime_hooks_delegate.cc
index 605a0d2..ecfbb77 100644
--- a/extensions/renderer/runtime_hooks_delegate.cc
+++ b/extensions/renderer/runtime_hooks_delegate.cc
@@ -5,7 +5,6 @@
 #include "extensions/renderer/runtime_hooks_delegate.h"
 
 #include "base/containers/span.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
 #include "content/public/renderer/render_frame.h"
@@ -87,7 +86,7 @@
       ExtensionFrameHelper::GetV8BackgroundPageMainFrame(
           isolate, script_context->extension()->id());
   v8::Local<v8::Value> args[] = {background_page};
-  script_context->SafeCallFunction(info[0].As<v8::Function>(), base::size(args),
+  script_context->SafeCallFunction(info[0].As<v8::Function>(), std::size(args),
                                    args);
 }
 
diff --git a/extensions/renderer/storage_area_unittest.cc b/extensions/renderer/storage_area_unittest.cc
index 4240589..9cb2893 100644
--- a/extensions/renderer/storage_area_unittest.cc
+++ b/extensions/renderer/storage_area_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/renderer/storage_area.h"
 
-#include "base/cxx17_backports.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/values_test_util.h"
 #include "components/version_info/channel.h"
@@ -50,7 +49,7 @@
       FunctionFromString(context, kRunStorageGet);
   v8::Local<v8::Value> args[] = {storage_get};
   RunFunctionAndExpectError(
-      run_storage_get, context, base::size(args), args,
+      run_storage_get, context, std::size(args), args,
       "Uncaught TypeError: Illegal invocation: Function must be called on "
       "an object of type StorageArea");
 }
@@ -78,12 +77,12 @@
   v8::Local<v8::Function> run_storage_get =
       FunctionFromString(context, kRunStorageGet);
   v8::Local<v8::Value> args[] = {storage};
-  RunFunction(run_storage_get, context, base::size(args), args);
+  RunFunction(run_storage_get, context, std::size(args), args);
 
   DisposeContext(context);
 
   EXPECT_FALSE(binding::IsContextValid(context));
-  RunFunctionAndExpectError(run_storage_get, context, base::size(args), args,
+  RunFunctionAndExpectError(run_storage_get, context, std::size(args), args,
                             "Uncaught Error: Extension context invalidated.");
 }
 
@@ -111,7 +110,7 @@
       FunctionFromString(context, kRunStorageGet);
   v8::Local<v8::Value> args[] = {storage};
   RunFunctionAndExpectError(
-      run_storage_get, context, base::size(args), args,
+      run_storage_get, context, std::size(args), args,
       "Uncaught TypeError: " +
           api_errors::InvocationError(
               "storage.get",
@@ -184,7 +183,7 @@
       FunctionFromString(context, kRunStorageGet);
   v8::Local<v8::Value> args[] = {storage};
   v8::Local<v8::Value> return_value =
-      RunFunctionOnGlobal(run_storage_get, context, base::size(args), args);
+      RunFunctionOnGlobal(run_storage_get, context, std::size(args), args);
 
   ASSERT_TRUE(return_value->IsPromise());
   v8::Local<v8::Promise> promise = return_value.As<v8::Promise>();
@@ -238,7 +237,7 @@
           "storage.get",
           "optional [string|array|object] keys, function callback",
           api_errors::NoMatchingSignature());
-  RunFunctionAndExpectError(run_storage_get, context, base::size(args), args,
+  RunFunctionAndExpectError(run_storage_get, context, std::size(args), args,
                             expected_error);
 }
 
diff --git a/extensions/renderer/wake_event_page.cc b/extensions/renderer/wake_event_page.cc
index a685cc6f..3dbd4d5c 100644
--- a/extensions/renderer/wake_event_page.cc
+++ b/extensions/renderer/wake_event_page.cc
@@ -11,7 +11,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/worker_thread.h"
@@ -97,7 +96,7 @@
         v8::Boolean::New(isolate, success),
     };
     context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, callback),
-                                base::size(args), args);
+                                std::size(args), args);
   }
 
   MakeRequestCallback make_request_;
diff --git a/extensions/renderer/web_request_hooks.cc b/extensions/renderer/web_request_hooks.cc
index 90bdc55..858f89b 100644
--- a/extensions/renderer/web_request_hooks.cc
+++ b/extensions/renderer/web_request_hooks.cc
@@ -4,7 +4,6 @@
 
 #include "extensions/renderer/web_request_hooks.h"
 
-#include "base/cxx17_backports.h"
 #include "base/values.h"
 #include "content/public/renderer/v8_value_converter.h"
 #include "extensions/common/api/web_request.h"
@@ -83,7 +82,7 @@
   v8::TryCatch try_catch(isolate);
   v8::Local<v8::Value> event;
   if (!JSRunner::Get(context)
-           ->RunJSFunctionSync(get_event, context, base::size(args), args)
+           ->RunJSFunctionSync(get_event, context, std::size(args), args)
            .ToLocal(&event)) {
     // TODO(devlin): Do we care about the error? In theory, this should never
     // happen, so probably not.
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc
index 5316bcd5..1c7064d 100644
--- a/extensions/shell/browser/shell_content_browser_client.cc
+++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
 #include "components/nacl/common/buildflags.h"
 #include "content/public/browser/browser_main_runner.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -400,15 +399,14 @@
       switches::kExtensionProcess,
   };
   command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
-                                 kSwitchNames, base::size(kSwitchNames));
+                                 kSwitchNames, std::size(kSwitchNames));
 
 #if BUILDFLAG(ENABLE_NACL)
   static const char* const kNaclSwitchNames[] = {
       ::switches::kEnableNaClDebug,
   };
   command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
-                                 kNaclSwitchNames,
-                                 base::size(kNaclSwitchNames));
+                                 kNaclSwitchNames, std::size(kNaclSwitchNames));
 #endif  // BUILDFLAG(ENABLE_NACL)
 }
 
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index 90cd1809..3bb24e3 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -245,7 +245,7 @@
         embedder_support::kOriginTrialPublicKey,
     };
     command_line->CopySwitchesFrom(old_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
   }
 
   if (append_command_line_flags_callback_) {
diff --git a/headless/test/data/structured_doc_only_image.html b/headless/test/data/structured_doc_only_image.html
new file mode 100644
index 0000000..e980cbf
--- /dev/null
+++ b/headless/test/data/structured_doc_only_image.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html lang="en">
+<body>
+  <img src="svg_example_image.png" alt="Sample SVG image">
+</body>
+</html>
diff --git a/headless/test/headless_web_contents_browsertest.cc b/headless/test/headless_web_contents_browsertest.cc
index d4442eb..6e81c29 100644
--- a/headless/test/headless_web_contents_browsertest.cc
+++ b/headless/test/headless_web_contents_browsertest.cc
@@ -570,9 +570,33 @@
 }
 )";
 
+const char kExpectedImageOnlyStructTreeJSON[] = R"({
+   "lang": "en",
+   "type": "Document",
+   "~children": [ {
+      "type": "Div",
+      "~children": [ {
+         "alt": "Sample SVG image",
+         "type": "Figure"
+      } ]
+   } ]
+}
+)";
+
+struct TaggedPDFTestData {
+  const char* url;
+  const char* expected_json;
+};
+
+constexpr TaggedPDFTestData kTaggedPDFTestData[] = {
+    {"/structured_doc.html", kExpectedStructTreeJSON},
+    {"/structured_doc_only_image.html", kExpectedImageOnlyStructTreeJSON},
+};
+
 class HeadlessWebContentsTaggedPDFTest
     : public HeadlessAsyncDevTooledBrowserTest,
-      public page::Observer {
+      public page::Observer,
+      public ::testing::WithParamInterface<TaggedPDFTestData> {
  public:
   void RunDevTooledTest() override {
     EXPECT_TRUE(embedded_test_server()->Start());
@@ -584,7 +608,7 @@
     run_loop.Run();
 
     devtools_client_->GetPage()->Navigate(
-        embedded_test_server()->GetURL("/structured_doc.html").spec());
+        embedded_test_server()->GetURL(GetParam().url).spec());
   }
 
   void OnLoadEventFired(const page::LoadEventFiredParams&) override {
@@ -624,13 +648,17 @@
     // Map Windows line endings to Unix by removing '\r'.
     base::RemoveChars(json, "\r", &json);
 
-    EXPECT_EQ(kExpectedStructTreeJSON, json);
+    EXPECT_EQ(GetParam().expected_json, json);
 
     FinishAsynchronousTest();
   }
 };
 
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsTaggedPDFTest);
+HEADLESS_ASYNC_DEVTOOLED_TEST_P(HeadlessWebContentsTaggedPDFTest);
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         HeadlessWebContentsTaggedPDFTest,
+                         ::testing::ValuesIn(kTaggedPDFTestData));
 
 #endif  // BUILDFLAG(ENABLE_TAGGED_PDF)
 
diff --git a/infra/archive_config/win-archive-rel.json b/infra/archive_config/win-archive-rel.json
index 1e4d1ed..0aa6446c 100644
--- a/infra/archive_config/win-archive-rel.json
+++ b/infra/archive_config/win-archive-rel.json
@@ -176,6 +176,15 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Win_x64/{%position%}",
             "archive_type": "ARCHIVE_TYPE_FILES"
+        },
+        {
+            "files": [
+                "updater.exe.pdb",
+                "UpdaterSetup.exe.pdb"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Win_x64/{%position%}/updater-syms.zip",
+            "archive_type":"ARCHIVE_TYPE_ZIP"
         }
     ]
 }
diff --git a/infra/archive_config/win32-archive-rel.json b/infra/archive_config/win32-archive-rel.json
index 9a2f312e..378f9341 100644
--- a/infra/archive_config/win32-archive-rel.json
+++ b/infra/archive_config/win32-archive-rel.json
@@ -187,6 +187,15 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Win/{%position%}",
             "archive_type": "ARCHIVE_TYPE_FILES"
+        },
+        {
+            "files": [
+                "updater.exe.pdb",
+                "UpdaterSetup.exe.pdb"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Win/{%position%}/updater-syms.zip",
+            "archive_type":"ARCHIVE_TYPE_ZIP"
         }
     ]
 }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 848d01273..389edce 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -178,7 +178,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -257,7 +257,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -336,7 +336,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -415,7 +415,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -494,7 +494,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -573,7 +573,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -652,7 +652,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -2932,7 +2932,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8040,7 +8040,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8112,7 +8112,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8183,7 +8183,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8254,7 +8254,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8325,7 +8325,7 @@
       dimensions: "builder:Libfuzzer Upload Linux UBSan"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-16.04|Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       exe {
         cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
@@ -8395,7 +8395,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8467,7 +8467,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8539,7 +8539,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8610,7 +8610,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8681,7 +8681,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -8753,7 +8753,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -11748,7 +11748,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -11827,7 +11827,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -15525,7 +15525,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -15604,7 +15604,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -18599,7 +18599,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
@@ -18678,7 +18678,7 @@
       dimensions: "builderless:1"
       dimensions: "cores:8"
       dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-16.04"
+      dimensions: "os:Ubuntu-18.04"
       dimensions: "pool:luci.chromium.ci"
       dimensions: "ssd:0"
       exe {
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
index 6a916ce..4c64943 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -14,7 +14,7 @@
     execution_timeout = ci.DEFAULT_EXECUTION_TIMEOUT,
     goma_backend = goma.backend.RBE_PROD,
     notifies = ["chromesec-lkgr-failures"],
-    os = os.LINUX_DEFAULT,
+    os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT,
     pool = ci.DEFAULT_POOL,
     service_account = ci.DEFAULT_SERVICE_ACCOUNT,
 )
@@ -370,6 +370,7 @@
     triggering_policy = scheduler.greedy_batching(
         max_concurrent_invocations = 5,
     ),
+    os = os.LINUX_XENIAL_OR_BIONIC_REMOVE,
     goma_backend = None,
     reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI,
     reclient_instance = rbe_instance.DEFAULT,
diff --git a/infra/config/subprojects/chromium/ci/chromium.swangle.star b/infra/config/subprojects/chromium/ci/chromium.swangle.star
index 4a7c58f..0ca325d3 100644
--- a/infra/config/subprojects/chromium/ci/chromium.swangle.star
+++ b/infra/config/subprojects/chromium/ci/chromium.swangle.star
@@ -11,7 +11,6 @@
     builder_group = "chromium.swangle",
     executable = "recipe:angle_chromium",
     execution_timeout = ci.DEFAULT_EXECUTION_TIMEOUT,
-    goma_backend = goma.backend.RBE_PROD,
     pool = ci.gpu.POOL,
     service_account = ci.gpu.SERVICE_ACCOUNT,
     sheriff_rotations = sheriff_rotations.CHROMIUM_GPU,
@@ -89,6 +88,7 @@
         short_name = "x64",
     ),
     executable = ci.DEFAULT_EXECUTABLE,
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -98,6 +98,7 @@
         short_name = "x86",
     ),
     executable = ci.DEFAULT_EXECUTABLE,
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -106,6 +107,7 @@
         category = "ToT ANGLE|Windows",
         short_name = "x64",
     ),
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -114,6 +116,7 @@
         category = "ToT ANGLE|Windows",
         short_name = "x86",
     ),
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -122,6 +125,7 @@
         category = "ToT SwiftShader|Windows",
         short_name = "x64",
     ),
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -130,6 +134,7 @@
         category = "ToT SwiftShader|Windows",
         short_name = "x86",
     ),
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -139,6 +144,7 @@
         short_name = "x64",
     ),
     executable = ci.DEFAULT_EXECUTABLE,
+    goma_backend = goma.backend.RBE_PROD,
 )
 
 ci.gpu.windows_builder(
@@ -148,4 +154,5 @@
         short_name = "x86",
     ),
     executable = ci.DEFAULT_EXECUTABLE,
+    goma_backend = goma.backend.RBE_PROD,
 )
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm
index 0208eb5..68108707 100644
--- a/ios/chrome/app/application_delegate/metrics_mediator.mm
+++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -106,7 +106,7 @@
   struct kinfo_proc info;
   size_t length = sizeof(struct kinfo_proc);
   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)getpid()};
-  const int kr = sysctl(mib, base::size(mib), &info, &length, nullptr, 0);
+  const int kr = sysctl(mib, std::size(mib), &info, &length, nullptr, 0);
   DCHECK_EQ(KERN_SUCCESS, kr);
 
   const struct timeval time = info.kp_proc.p_starttime;
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 16a4a61..06dfc51 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2788,6 +2788,9 @@
       <message name="IDS_IOS_TAB_GRID_REGULAR_TABS_UNAVAILABLE_TITLE" desc="Title shown above a message in the Regular Tabs page of the tab grid when the IncognitoModeAvailability enterprise policy is set to forced. [iOS only]">
         Only Incognito Mode is Available
       </message>
+      <message name="IDS_IOS_TAB_GRID_SEARCH_RESULTS_EMPTY_TITLE" desc="Title shown above a message on the  tab switcher when there are no matching tabs for the given search terms. [iOS only]">
+        No Results Found
+      </message>
       <message name="IDS_IOS_TAB_GRID_CREATE_NEW_INCOGNITO_TAB" desc="The accessibility label for the button that creates new Incognito tabs. [iOS only]">
         Create new Incognito tab.
       </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_TAB_GRID_SEARCH_RESULTS_EMPTY_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_TAB_GRID_SEARCH_RESULTS_EMPTY_TITLE.png.sha1
new file mode 100644
index 0000000..2d7e3f7
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_TAB_GRID_SEARCH_RESULTS_EMPTY_TITLE.png.sha1
@@ -0,0 +1 @@
+8fe2239f30921d3bdd968ad276419be083b46a8c
\ No newline at end of file
diff --git a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
index e0b7a10..c442c81 100644
--- a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
@@ -4,7 +4,6 @@
 
 #import <UIKit/UIKit.h>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
@@ -949,7 +948,7 @@
   web::test::LoadHtml(kHTMLForTestingElements, web_state());
   ExecuteBooleanJavaScriptOnElementsAndCheck(
       javascript,
-      GetElementsByNameJavaScripts(elementsByName, base::size(elementsByName)),
+      GetElementsByNameJavaScripts(elementsByName, std::size(elementsByName)),
       GetElementsByNameJavaScripts(elements_with_true_expected,
                                    size_elements_with_true_expected));
 }
@@ -1003,7 +1002,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(
       @"__gCrWeb.fill.hasTagName(%@, 'input')", elements_expecting_true,
-      base::size(elements_expecting_true));
+      std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, CombineAndCollapseWhitespace) {
@@ -1244,7 +1243,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(
       @"__gCrWeb.fill.isAutofillableElement(%@)", elements_expecting_true,
-      base::size(elements_expecting_true));
+      std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, GetOptionStringsFromElement) {
@@ -1257,7 +1256,7 @@
        "__gCrWeb.fill.getOptionStringsFromElement(%@, field);"
        "__gCrWeb.stringify(field);",
       GetElementsByNameJavaScripts(testing_elements,
-                                   base::size(testing_elements)),
+                                   std::size(testing_elements)),
       @[
         @("{\"option_values\":[\"CA\",\"MA\"],"
           "\"option_contents\":[\"CA\",\"MA\"]}"),
@@ -1288,7 +1287,7 @@
     @"new name",
     @"MA",
   ];
-  for (size_t i = 0; i < base::size(elements); ++i) {
+  for (size_t i = 0; i < std::size(elements); ++i) {
     NSString* get_element_javascript = GetElementByNameJavaScript(elements[i]);
     NSString* new_value = [values objectAtIndex:i];
     EXPECT_NSEQ(
@@ -1310,7 +1309,7 @@
   const bool final_is_checked_values[] = {
       true, false, true, false, true, true,
   };
-  for (size_t i = 0; i < base::size(checkable_elements); ++i) {
+  for (size_t i = 0; i < std::size(checkable_elements); ++i) {
     NSString* get_element_javascript =
         GetElementByNameJavaScript(checkable_elements[i]);
     bool is_checked = final_is_checked_values[i];
@@ -1334,7 +1333,7 @@
       {"state", 0, 0},  // option element
       {"state", 0, 1},  // option element
   };
-  for (size_t i = 0; i < base::size(unchanged_elements); ++i) {
+  for (size_t i = 0; i < std::size(unchanged_elements); ++i) {
     NSString* get_element_javascript =
         GetElementByNameJavaScript(unchanged_elements[i]);
     NSString* actual = web::test::ExecuteJavaScript(
@@ -1359,7 +1358,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(@"__gCrWeb.fill.isTextInput(%@)",
                                           elements_expecting_true,
-                                          base::size(elements_expecting_true));
+                                          std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, IsSelectElement) {
@@ -1369,7 +1368,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(@"__gCrWeb.fill.isSelectElement(%@)",
                                           elements_expecting_true,
-                                          base::size(elements_expecting_true));
+                                          std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, IsCheckableElement) {
@@ -1380,7 +1379,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(
       @"__gCrWeb.fill.isCheckableElement(%@)", elements_expecting_true,
-      base::size(elements_expecting_true));
+      std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, IsAutofillableInputElement) {
@@ -1396,7 +1395,7 @@
 
   TestExecutingBooleanJavaScriptOnElement(
       @"__gCrWeb.fill.isAutofillableInputElement(%@)", elements_expecting_true,
-      base::size(elements_expecting_true));
+      std::size(elements_expecting_true));
 }
 
 TEST_F(AutofillControllerJsTest, ExtractAutofillableElements) {
@@ -1411,7 +1410,7 @@
       {"boolean", 2, -1},   {"state", 0, -1},
   };
   NSArray* expected = GetElementsByNameJavaScripts(
-      expected_elements, base::size(expected_elements));
+      expected_elements, std::size(expected_elements));
 
   NSString* parameter = @"window.document.getElementsByTagName('form')[0]";
   for (NSUInteger index = 0; index < [expected count]; index++) {
@@ -1433,7 +1432,7 @@
     NSString* tag_name) {
   web::test::LoadHtml([test_data firstObject], web_state());
 
-  for (NSUInteger i = 0; i < base::size(kFormExtractMasks); ++i) {
+  for (NSUInteger i = 0; i < std::size(kFormExtractMasks); ++i) {
     ExtractMask extract_mask = kFormExtractMasks[i];
     NSArray* attributes_to_check =
         GetFormFieldAttributeListsToCheck(extract_mask);
@@ -1551,7 +1550,7 @@
 
   NSString* parameter = @"document.getElementsByTagName('form')[0]";
   for (NSUInteger extract_index = 0;
-       extract_index < base::size(kFormExtractMasks); ++extract_index) {
+       extract_index < std::size(kFormExtractMasks); ++extract_index) {
     NSString* expected_result = @"true";
     // We don't verify 'action' here as action is generated as a complete url
     // and here data url is used.
diff --git a/ios/chrome/browser/browser_about_rewriter.cc b/ios/chrome/browser/browser_about_rewriter.cc
index f4e0a51..50d5288 100644
--- a/ios/chrome/browser/browser_about_rewriter.cc
+++ b/ios/chrome/browser/browser_about_rewriter.cc
@@ -7,7 +7,6 @@
 #include <string>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/feature_list.h"
 #include "components/url_formatter/url_fixer.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
@@ -56,7 +55,7 @@
   }
 
   std::string host(url->host());
-  for (size_t i = 0; i < base::size(kHostReplacements); ++i) {
+  for (size_t i = 0; i < std::size(kHostReplacements); ++i) {
     if (host != kHostReplacements[i].old_host_name)
       continue;
 
diff --git a/ios/chrome/browser/chrome_url_constants.cc b/ios/chrome/browser/chrome_url_constants.cc
index 30b7420..3149ba4 100644
--- a/ios/chrome/browser/chrome_url_constants.cc
+++ b/ios/chrome/browser/chrome_url_constants.cc
@@ -6,7 +6,8 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
+#include <iterator>
+
 #include "ios/components/webui/web_ui_url_constants.h"
 
 const char kChromeUIChromeURLsURL[] = "chrome://chrome-urls/";
@@ -77,7 +78,7 @@
     kChromeUIUserActionsHost,
     kChromeUIVersionHost,
 };
-const size_t kNumberOfChromeHostURLs = base::size(kChromeHostURLs);
+const size_t kNumberOfChromeHostURLs = std::size(kChromeHostURLs);
 
 const char kSyncGoogleDashboardURL[] =
     "https://www.google.com/settings/chrome/sync/";
diff --git a/ios/chrome/browser/chrome_url_util_unittest.mm b/ios/chrome/browser/chrome_url_util_unittest.mm
index 6a9dc63..5c8e9cce 100644
--- a/ios/chrome/browser/chrome_url_util_unittest.mm
+++ b/ios/chrome/browser/chrome_url_util_unittest.mm
@@ -4,7 +4,6 @@
 
 #import "ios/chrome/browser/chrome_url_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"
@@ -40,7 +39,7 @@
 
 // Tests UrlHasChromeScheme with NSURL* parameter.
 TEST_F(ChromeURLUtilTest, NSURLHasChromeScheme) {
-  for (unsigned int i = 0; i < base::size(kSchemeTestData); ++i) {
+  for (unsigned int i = 0; i < std::size(kSchemeTestData); ++i) {
     const char* url = kSchemeTestData[i];
     NSURL* nsurl = [NSURL URLWithString:base::SysUTF8ToNSString(url)];
     bool nsurl_result = UrlHasChromeScheme(nsurl);
@@ -51,7 +50,7 @@
 
 // Tests UrlHasChromeScheme with const GURL& paramter.
 TEST_F(ChromeURLUtilTest, GURLHasChromeScheme) {
-  for (unsigned int i = 0; i < base::size(kSchemeTestData); ++i) {
+  for (unsigned int i = 0; i < std::size(kSchemeTestData); ++i) {
     GURL gurl(kSchemeTestData[i]);
     bool result = UrlHasChromeScheme(gurl);
     EXPECT_EQ(gurl.SchemeIs(kChromeUIScheme), result)
diff --git a/ios/chrome/browser/crash_report/crash_helper.mm b/ios/chrome/browser/crash_report/crash_helper.mm
index 39f213c..747c119 100644
--- a/ios/chrome/browser/crash_report/crash_helper.mm
+++ b/ios/chrome/browser/crash_report/crash_helper.mm
@@ -129,7 +129,7 @@
   kinfo_proc kern_proc_info;
   int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
   size_t len = sizeof(kern_proc_info);
-  if (sysctl(mib, base::size(mib), &kern_proc_info, &len, nullptr, 0) != 0)
+  if (sysctl(mib, std::size(mib), &kern_proc_info, &len, nullptr, 0) != 0)
     return 0;
   time_t process_uptime_seconds =
       tv.tv_sec - kern_proc_info.kp_proc.p_starttime.tv_sec;
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 89c148c..9759b3832 100644
--- a/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm
+++ b/ios/chrome/browser/crash_report/crash_restore_helper_unittest.mm
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ios/chrome/browser/crash_report/crash_restore_helper.h"
+
 #import <Foundation/Foundation.h>
 
 #include <memory>
 
-#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"
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
-#include "ios/chrome/browser/crash_report/crash_restore_helper.h"
 #import "ios/chrome/browser/main/test_browser.h"
 #import "ios/chrome/browser/sessions/session_service_ios.h"
 #include "ios/web/public/test/web_task_environment.h"
@@ -51,7 +51,7 @@
         off_the_record_chrome_browser_state_,
     };
     NSData* data = [NSData dataWithBytes:"hello" length:5];
-    for (size_t index = 0; index < base::size(browser_states); ++index) {
+    for (size_t index = 0; index < std::size(browser_states); ++index) {
       const base::FilePath& state_path = browser_states[index]->GetStatePath();
       NSString* backup_path =
           [CrashRestoreHelper backupPathForSessionID:session_id
@@ -83,7 +83,7 @@
         off_the_record_chrome_browser_state_,
     };
 
-    for (size_t index = 0; index < base::size(browser_states); ++index) {
+    for (size_t index = 0; index < std::size(browser_states); ++index) {
       const base::FilePath& state_path = browser_states[index]->GetStatePath();
       NSString* session_path =
           [SessionServiceIOS sessionPathForSessionID:session_id
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 6a468aa0..9d41ef5d 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -15,7 +15,6 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #import "base/mac/foundation_util.h"
 #include "base/no_destructor.h"
 #include "base/strings/stringprintf.h"
@@ -149,19 +148,19 @@
 const FeatureEntry::FeatureVariation
     kOmniboxUIMaxAutocompleteMatchesVariations[] = {
         {"3 matches", kOmniboxUIMaxAutocompleteMatches3,
-         base::size(kOmniboxUIMaxAutocompleteMatches3), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches3), nullptr},
         {"4 matches", kOmniboxUIMaxAutocompleteMatches4,
-         base::size(kOmniboxUIMaxAutocompleteMatches4), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches4), nullptr},
         {"5 matches", kOmniboxUIMaxAutocompleteMatches5,
-         base::size(kOmniboxUIMaxAutocompleteMatches5), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches5), nullptr},
         {"6 matches", kOmniboxUIMaxAutocompleteMatches6,
-         base::size(kOmniboxUIMaxAutocompleteMatches6), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches6), nullptr},
         {"8 matches", kOmniboxUIMaxAutocompleteMatches8,
-         base::size(kOmniboxUIMaxAutocompleteMatches8), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches8), nullptr},
         {"10 matches", kOmniboxUIMaxAutocompleteMatches10,
-         base::size(kOmniboxUIMaxAutocompleteMatches10), nullptr},
+         std::size(kOmniboxUIMaxAutocompleteMatches10), nullptr},
         {"12 matches", kOmniboxUIMaxAutocompleteMatches12,
-         base::size(kOmniboxUIMaxAutocompleteMatches12), nullptr}};
+         std::size(kOmniboxUIMaxAutocompleteMatches12), nullptr}};
 
 const FeatureEntry::FeatureParam
     kAutofillUseMobileLabelDisambiguationShowAll[] = {
@@ -177,9 +176,9 @@
 const FeatureEntry::FeatureVariation
     kAutofillUseMobileLabelDisambiguationVariations[] = {
         {"(show all)", kAutofillUseMobileLabelDisambiguationShowAll,
-         base::size(kAutofillUseMobileLabelDisambiguationShowAll), nullptr},
+         std::size(kAutofillUseMobileLabelDisambiguationShowAll), nullptr},
         {"(show one)", kAutofillUseMobileLabelDisambiguationShowOne,
-         base::size(kAutofillUseMobileLabelDisambiguationShowOne), nullptr}};
+         std::size(kAutofillUseMobileLabelDisambiguationShowOne), nullptr}};
 
 const FeatureEntry::FeatureParam
     kDefaultBrowserFullscreenPromoExperimentRemindMeLater[] = {
@@ -188,14 +187,14 @@
     kDefaultBrowserFullscreenPromoExperimentVariations[] = {
         {"Remind me later",
          kDefaultBrowserFullscreenPromoExperimentRemindMeLater,
-         base::size(kDefaultBrowserFullscreenPromoExperimentRemindMeLater),
+         std::size(kDefaultBrowserFullscreenPromoExperimentRemindMeLater),
          nullptr}};
 
 const FeatureEntry::FeatureParam kDiscoverFeedInNtpEnableNativeUI[] = {
     {kDiscoverFeedIsNativeUIEnabled, "true"}};
 const FeatureEntry::FeatureVariation kDiscoverFeedInNtpVariations[] = {
     {"Native UI", kDiscoverFeedInNtpEnableNativeUI,
-     base::size(kDiscoverFeedInNtpEnableNativeUI), nullptr}};
+     std::size(kDiscoverFeedInNtpEnableNativeUI), nullptr}};
 
 const FeatureEntry::FeatureParam kDiscoverFeedSRSReconstructedTemplates[] = {
     {kDiscoverFeedSRSReconstructedTemplatesEnabled, "true"}};
@@ -204,9 +203,9 @@
 const FeatureEntry::FeatureVariation
     kEnableDiscoverFeedStaticResourceServingVariations[] = {
         {"Reconstruct Templates", kDiscoverFeedSRSReconstructedTemplates,
-         base::size(kDiscoverFeedSRSReconstructedTemplates), nullptr},
+         std::size(kDiscoverFeedSRSReconstructedTemplates), nullptr},
         {"Preload Templates", kDiscoverFeedSRSPreloadTemplates,
-         base::size(kDiscoverFeedSRSPreloadTemplates), nullptr},
+         std::size(kDiscoverFeedSRSPreloadTemplates), nullptr},
 };
 
 const FeatureEntry::FeatureParam kStartSurfaceTenSecondsShrinkLogo[] = {
@@ -251,30 +250,29 @@
 const FeatureEntry::FeatureVariation kStartSurfaceVariations[] = {
     {"10s:Show Return to Recent Tab tile",
      kStartSurfaceTenSecondsReturnToRecentTab,
-     base::size(kStartSurfaceTenSecondsReturnToRecentTab), nullptr},
+     std::size(kStartSurfaceTenSecondsReturnToRecentTab), nullptr},
     {"10s:Shrink Logo", kStartSurfaceTenSecondsShrinkLogo,
-     base::size(kStartSurfaceTenSecondsShrinkLogo), nullptr},
+     std::size(kStartSurfaceTenSecondsShrinkLogo), nullptr},
     {"10s:Hide Shortcuts", kStartSurfaceTenSecondsHideShortcuts,
-     base::size(kStartSurfaceTenSecondsHideShortcuts), nullptr},
+     std::size(kStartSurfaceTenSecondsHideShortcuts), nullptr},
     {"10s:Shrink Logo and show Return to Recent Tab tile",
      kStartSurfaceTenSecondsShrinkLogoReturnToRecentTab,
-     base::size(kStartSurfaceTenSecondsShrinkLogoReturnToRecentTab), nullptr},
+     std::size(kStartSurfaceTenSecondsShrinkLogoReturnToRecentTab), nullptr},
     {"10s:Hide Shortcuts and show Return to Recent Tab tile",
      kStartSurfaceTenSecondsHideShortcutsReturnToRecentTab,
-     base::size(kStartSurfaceTenSecondsHideShortcutsReturnToRecentTab),
-     nullptr},
+     std::size(kStartSurfaceTenSecondsHideShortcutsReturnToRecentTab), nullptr},
     {"1h:Show Return to Recent Tab tile", kStartSurfaceOneHourReturnToRecentTab,
-     base::size(kStartSurfaceOneHourReturnToRecentTab), nullptr},
+     std::size(kStartSurfaceOneHourReturnToRecentTab), nullptr},
     {"1h:Shrink Logo", kStartSurfaceOneHourShrinkLogo,
-     base::size(kStartSurfaceOneHourShrinkLogo), nullptr},
+     std::size(kStartSurfaceOneHourShrinkLogo), nullptr},
     {"1h:Hide Shortcuts", kStartSurfaceOneHourHideShortcuts,
-     base::size(kStartSurfaceOneHourHideShortcuts), nullptr},
+     std::size(kStartSurfaceOneHourHideShortcuts), nullptr},
     {"1h:Shrink Logo and show Return to Recent Tab tile",
      kStartSurfaceOneHourShrinkLogoReturnToRecentTab,
-     base::size(kStartSurfaceOneHourShrinkLogoReturnToRecentTab), nullptr},
+     std::size(kStartSurfaceOneHourShrinkLogoReturnToRecentTab), nullptr},
     {"1h:Hide Shortcuts and show Return to Recent Tab tile",
      kStartSurfaceOneHourHideShortcutsReturnToRecentTab,
-     base::size(kStartSurfaceOneHourHideShortcutsReturnToRecentTab), nullptr},
+     std::size(kStartSurfaceOneHourHideShortcutsReturnToRecentTab), nullptr},
 };
 
 const FeatureEntry::FeatureParam kFREDefaultPromoTestingDefaultDelay[] = {
@@ -286,12 +284,12 @@
 const FeatureEntry::FeatureVariation kFREDefaultPromoTestingVariations[] = {
     {"Wait 14 days after FRE default browser promo",
      kFREDefaultPromoTestingDefaultDelay,
-     base::size(kFREDefaultPromoTestingDefaultDelay), nullptr},
+     std::size(kFREDefaultPromoTestingDefaultDelay), nullptr},
     {"FRE default browser promo only", kFREDefaultPromoTestingOnly,
-     base::size(kFREDefaultPromoTestingOnly), nullptr},
+     std::size(kFREDefaultPromoTestingOnly), nullptr},
     {"Wait 3 days after FRE default browser promo",
      kFREDefaultPromoTestingShortDelay,
-     base::size(kFREDefaultPromoTestingShortDelay), nullptr},
+     std::size(kFREDefaultPromoTestingShortDelay), nullptr},
 };
 
 const FeatureEntry::FeatureVariation kEnableFREUIModuleIOSVariations[] = {
@@ -1164,7 +1162,7 @@
 
 base::span<const flags_ui::FeatureEntry> GetFeatureEntries() {
   return base::span<const flags_ui::FeatureEntry>(kFeatureEntries,
-                                                  base::size(kFeatureEntries));
+                                                  std::size(kFeatureEntries));
 }
 
 }  // namespace testing
diff --git a/ios/chrome/browser/metrics/first_user_action_recorder.cc b/ios/chrome/browser/metrics/first_user_action_recorder.cc
index c06deaa..a0d867b 100644
--- a/ios/chrome/browser/metrics/first_user_action_recorder.cc
+++ b/ios/chrome/browser/metrics/first_user_action_recorder.cc
@@ -5,7 +5,6 @@
 #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"
@@ -131,7 +130,7 @@
 void FirstUserActionRecorder::OnUserAction(const std::string& action_name,
                                            base::TimeTicks action_time) {
   if (ShouldProcessAction(action_name, action_time)) {
-    if (ArrayContainsString(kNewTaskActions, base::size(kNewTaskActions),
+    if (ArrayContainsString(kNewTaskActions, std::size(kNewTaskActions),
                             action_name.c_str())) {
       std::string log_message = base::StringPrintf(
           "Recording 'New task' for first user action type"
@@ -193,7 +192,7 @@
     return false;
 
   if (!action_pending_ &&
-      ArrayContainsString(kRethrownActions, base::size(kRethrownActions),
+      ArrayContainsString(kRethrownActions, std::size(kRethrownActions),
                           action_name.c_str())) {
     rethrow_callback_.Reset(
         base::BindOnce(&FirstUserActionRecorder::OnUserAction,
@@ -208,11 +207,11 @@
   // inkNewTaskActions.
   bool known_mobile_action =
       base::StartsWith(action_name, "Mobile", base::CompareCase::SENSITIVE) ||
-      ArrayContainsString(kNewTaskActions, base::size(kNewTaskActions),
+      ArrayContainsString(kNewTaskActions, std::size(kNewTaskActions),
                           action_name.c_str());
 
   return known_mobile_action &&
-         !ArrayContainsString(kIgnoredActions, base::size(kIgnoredActions),
+         !ArrayContainsString(kIgnoredActions, std::size(kIgnoredActions),
                               action_name.c_str());
 }
 
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
index ee4cf99..58534f7 100644
--- a/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
+++ b/ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.mm
@@ -509,7 +509,7 @@
       ui::PAGE_TRANSITION_KEYWORD_GENERATED,
   };
 
-  for (size_t i = 0; i < base::size(kRecordedPageTransitionTypes); ++i) {
+  for (size_t i = 0; i < std::size(kRecordedPageTransitionTypes); ++i) {
     const ui::PageTransition recorded_type = kRecordedPageTransitionTypes[i];
     if (ui::PageTransitionCoreTypeIs(transition, recorded_type)) {
       return true;
diff --git a/ios/chrome/browser/omaha/omaha_service_unittest.mm b/ios/chrome/browser/omaha/omaha_service_unittest.mm
index 8b34c85..c3990463 100644
--- a/ios/chrome/browser/omaha/omaha_service_unittest.mm
+++ b/ios/chrome/browser/omaha/omaha_service_unittest.mm
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #import "base/test/ios/wait_util.h"
@@ -219,8 +218,7 @@
       base::StringPrintf(kExpectedResultFormat, "" /* previous version */,
                          -1 /* install age */, 2 /* event type */);
   regcomp(&regex, expected_result.c_str(), REG_EXTENDED);
-  int result =
-      regexec(&regex, content.c_str(), base::size(matches), matches, 0);
+  int result = regexec(&regex, content.c_str(), std::size(matches), matches, 0);
   regfree(&regex);
   EXPECT_EQ(0, result) << "Actual contents: " << content;
   EXPECT_FALSE(NeedUpdate());
@@ -234,7 +232,7 @@
   expected_result = base::StringPrintf(kExpectedResultFormat, kPreviousVersion,
                                        0 /* install age */, 3 /* event type */);
   regcomp(&regex, expected_result.c_str(), REG_EXTENDED);
-  result = regexec(&regex, content.c_str(), base::size(matches), matches, 0);
+  result = regexec(&regex, content.c_str(), std::size(matches), matches, 0);
   regfree(&regex);
   EXPECT_EQ(0, result) << "Actual contents: " << content;
   EXPECT_FALSE(NeedUpdate());
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm
index c7b7a2bc..32686876 100644
--- a/ios/chrome/browser/passwords/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/memory/ref_counted.h"
 #include "base/strings/sys_string_conversions.h"
@@ -1134,7 +1133,7 @@
                          {"f2", 4, "u2", 5, "p2", 6}};
 
   // Send fill data to passwordController_.
-  for (size_t form_i = 0; form_i < base::size(kTestData); ++form_i) {
+  for (size_t form_i = 0; form_i < std::size(kTestData); ++form_i) {
     // Initialize |form_data| with test data and an indicator that autofill
     // should not be performed while the user is entering the username so that
     // we can test with an initially-empty username field.
@@ -1162,7 +1161,7 @@
   }
 
   // Check that the right password form is filled on suggesion selection.
-  for (size_t form_i = 0; form_i < base::size(kTestData); ++form_i) {
+  for (size_t form_i = 0; form_i < std::size(kTestData); ++form_i) {
     const auto& test_data = kTestData[form_i];
     NSString* form_name = SysUTF8ToNSString(test_data.form_name);
     FormRendererId form_renderer_id =
@@ -1391,7 +1390,7 @@
       "</form>"
       "</body></html>"};
 
-  for (size_t i = 0; i < base::size(kHtml); ++i) {
+  for (size_t i = 0; i < std::size(kHtml); ++i) {
     LoadHtml(SysUTF8ToNSString(kHtml[i]));
     WaitForFormManagersCreation();
 
diff --git a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
index b923d34..ea4c338 100644
--- a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
+++ b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
@@ -132,7 +132,7 @@
     return handlers;
   }
 
-  for (size_t i = 0; i < base::size(kSimplePolicyMap); ++i) {
+  for (size_t i = 0; i < std::size(kSimplePolicyMap); ++i) {
     handlers->AddHandler(std::make_unique<SimplePolicyHandler>(
         kSimplePolicyMap[i].policy_name, kSimplePolicyMap[i].preference_path,
         kSimplePolicyMap[i].value_type));
diff --git a/ios/chrome/browser/snapshots/snapshots_util.mm b/ios/chrome/browser/snapshots/snapshots_util.mm
index 9b3094e..ed91f26 100644
--- a/ios/chrome/browser/snapshots/snapshots_util.mm
+++ b/ios/chrome/browser/snapshots/snapshots_util.mm
@@ -7,7 +7,6 @@
 #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"
@@ -62,7 +61,7 @@
   } else if (scale == 3) {
     retina_suffix = "@3x";
   }
-  for (unsigned int i = 0; i < base::size(kOrientationDescriptions); i++) {
+  for (unsigned int i = 0; i < std::size(kOrientationDescriptions); i++) {
     std::string snapshot_filename =
         base::StringPrintf("UIApplicationAutomaticSnapshotDefault-%s%s.png",
                            kOrientationDescriptions[i], retina_suffix);
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc
index 93f9c67..cab5ffd 100644
--- a/ios/chrome/browser/sync/sync_setup_service.cc
+++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -6,7 +6,6 @@
 
 #include <stdio.h>
 
-#include "base/cxx17_backports.h"
 #include "base/metrics/histogram_macros.h"
 #include "components/sync/base/stop_source.h"
 #include "components/sync/base/user_selectable_type.h"
@@ -32,7 +31,7 @@
 SyncSetupService::~SyncSetupService() {}
 
 syncer::ModelType SyncSetupService::GetModelType(SyncableDatatype datatype) {
-  DCHECK(datatype < base::size(kDataTypes));
+  DCHECK(datatype < std::size(kDataTypes));
   return kDataTypes[datatype];
 }
 
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 28e01d2..2f25d708 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -348,7 +348,7 @@
   DownloadManagerCoordinator* _downloadManagerCoordinator;
 
   // A map associating webStates with their NTP coordinators.
-  // TODO(crbug.com/1173610): Factor NTPCoordinator ownership out of the BVC
+  // TODO(crbug.com/1300911): Factor NTPCoordinator ownership out of the BVC
   std::map<web::WebState*, NewTabPageCoordinator*> _ntpCoordinatorsForWebStates;
 
   // Fake status bar view used to blend the toolbar into the status bar.
@@ -2582,7 +2582,7 @@
   if (!webState->IsRealized())
     return;
 
-  // TODO(crbug.com/1173610): Have BrowserCoordinator manage the NTP.
+  // TODO(crbug.com/1300911): Have BrowserCoordinator manage the NTP.
   // No need to stop _ntpCoordinator with Single NTP enabled since shutdown will
   // do that. In addition, uninstallDelegatesForWebState: is called for
   // individual WebState removals, which should not trigger a stop.
@@ -2706,7 +2706,6 @@
 
 - (void)stopNTP {
   [_ntpCoordinator stop];
-  [_ntpCoordinator disconnect];
   _ntpCoordinator = nullptr;
 }
 
@@ -4625,7 +4624,7 @@
       // Checks for leaks in |_ntpCoordinatorsForWebStates|.
       DCHECK_LE(static_cast<int>(_ntpCoordinatorsForWebStates.size()),
                 self.browser->GetWebStateList()->count() - 1);
-      // TODO(crbug.com/1173610): Have BrowserCoordinator manage the NTP.
+      // TODO(crbug.com/1300911): Have BrowserCoordinator manage the NTP.
       NewTabPageCoordinator* newTabPageCoordinator =
           [[NewTabPageCoordinator alloc]
               initWithBaseViewController:self
@@ -4640,7 +4639,6 @@
           [self ntpCoordinatorForWebState:webState];
       DCHECK(newTabPageCoordinator);
       [newTabPageCoordinator stop];
-      [newTabPageCoordinator disconnect];
       _ntpCoordinatorsForWebStates.erase(webState);
     }
   }
diff --git a/ios/chrome/browser/ui/browser_view/common_tab_helper_delegate.h b/ios/chrome/browser/ui/browser_view/common_tab_helper_delegate.h
index 02ba50e..dce98d0 100644
--- a/ios/chrome/browser/ui/browser_view/common_tab_helper_delegate.h
+++ b/ios/chrome/browser/ui/browser_view/common_tab_helper_delegate.h
@@ -18,7 +18,7 @@
 // that the BVC conforms to to zero.
 @protocol CommonTabHelperDelegate <
     BubblePresenterDelegate,
-    // TODO(crbug.com/1173610): Factor NewTabPageTabHelperDelegate out of the
+    // TODO(crbug.com/1300911): Factor NewTabPageTabHelperDelegate out of the
     // BVC.
     NewTabPageTabHelperDelegate,
     OverscrollActionsControllerDelegate,
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h
index 1def122..62aab6b5 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.h
@@ -37,14 +37,10 @@
 class WebStateList;
 
 // Mediator for ContentSuggestions.
-// TODO(crbug.com/1200303): Update comment once this file has been cleaned up.
-// This means removing legacy Feed and non refactored NTP code.
 @interface ContentSuggestionsMediator
     : NSObject <StartSurfaceRecentTabObserving>
 
 // Default initializer.
-// TODO(crbug.com/1200303): Update comment once this file has been cleaned up.
-// This means removing legacy Feed and non refactored NTP code.
 - (instancetype)
          initWithLargeIconService:(favicon::LargeIconService*)largeIconService
                    largeIconCache:(LargeIconCache*)largeIconCache
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 b675a05..0f4f7d42 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -443,7 +443,9 @@
       [convertedSuggestions addObjectsFromArray:self.actionButtonItems];
     }
   } else if (sectionInfo == self.singleCellSectionInfo) {
-    self.parentItem = [[ContentSuggestionsParentItem alloc] initWithType:0];
+    if (!self.parentItem) {
+      self.parentItem = [[ContentSuggestionsParentItem alloc] initWithType:0];
+    }
     if (_notificationPromo->CanShow() && !self.shouldHidePromoAfterTap) {
       ContentSuggestionsWhatsNewItem* item =
           [[ContentSuggestionsWhatsNewItem alloc] initWithType:0];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index f19cbeb..4ab5ab9 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -132,16 +132,6 @@
                          @{@"collection" : self.collectionView});
 }
 
-- (void)viewDidAppear:(BOOL)animated {
-  [super viewDidAppear:animated];
-
-  // TODO(crbug.com/1200303): Reload data is needed here so the content matches
-  // the current UI Layout after changing the Feed state (e.g. Turned On/Off).
-  // This shouldn't be necessary once we stop starting and stopping the
-  // Coordinator to achieve this.
-  [self.collectionView reloadData];
-}
-
 - (void)viewDidDisappear:(BOOL)animated {
   [super viewDidDisappear:animated];
   if (ShouldShowReturnToMostRecentTabForStartSurface()) {
diff --git a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h
index 00cd229..c9109b41 100644
--- a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h
+++ b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h
@@ -8,7 +8,8 @@
 #import <UIKit/UIKit.h>
 
 // App interface for the NTP.
-// TODO(crbug.com/1200303): Move this to */ui/ntp.
+// TODO(crbug.com/1299373): Separate content suggestions functions into
+// ContentSuggestionsAppInterface interface and move this to /ui/ntp.
 @interface NewTabPageAppInterface : NSObject
 
 // Sets the fake service up.
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
index 1948241..77f1be5 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h
@@ -76,10 +76,6 @@
 // Constrains the named layout guide for the Discover header menu button.
 - (void)constrainDiscoverHeaderMenuButtonNamedGuide;
 
-// TODO(crbug.com/1200303):Remove this method once we stop starting/stopping the
-// Coordinator when turning the feed on/off.
-- (void)disconnect;
-
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_NTP_NEW_TAB_PAGE_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index b5c8cda..aadd73d 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -373,18 +373,14 @@
   [self.containedViewController.view removeFromSuperview];
   [self.containedViewController removeFromParentViewController];
 
-  self.started = NO;
-}
-
-- (void)disconnect {
-  // TODO(crbug.com/1200303): Move this to stop once we stop starting/stopping
-  // the Coordinator when turning the feed on/off.
   [self.feedExpandedPref setObserver:nil];
   self.feedExpandedPref = nil;
 
   _prefChangeRegistrar.reset();
   _prefObserverBridge.reset();
   _discoverFeedProviderObserverBridge.reset();
+
+  self.started = NO;
 }
 
 // Updates the visible property based on viewPresented and sceneInForeground
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
index ab538bf..8077536 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -107,7 +107,6 @@
   UIViewController* viewController = [coordinator_ viewController];
   EXPECT_FALSE([viewController isKindOfClass:[IncognitoViewController class]]);
   [coordinator_ stop];
-  [coordinator_ disconnect];
 }
 
 // Tests that the coordinator vends an incognito VC off the record.
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 ad2d915..8fda73b1 100644
--- a/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
+++ b/ios/chrome/browser/ui/ntp/notification_promo_whats_new.mm
@@ -5,12 +5,12 @@
 #import "ios/chrome/browser/ui/ntp/notification_promo_whats_new.h"
 
 #include <stdint.h>
+
 #include <algorithm>
 #include <memory>
 #include <vector>
 
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/ios/ios_util.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/field_trial.h"
@@ -56,7 +56,7 @@
 // Returns a localized version of |promo_text| if it has an entry in the
 // |kPromoStringToIdsMap|. If there is no entry, an empty string is returned.
 std::string GetLocalizedPromoText(const std::string& promo_text) {
-  for (size_t i = 0; i < base::size(kPromoStringToIdsMap); ++i) {
+  for (size_t i = 0; i < std::size(kPromoStringToIdsMap); ++i) {
     auto& entry = kPromoStringToIdsMap[i];
     if (entry.promo_text_str == promo_text) {
       return entry.nonlocalized_message
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 07a4f844..bd3a66b 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,7 +5,6 @@
 #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"
@@ -1083,7 +1082,7 @@
   void (^updates)(void) = ^{
     SectionIdentifier sections[] = {SectionIdentifierRead,
                                     SectionIdentifierUnread};
-    for (size_t i = 0; i < base::size(sections); ++i) {
+    for (size_t i = 0; i < std::size(sections); ++i) {
       SectionIdentifier section = sections[i];
 
       if ([model hasSectionForSectionIdentifier:section] &&
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 50cd918c..f96bff7 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,7 +4,6 @@
 
 #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/strings/sys_string_conversions.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
@@ -145,7 +144,7 @@
 
   std::string locale = GetApplicationContext()->GetApplicationLocale();
   [model addSectionWithIdentifier:SectionIdentifierFields];
-  for (size_t i = 0; i < base::size(kProfileFieldsToDisplay); ++i) {
+  for (size_t i = 0; i < std::size(kProfileFieldsToDisplay); ++i) {
     const AutofillProfileFieldDisplayInfo& field = kProfileFieldsToDisplay[i];
 
     if (field.autofillType == autofill::NAME_HONORIFIC_PREFIX &&
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 6f1e885..1284a5f3 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,7 +4,6 @@
 
 #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 "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
@@ -44,7 +43,7 @@
     IDS_IOS_CLEAR_BROWSING_DATA_TIME_RANGE_OPTION_OLDER_THAN_30_DAYS};
 
 static_assert(
-    base::size(kStringIDS) ==
+    std::size(kStringIDS) ==
         static_cast<int>(browsing_data::TimePeriod::TIME_PERIOD_LAST) + 1,
     "Strings have to match the enum values.");
 
@@ -158,7 +157,7 @@
   if (!prefs)
     return nil;
   int prefValue = prefs->GetInteger(browsing_data::prefs::kDeleteTimePeriod);
-  if (prefValue < 0 || static_cast<size_t>(prefValue) >= base::size(kStringIDS))
+  if (prefValue < 0 || static_cast<size_t>(prefValue) >= std::size(kStringIDS))
     return nil;
   return l10n_util::GetNSString(kStringIDS[prefValue]);
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_empty_view.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_empty_view.h
index ac425c61..7257e14b 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_empty_view.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_empty_view.h
@@ -7,8 +7,10 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_paging.h"
+
 // Protocol defining the interface of the view displayed when the grid is empty.
-@protocol GridEmptyView
+@protocol GridEmptyView <TabGridPaging>
 
 // Insets of the inner ScrollView.
 @property(nonatomic, assign) UIEdgeInsets scrollViewContentInsets;
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 cbfb60b2..c6edd28b 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
@@ -306,6 +306,7 @@
   _mode = mode;
   // TODO(crbug.com/1300369): Enable dragging items from search results.
   self.collectionView.dragInteractionEnabled = (_mode != TabGridModeSearch);
+  self.emptyStateView.tabGridMode = _mode;
 
   if (IsTabsSearchRegularResultsSuggestedActionsEnabled()) {
     if (mode == TabGridModeSearch && self.suggestedActionsDelegate) {
@@ -339,7 +340,8 @@
   if (mode == TabGridModeNormal) {
     [self.selectedEditingItemIDs removeAllObjects];
     [self.selectedSharableEditingItemIDs removeAllObjects];
-    self.searchText = nil;
+    if (IsTabsSearchEnabled())
+      self.searchText = nil;
     // After transition from the selection mode to the normal mode, the
     // selection border doesn't show around the selection item. The collection
     // view needs to be updated with the selected item again for it to appear
@@ -1556,7 +1558,6 @@
 #pragma mark Suggested Actions Section
 
 - (void)updateSuggestedActionsSection {
-  DCHECK(IsTabsSearchEnabled());
   if (!self.suggestedActionsDelegate)
     return;
   // In search mode if there is already a search query, and the suggested
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index 25fded0..2137647 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -8,6 +8,7 @@
 #import "base/test/ios/wait_util.h"
 #import "components/bookmarks/common/bookmark_pref_names.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -37,6 +38,9 @@
 using chrome_test_util::AddToBookmarksButton;
 using chrome_test_util::AddToReadingListButton;
 using chrome_test_util::CloseTabMenuButton;
+using chrome_test_util::TabGridSearchBar;
+using chrome_test_util::TabGridSearchCancelButton;
+using chrome_test_util::TabGridSearchTabsButton;
 using chrome_test_util::TabGridSelectTabsMenuButton;
 
 namespace {
@@ -112,6 +116,16 @@
 
 @implementation TabGridTestCase
 
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+
+  if ([self isRunningTest:@selector(testEnterExitSearch)]) {
+    config.features_enabled.push_back(kTabsSearch);
+  }
+
+  return config;
+}
+
 - (void)setUp {
   [super setUp];
 
@@ -1187,6 +1201,24 @@
   GREYAssertTrue([copyCondition waitWithTimeout:5], @"Copying URLs failed");
 }
 
+#pragma mark - Tab Grid Search
+
+// Tests entering and exit of the tab grid search mode.
+- (void)testEnterExitSearch {
+  [ChromeEarlGrey openNewTab];
+  [ChromeEarlGrey showTabSwitcher];
+
+  [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridSearchBar()]
+      performAction:grey_typeText(@"text")];
+  [[EarlGrey selectElementWithMatcher:TabGridSearchCancelButton()]
+      performAction:grey_tap()];
+
+  GREYAssertEqual([ChromeEarlGrey mainTabCount], 2,
+                  @"All tabs did not return after exiting search.");
+}
+
 #pragma mark - Helper Methods
 
 - (void)loadTestURLs {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm
index c84e018..08b4a39 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm
@@ -19,47 +19,88 @@
 const CGFloat kVerticalMargin = 16.0;
 const CGFloat kImageHeight = 150.0;
 const CGFloat kImageWidth = 150.0;
+
+// Returns the image to display for the given grid |page|.
+UIImage* ImageForPage(TabGridPage page) {
+  switch (page) {
+    case TabGridPageIncognitoTabs:
+      return [UIImage imageNamed:@"tab_grid_incognito_tabs_empty"];
+    case TabGridPageRegularTabs:
+      return [UIImage imageNamed:@"tab_grid_regular_tabs_empty"];
+    case TabGridPageRemoteTabs:
+      // No-op. Empty page.
+      break;
+  }
+  return nil;
+}
+
+// Returns the title to display for the given grid |page| and |mode|.
+NSString* TitleForPageAndMode(TabGridPage page, TabGridMode mode) {
+  if (mode == TabGridModeSearch) {
+    return l10n_util::GetNSString(IDS_IOS_TAB_GRID_SEARCH_RESULTS_EMPTY_TITLE);
+  }
+
+  switch (page) {
+    case TabGridPageIncognitoTabs:
+      return l10n_util::GetNSString(
+          IDS_IOS_TAB_GRID_INCOGNITO_TABS_EMPTY_TITLE);
+    case TabGridPageRegularTabs:
+      return l10n_util::GetNSString(IDS_IOS_TAB_GRID_REGULAR_TABS_EMPTY_TITLE);
+    case TabGridPageRemoteTabs:
+      // No-op. Empty page.
+      break;
+  }
+
+  return nil;
+}
+
+// Returns the message to display for the given grid |page| and |mode|.
+NSString* BodyTextForPageAndMode(TabGridPage page, TabGridMode mode) {
+  if (mode == TabGridModeSearch) {
+    return nil;
+  }
+
+  switch (page) {
+    case TabGridPageIncognitoTabs:
+      return l10n_util::GetNSString(
+          IDS_IOS_TAB_GRID_INCOGNITO_TABS_EMPTY_MESSAGE);
+    case TabGridPageRegularTabs:
+      return l10n_util::GetNSString(
+          IDS_IOS_TAB_GRID_REGULAR_TABS_EMPTY_MESSAGE);
+    case TabGridPageRemoteTabs:
+      // No-op. Empty page.
+      break;
+  }
+
+  return nil;
+}
+
 }  // namespace
 
 @interface TabGridEmptyStateView ()
 @property(nonatomic, strong) UIView* container;
 @property(nonatomic, strong) UIScrollView* scrollView;
 @property(nonatomic, strong) NSLayoutConstraint* scrollViewHeight;
-@property(nonatomic, copy, readonly) UIImage* image;
-@property(nonatomic, copy, readonly) NSString* title;
-@property(nonatomic, copy, readonly) NSString* body;
+@property(nonatomic, weak) UIImageView* imageView;
+@property(nonatomic, weak) UILabel* topLabel;
+@property(nonatomic, weak) UILabel* bottomLabel;
 @end
 
 @implementation TabGridEmptyStateView
 // GridEmptyView properties.
 @synthesize scrollViewContentInsets = _scrollViewContentInsets;
+@synthesize activePage = _activePage;
+@synthesize tabGridMode = _tabGridMode;
 
 - (instancetype)initWithPage:(TabGridPage)page {
   if (self = [super initWithFrame:CGRectZero]) {
-    switch (page) {
-      case TabGridPageIncognitoTabs:
-        _image = [UIImage imageNamed:@"tab_grid_incognito_tabs_empty"];
-        _title =
-            l10n_util::GetNSString(IDS_IOS_TAB_GRID_INCOGNITO_TABS_EMPTY_TITLE);
-        _body = l10n_util::GetNSString(
-            IDS_IOS_TAB_GRID_INCOGNITO_TABS_EMPTY_MESSAGE);
-        break;
-      case TabGridPageRegularTabs:
-        _image = [UIImage imageNamed:@"tab_grid_regular_tabs_empty"];
-        _title =
-            l10n_util::GetNSString(IDS_IOS_TAB_GRID_REGULAR_TABS_EMPTY_TITLE);
-        _body =
-            l10n_util::GetNSString(IDS_IOS_TAB_GRID_REGULAR_TABS_EMPTY_MESSAGE);
-        break;
-      case TabGridPageRemoteTabs:
-        // No-op. Empty page.
-        break;
-    }
+    _activePage = page;
+    _tabGridMode = TabGridModeNormal;
   }
   return self;
 }
 
-#pragma mark - Accessor
+#pragma mark - GridEmptyView
 
 - (void)setScrollViewContentInsets:(UIEdgeInsets)scrollViewContentInsets {
   _scrollViewContentInsets = scrollViewContentInsets;
@@ -68,6 +109,29 @@
       scrollViewContentInsets.top + scrollViewContentInsets.bottom;
 }
 
+- (void)setTabGridMode:(TabGridMode)tabGridMode {
+  if (_tabGridMode == tabGridMode) {
+    return;
+  }
+
+  _tabGridMode = tabGridMode;
+
+  self.topLabel.text = TitleForPageAndMode(_activePage, _tabGridMode);
+  self.bottomLabel.text = BodyTextForPageAndMode(_activePage, _tabGridMode);
+}
+
+- (void)setActivePage:(TabGridPage)activePage {
+  if (_activePage == activePage) {
+    return;
+  }
+
+  _activePage = activePage;
+
+  self.imageView.image = ImageForPage(_activePage);
+  self.topLabel.text = TitleForPageAndMode(_activePage, _tabGridMode);
+  self.bottomLabel.text = BodyTextForPageAndMode(_activePage, _tabGridMode);
+}
+
 #pragma mark - UIView
 
 - (void)willMoveToSuperview:(UIView*)newSuperview {
@@ -96,8 +160,9 @@
   self.scrollView = scrollView;
 
   UILabel* topLabel = [[UILabel alloc] init];
+  _topLabel = topLabel;
   topLabel.translatesAutoresizingMaskIntoConstraints = NO;
-  topLabel.text = self.title;
+  topLabel.text = TitleForPageAndMode(_activePage, _tabGridMode);
   topLabel.textColor = UIColorFromRGB(kTabGridEmptyStateTitleTextColor);
   topLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2];
   topLabel.adjustsFontForContentSizeCategory = YES;
@@ -105,20 +170,22 @@
   topLabel.textAlignment = NSTextAlignmentCenter;
 
   UILabel* bottomLabel = [[UILabel alloc] init];
+  _bottomLabel = bottomLabel;
   bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;
-  bottomLabel.text = self.body;
+  bottomLabel.text = BodyTextForPageAndMode(_activePage, _tabGridMode);
   bottomLabel.textColor = UIColorFromRGB(kTabGridEmptyStateBodyTextColor);
-    bottomLabel.font =
-        [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
+  bottomLabel.font =
+      [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline];
   bottomLabel.adjustsFontForContentSizeCategory = YES;
   bottomLabel.numberOfLines = 0;
   bottomLabel.textAlignment = NSTextAlignmentCenter;
 
-  UIImageView* imageView = nil;
-    imageView = [[UIImageView alloc] initWithImage:self.image];
-    imageView.translatesAutoresizingMaskIntoConstraints = NO;
+  UIImageView* imageView =
+      [[UIImageView alloc] initWithImage:ImageForPage(_activePage)];
+  _imageView = imageView;
+  imageView.translatesAutoresizingMaskIntoConstraints = NO;
 
-    [container addSubview:imageView];
+  [container addSubview:imageView];
 
   [container addSubview:topLabel];
   [container addSubview:bottomLabel];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm
index 809acf5..f20db35e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm
@@ -129,14 +129,21 @@
   return WebStateList::kInvalidIndex;
 }
 
-// Returns the WebState with |identifier| in |web_state_list|. Returns |nullptr|
+// Returns the WebState with |identifier| in |browser_state|. Returns |nullptr|
 // if not found.
-web::WebState* GetWebStateWithId(WebStateList* web_state_list,
+web::WebState* GetWebStateWithId(ChromeBrowserState* browser_state,
                                  NSString* identifier) {
-  for (int i = 0; i < web_state_list->count(); i++) {
-    web::WebState* web_state = web_state_list->GetWebStateAt(i);
-    if ([identifier isEqualToString:web_state->GetStableIdentifier()])
-      return web_state;
+  BrowserList* browser_list =
+      BrowserListFactory::GetForBrowserState(browser_state);
+  std::set<Browser*> browsers = browser_state->IsOffTheRecord()
+                                    ? browser_list->AllIncognitoBrowsers()
+                                    : browser_list->AllRegularBrowsers();
+  for (Browser* browser : browsers) {
+    WebStateList* web_state_list = browser->GetWebStateList();
+    int index = GetIndexOfTabWithId(web_state_list, identifier);
+    if (index != WebStateList::kInvalidIndex) {
+      return web_state_list->GetWebStateAt(index);
+    }
   }
   return nullptr;
 }
@@ -352,7 +359,7 @@
 - (void)snapshotCache:(SnapshotCache*)snapshotCache
     didUpdateSnapshotForIdentifier:(NSString*)identifier {
   [self.appearanceCache removeObjectForKey:identifier];
-  web::WebState* webState = GetWebStateWithId(self.webStateList, identifier);
+  web::WebState* webState = GetWebStateWithId(self.browserState, identifier);
   if (webState) {
     // It is possible to observe an updated snapshot for a WebState before
     // observing that the WebState has been added to the WebStateList. It is the
@@ -646,7 +653,7 @@
 #pragma mark - GridDragDropHandler
 
 - (UIDragItem*)dragItemForItemWithID:(NSString*)itemID {
-  web::WebState* webState = GetWebStateWithId(self.webStateList, itemID);
+  web::WebState* webState = GetWebStateWithId(self.browserState, itemID);
   return CreateTabDragItem(webState);
 }
 
@@ -741,7 +748,7 @@
     completion(self.appearanceCache[identifier]);
     return;
   }
-  web::WebState* webState = GetWebStateWithId(self.webStateList, identifier);
+  web::WebState* webState = GetWebStateWithId(self.browserState, identifier);
   if (webState) {
     SnapshotTabHelper::FromWebState(webState)->RetrieveColorSnapshot(
         ^(UIImage* image) {
@@ -752,7 +759,7 @@
 
 - (void)faviconForIdentifier:(NSString*)identifier
                   completion:(void (^)(UIImage*))completion {
-  web::WebState* webState = GetWebStateWithId(self.webStateList, identifier);
+  web::WebState* webState = GetWebStateWithId(self.browserState, identifier);
   if (!webState) {
     return;
   }
@@ -796,7 +803,8 @@
 #pragma mark - GridMenuActionsDataSource
 
 - (GridItem*)gridItemForCellIdentifier:(NSString*)identifier {
-  web::WebState* webState = GetWebStateWithId(self.webStateList, identifier);
+  web::WebState* webState = GetWebStateWithId(self.browserState, identifier);
+
   GridItem* item =
       [[GridItem alloc] initWithTitle:tab_util::GetTabTitle(webState)
                                   url:webState->GetVisibleURL()];
@@ -813,7 +821,7 @@
 #pragma mark - GridShareableItemsProvider
 
 - (BOOL)isItemWithIdentifierSharable:(NSString*)identifier {
-  web::WebState* webState = GetWebStateWithId(self.webStateList, identifier);
+  web::WebState* webState = GetWebStateWithId(self.browserState, identifier);
   const GURL& URL = webState->GetVisibleURL();
   return URL.is_valid() && URL.SchemeIsHTTPOrHTTPS();
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
index 1bbf190..01ae664 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -1977,19 +1977,16 @@
   gridViewController.showsSelectionUpdates = NO;
   // Check if the tab being selected is already selected.
   BOOL alreadySelected = NO;
+  id<GridCommands> tabsDelegate;
   if (gridViewController == self.regularTabsViewController) {
-    alreadySelected = [self.regularTabsDelegate isItemWithIDSelected:itemID];
-    [self.regularTabsDelegate selectItemWithID:itemID];
-    // Record when a regular tab is opened.
+    tabsDelegate = self.regularTabsDelegate;
     base::RecordAction(base::UserMetricsAction("MobileTabGridOpenRegularTab"));
     if (self.tabGridMode == TabGridModeSearch) {
       base::RecordAction(
           base::UserMetricsAction("MobileTabGridOpenRegularTabSearchResult"));
     }
   } else if (gridViewController == self.incognitoTabsViewController) {
-    alreadySelected = [self.incognitoTabsDelegate isItemWithIDSelected:itemID];
-    [self.incognitoTabsDelegate selectItemWithID:itemID];
-    // Record when an incognito tab is opened.
+    tabsDelegate = self.incognitoTabsDelegate;
     base::RecordAction(
         base::UserMetricsAction("MobileTabGridOpenIncognitoTab"));
     if (self.tabGridMode == TabGridModeSearch) {
@@ -1998,8 +1995,11 @@
     }
   }
 
+  alreadySelected = [tabsDelegate isItemWithIDSelected:itemID];
+  [tabsDelegate selectItemWithID:itemID];
+
   if (IsTabsSearchEnabled() && self.tabGridMode == TabGridModeSearch &&
-      ![self.regularTabsDelegate isItemWithIDSelected:itemID]) {
+      ![tabsDelegate isItemWithIDSelected:itemID]) {
     // That can happen when the search result that was selected is from
     // another window. In that case don't change the active page for this
     // window and don't close the tab grid.
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 abf25c3..ee0c100 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,6 @@
 #include <algorithm>
 #include <vector>
 
-#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"
@@ -294,7 +293,7 @@
   EXPECT_EQ(CGRectGetHeight(container_view().bounds), GetExpectedStackHeight());
   // Set the stack progress to the progress values in kStackProgressValues and
   // verify the toolbar frames for each of these stack progress values.
-  for (size_t index = 0; index < base::size(kStackProgressValues); ++index) {
+  for (size_t index = 0; index < std::size(kStackProgressValues); ++index) {
     SetStackProgress(kStackProgressValues[index]);
     CheckToolbarFrames();
   }
diff --git a/ios/chrome/browser/ui/util/ui_util_unittest.mm b/ios/chrome/browser/ui/util/ui_util_unittest.mm
index 3423ca6..2edbc7b 100644
--- a/ios/chrome/browser/ui/util/ui_util_unittest.mm
+++ b/ios/chrome/browser/ui/util/ui_util_unittest.mm
@@ -7,7 +7,6 @@
 #import <UIKit/UIKit.h>
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -25,7 +24,7 @@
   // "integer" values within <1 of the original value in the scaled space.
   CGFloat test_values[] = {10.0, 55.5, 3.14159, 2.71828};
   const CGFloat kMaxAlignDelta = 0.9999;
-  size_t value_count = base::size(test_values);
+  size_t value_count = std::size(test_values);
   for (unsigned int i = 0; i < value_count; ++i) {
     CGFloat aligned = AlignValueToPixel(test_values[i]);
     EXPECT_FLOAT_EQ(aligned * scale, floor(aligned * scale));
diff --git a/ios/chrome/common/x_callback_url_unittest.cc b/ios/chrome/common/x_callback_url_unittest.cc
index a546071..0c15c76 100644
--- a/ios/chrome/common/x_callback_url_unittest.cc
+++ b/ios/chrome/common/x_callback_url_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ios/chrome/common/x_callback_url.h"
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
@@ -109,7 +108,7 @@
       },
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     const XCallbackURLEncodeTestCase& test_case = test_cases[i];
     const GURL x_callback_url = CreateXCallbackURLWithParameters(
         test_case.scheme, test_case.action, test_case.success_url,
@@ -171,7 +170,7 @@
       },
   };
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
+  for (size_t i = 0; i < std::size(test_cases); ++i) {
     const XCallbackURLDecodeTestCase& test_case = test_cases[i];
     const std::map<std::string, std::string> parameters =
         ExtractQueryParametersFromXCallbackURL(test_case.x_callback_url);
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h
index bea1473..738ab80 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.h
+++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -631,6 +631,17 @@
 // Returns a matcher for the button to share tabs.
 id<GREYMatcher> TabGridEditShareButton();
 
+#pragma mark - Tab Grid Search Mode
+
+// Returns a matcher for the button to enter the tab grid search mode.
+id<GREYMatcher> TabGridSearchTabsButton();
+
+// Returns a matcher for the tab grid search bar text field.
+id<GREYMatcher> TabGridSearchBar();
+
+// Returns a matcher for the tab grid search cancel button.
+id<GREYMatcher> TabGridSearchCancelButton();
+
 }  // namespace chrome_test_util
 
 #endif  // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_H_
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm
index bd7c657..89f1ce4 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -787,4 +787,18 @@
   return [ChromeMatchersAppInterface tabGridEditShareButton];
 }
 
+#pragma mark - Tab Grid Search Mode
+
+id<GREYMatcher> TabGridSearchTabsButton() {
+  return [ChromeMatchersAppInterface tabGridSearchTabsButton];
+}
+
+id<GREYMatcher> TabGridSearchBar() {
+  return [ChromeMatchersAppInterface tabGridSearchBar];
+}
+
+id<GREYMatcher> TabGridSearchCancelButton() {
+  return [ChromeMatchersAppInterface tabGridSearchCancelButton];
+}
+
 }  // namespace chrome_test_util
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
index d7b05c2..3a5fa9ae 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
+++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -616,6 +616,17 @@
 // Returns a matcher for the button to share tabs.
 + (id<GREYMatcher>)tabGridEditShareButton;
 
+#pragma mark - Tab Grid Search Mode
+
+// Returns a matcher for the button to enter the tab grid search mode.
++ (id<GREYMatcher>)tabGridSearchTabsButton;
+
+// Returns a matcher for the tab grid search bar.
++ (id<GREYMatcher>)tabGridSearchBar;
+
+// Returns a matcher for the tab grid search cancel button.
++ (id<GREYMatcher>)tabGridSearchCancelButton;
+
 @end
 
 #endif  // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_APP_INTERFACE_H_
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
index fddc865..78417e2 100644
--- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -1198,4 +1198,20 @@
                     grey_sufficientlyVisible(), nil);
 }
 
+#pragma mark - Tab Grid Search Mode
++ (id<GREYMatcher>)tabGridSearchTabsButton {
+  return grey_allOf(grey_accessibilityID(kTabGridSearchButtonIdentifier),
+                    grey_sufficientlyVisible(), nil);
+}
+
++ (id<GREYMatcher>)tabGridSearchBar {
+  return grey_allOf(grey_accessibilityID(kTabGridSearchBarIdentifier),
+                    grey_sufficientlyVisible(), nil);
+}
+
++ (id<GREYMatcher>)tabGridSearchCancelButton {
+  return grey_allOf(grey_accessibilityID(kTabGridCancelButtonIdentifier),
+                    grey_sufficientlyVisible(), nil);
+}
+
 @end
diff --git a/ios/chrome/test/variations_smoke_test/variations_smoke_test_app_interface.mm b/ios/chrome/test/variations_smoke_test/variations_smoke_test_app_interface.mm
index 54c4876e..bdbddf6 100644
--- a/ios/chrome/test/variations_smoke_test/variations_smoke_test_app_interface.mm
+++ b/ios/chrome/test/variations_smoke_test/variations_smoke_test_app_interface.mm
@@ -27,7 +27,7 @@
   struct kinfo_proc info;
   size_t length = sizeof(struct kinfo_proc);
   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)getpid()};
-  const int kr = sysctl(mib, base::size(mib), &info, &length, nullptr, 0);
+  const int kr = sysctl(mib, std::size(mib), &info, &length, nullptr, 0);
   DCHECK_EQ(KERN_SUCCESS, kr);
   return base::Time::FromTimeVal(info.kp_proc.p_starttime);
 }
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index 39bd42b..2ab526c6 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-144d31ef85d9908ec552e5ad76aa3ab0ed199c19
\ No newline at end of file
+ba6ad1c638e3256b31133e08caf9485c93051d32
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 747efc0..e6054dd9 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-39102119a6c26dee837eb0384e4fcdb76795308d
\ No newline at end of file
+a09c859cafe91f68e00e9e59e18eef74983660bc
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 986e4ee1..28e83dc9 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-ffad931760efb4aaad272aa7cb4069c145f898ac
\ No newline at end of file
+7f8132105ae765dccd9c6a414b2355cbd09294a8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 0c6c87f6..d179395 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-17bdf3233e57cd95fff84003d69379793c9146b7
\ No newline at end of file
+839c876884736427f6452e1f402bface6f7f54ac
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index c3d550e..227ec86 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a04f6dd0b0cb6514a0efd24015bb6160963efb5a
\ No newline at end of file
+3c26ca277558f14ad8dbb5c226c036ded76c1967
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index 1ef08a9..58c4242 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-fa8d623b33cfdda448de0c69d2b3fc32ce886f57
\ No newline at end of file
+6ac3db609148a88ef0d2fd48aa19c1a7aca1a182
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index bbadeaf..684f1ea 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-e5323bf840b10d6636b4368dee04c81fed5f07a7
\ No newline at end of file
+9678939255d6c5b7002470c81d949ab2f3354f6f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index a8be1b22..63ded5a 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-ee8d55521a4140fa2efdc9655bc9074e95be51c1
\ No newline at end of file
+ebc520291875285bea815a89d33740cd22b878e1
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index f211e8f..7ea93d560 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-0fa1f3773a57ce1732e5436e158fc83bf865fc76
\ No newline at end of file
+a2b63f6d53116c036b8617c89bad9b8835b931ef
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 47c4020..3589fb5 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-a07a42101446c82adc398cb9f8d613869df195a8
\ No newline at end of file
+c13c3898bb1e5529c903fb5a1f6aad71fbdfe16b
\ 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 3898f4f..3123e9e6 100644
--- a/ios/net/url_scheme_util_unittest.mm
+++ b/ios/net/url_scheme_util_unittest.mm
@@ -6,7 +6,6 @@
 
 #import <Foundation/Foundation.h>
 
-#include "base/cxx17_backports.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
 #include "url/gurl.h"
@@ -28,7 +27,7 @@
 using URLSchemeUtilTest = PlatformTest;
 
 TEST_F(URLSchemeUtilTest, NSURLHasDataScheme) {
-  for (unsigned int i = 0; i < base::size(kSchemeTestData); ++i) {
+  for (unsigned int i = 0; i < std::size(kSchemeTestData); ++i) {
     const char* url = kSchemeTestData[i];
     bool nsurl_result = UrlHasDataScheme(
         [NSURL URLWithString:[NSString stringWithUTF8String:url]]);
diff --git a/ios/web/common/referrer_util_unittest.cc b/ios/web/common/referrer_util_unittest.cc
index 3ad3730..661e807 100644
--- a/ios/web/common/referrer_util_unittest.cc
+++ b/ios/web/common/referrer_util_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ios/web/common/referrer_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"
@@ -30,8 +29,8 @@
 // Tests that no matter what the transition and policy, the result is always
 // stripped of things that should not be in a referrer (e.g., passwords).
 TEST_F(ReferrerUtilTest, ReferrerSanitization) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 0; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 0; dest < std::size(kTestUrls); ++dest) {
       for (unsigned int policy = 0; policy <= ReferrerPolicyLast; ++policy) {
         Referrer referrer(GURL(kTestUrls[source]),
                           static_cast<ReferrerPolicy>(policy));
@@ -46,8 +45,8 @@
 
 // Tests that the Always policy works as expected.
 TEST_F(ReferrerUtilTest, AlwaysPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyAlways);
@@ -62,8 +61,8 @@
 // Tests that the Default policy works as expected, and matches
 // NoReferrerWhenDowngrade.
 TEST_F(ReferrerUtilTest, DefaultPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyDefault);
@@ -85,8 +84,8 @@
 
 // Tests that the Never policy works as expected.
 TEST_F(ReferrerUtilTest, NeverPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyNever);
@@ -100,8 +99,8 @@
 
 // Tests that the Origin policy works as expected.
 TEST_F(ReferrerUtilTest, OriginPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyOrigin);
@@ -115,8 +114,8 @@
 
 // Tests that the OriginWhenCrossOrigin policy works as expected.
 TEST_F(ReferrerUtilTest, OriginWhenCrossOriginPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyOriginWhenCrossOrigin);
@@ -135,8 +134,8 @@
 
 // Tests that the same-origin policy works as expected.
 TEST_F(ReferrerUtilTest, SameOriginPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicySameOrigin);
@@ -154,8 +153,8 @@
 
 // Tests that the strict-origin policy works as expected.
 TEST_F(ReferrerUtilTest, StrictOriginPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyStrictOrigin);
@@ -173,8 +172,8 @@
 
 // Tests that the strict-origin-when-cross-origin policy works as expected.
 TEST_F(ReferrerUtilTest, StrictOriginWhenCrossOriginPolicy) {
-  for (unsigned int source = 0; source < base::size(kTestUrls); ++source) {
-    for (unsigned int dest = 1; dest < base::size(kTestUrls); ++dest) {
+  for (unsigned int source = 0; source < std::size(kTestUrls); ++source) {
+    for (unsigned int dest = 1; dest < std::size(kTestUrls); ++dest) {
       GURL source_url(kTestUrls[source]);
       GURL dest_url(kTestUrls[dest]);
       Referrer referrer(source_url, ReferrerPolicyStrictOriginWhenCrossOrigin);
@@ -266,7 +265,7 @@
   // Verify that if something is added to the enum, its string value gets added
   // to the mapping function.
   EXPECT_EQ(ReferrerPolicyLast + 1,
-            static_cast<int>(base::size(kPolicyStrings)));
+            static_cast<int>(std::size(kPolicyStrings)));
 
   // Test the legacy policy names.
   EXPECT_EQ(ReferrerPolicyNever, ReferrerPolicyFromString("never"));
diff --git a/ios/web/history_state_util_unittest.mm b/ios/web/history_state_util_unittest.mm
index c117f50e..c5c5b32 100644
--- a/ios/web/history_state_util_unittest.mm
+++ b/ios/web/history_state_util_unittest.mm
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
@@ -63,7 +62,7 @@
 };
 
 TEST_F(HistoryStateUtilTest, TestIsHistoryStateChangeValid) {
-  for (size_t i = 0; i < base::size(tests_); ++i) {
+  for (size_t i = 0; i < std::size(tests_); ++i) {
     GURL fromUrl(tests_[i].fromUrl);
     GURL toUrl = history_state_util::GetHistoryStateChangeUrl(fromUrl, fromUrl,
                                                               tests_[i].toUrl);
@@ -79,7 +78,7 @@
 }
 
 TEST_F(HistoryStateUtilTest, TestGetHistoryStateChangeUrl) {
-  for (size_t i = 0; i < base::size(tests_); ++i) {
+  for (size_t i = 0; i < std::size(tests_); ++i) {
     GURL fromUrl(tests_[i].fromUrl);
     GURL expectedResult(tests_[i].expectedUrl);
     GURL actualResult = history_state_util::GetHistoryStateChangeUrl(
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm
index c7d661f..9a7e700 100644
--- a/ios/web/navigation/navigation_manager_impl_unittest.mm
+++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -1581,7 +1581,7 @@
                             PageDisplayState()};
 
   std::vector<std::unique_ptr<NavigationItem>> items;
-  for (size_t index = 0; index < base::size(restore_information); ++index) {
+  for (size_t index = 0; index < std::size(restore_information); ++index) {
     items.push_back(NavigationItem::Create());
     items.back()->SetURL(restore_information[index].url);
     items.back()->SetVirtualURL(restore_information[index].virtual_url);
@@ -1631,7 +1631,7 @@
   EXPECT_EQ(restore_information[1].url,
             navigation_manager()->GetLastCommittedItem()->GetURL());
 
-  for (size_t i = 0; i < base::size(restore_information); ++i) {
+  for (size_t i = 0; i < std::size(restore_information); ++i) {
     NavigationItem* navigation_item = navigation_manager()->GetItemAtIndex(i);
     EXPECT_EQ(restore_information[i].url, navigation_item->GetURL());
 
diff --git a/ios/web/navigation/nscoder_util_unittest.mm b/ios/web/navigation/nscoder_util_unittest.mm
index a0cf35ed..14229de 100644
--- a/ios/web/navigation/nscoder_util_unittest.mm
+++ b/ios/web/navigation/nscoder_util_unittest.mm
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#import "ios/web/navigation/nscoder_util.h"
+
 #import <Foundation/Foundation.h>
 #include <stddef.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"
 
@@ -29,7 +29,7 @@
 };
 
 TEST_F(NSCoderStdStringTest, encodeDecode) {
-  for (size_t i = 0; i < base::size(testStrings); ++i) {
+  for (size_t i = 0; i < std::size(testStrings); ++i) {
     NSKeyedArchiver* archiver =
         [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
     nscoder_util::EncodeString(archiver, @"test", testStrings[i]);
diff --git a/ios/web/web_state/js/common_js_unittest.mm b/ios/web/web_state/js/common_js_unittest.mm
index ab18f3d..067c326 100644
--- a/ios/web/web_state/js/common_js_unittest.mm
+++ b/ios/web/web_state/js/common_js_unittest.mm
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <stddef.h>
 #import <Foundation/Foundation.h>
+#include <stddef.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"
@@ -86,7 +85,7 @@
       {"state", 0, false},
       {"cars", 0, false},
       {"submit", 0, false}};
-  for (size_t i = 0; i < base::size(testElements); ++i) {
+  for (size_t i = 0; i < std::size(testElements); ++i) {
     TextFieldTestElement element = testElements[i];
     id result = ExecuteJavaScript([NSString
         stringWithFormat:@"__gCrWeb.common.isTextField("
@@ -130,7 +129,7 @@
       {@"__gCrWeb.stringify(undefined)", @"undefined"},
   };
 
-  for (size_t i = 0; i < base::size(test_data); i++) {
+  for (size_t i = 0; i < std::size(test_data); i++) {
     TestScriptAndExpectedValue& data = test_data[i];
     // Load a sample HTML page. As a side-effect, loading HTML via
     // |webController_| will also inject web_bundle.js.
@@ -161,7 +160,7 @@
       {@"data:abc", @"data:abc"},
       {@"javascript:login()", @"javascript:login()"},
   };
-  for (size_t i = 0; i < base::size(test_data); i++) {
+  for (size_t i = 0; i < std::size(test_data); i++) {
     LoadHtml(@"<p>");
     TestData& data = test_data[i];
     id result = ExecuteJavaScript(
@@ -184,7 +183,7 @@
       {@"'http://abc.com', 'http://def.com'", @NO},
       {@"'http://abc.com/def', 'http://abc.com/xyz'", @YES}};
 
-  for (size_t i = 0; i < base::size(test_data); i++) {
+  for (size_t i = 0; i < std::size(test_data); i++) {
     TestScriptAndExpectedValue& data = test_data[i];
     LoadHtml(@"<p>");
     id result = ExecuteJavaScript(
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index b4cababe..046d052 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -1026,7 +1026,7 @@
                   GURL("https://chromium.test/2"),
                   GURL("https://chromium.test/3")};
   std::vector<std::unique_ptr<NavigationItem>> items;
-  for (size_t index = 0; index < base::size(urls); ++index) {
+  for (size_t index = 0; index < std::size(urls); ++index) {
     items.push_back(NavigationItem::Create());
     items.back()->SetURL(urls[index]);
   }
@@ -1266,7 +1266,7 @@
                   GURL("https://chromium.test/2"),
                   GURL("https://chromium.test/3")};
   std::vector<std::unique_ptr<NavigationItem>> items;
-  for (size_t index = 0; index < base::size(urls); ++index) {
+  for (size_t index = 0; index < std::size(urls); ++index) {
     items.push_back(NavigationItem::Create());
     items.back()->SetURL(urls[index]);
   }
@@ -1288,7 +1288,7 @@
   scoped_feature_list.Reset();
   scoped_feature_list.InitWithFeatures({features::kSynthesizedRestoreSession},
                                        {});
-  for (size_t index = 0; index < base::size(urls); ++index) {
+  for (size_t index = 0; index < std::size(urls); ++index) {
     items.push_back(NavigationItem::Create());
     items.back()->SetURL(urls[index]);
   }
diff --git a/ios/web/webui/url_data_manager_ios_backend.mm b/ios/web/webui/url_data_manager_ios_backend.mm
index 4b6c531..613a457 100644
--- a/ios/web/webui/url_data_manager_ios_backend.mm
+++ b/ios/web/webui/url_data_manager_ios_backend.mm
@@ -9,7 +9,6 @@
 #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"
@@ -373,7 +372,7 @@
 int URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size) {
   // http://crbug.com/373841
   char url_buf[128];
-  base::strlcpy(url_buf, request_->url().spec().c_str(), base::size(url_buf));
+  base::strlcpy(url_buf, request_->url().spec().c_str(), std::size(url_buf));
   base::debug::Alias(url_buf);
 
   int remaining = data_->size() - data_offset_;
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 5a3f819..640a062 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -118,6 +118,8 @@
     "internal/autofill/web_view_personal_data_manager_factory.mm",
     "internal/autofill/web_view_strike_database_factory.h",
     "internal/autofill/web_view_strike_database_factory.mm",
+    "internal/component_updater/web_view_component_updater_configurator.h",
+    "internal/component_updater/web_view_component_updater_configurator.mm",
     "internal/cwv_back_forward_list.mm",
     "internal/cwv_back_forward_list_internal.h",
     "internal/cwv_back_forward_list_item.mm",
@@ -269,6 +271,8 @@
     "//components/autofill/ios/form_util",
     "//components/autofill/ios/form_util:form_handler_feature",
     "//components/browser_sync",
+    "//components/component_updater",
+    "//components/component_updater/installer_policies",
     "//components/flags_ui",
     "//components/flags_ui:switches",
     "//components/gcm_driver",
@@ -298,6 +302,8 @@
     "//components/proxy_config",
     "//components/safe_browsing/core/common:safe_browsing_prefs",
     "//components/security_state/ios",
+    "//components/services/patch:in_process",
+    "//components/services/unzip:in_process",
     "//components/signin/core/browser",
     "//components/signin/ios/browser",
     "//components/signin/public/identity_manager",
@@ -311,6 +317,8 @@
     "//components/translate/core/common",
     "//components/translate/ios/browser",
     "//components/unified_consent",
+    "//components/update_client",
+    "//components/update_client:common_impl",
     "//components/url_formatter",
     "//components/variations",
     "//components/variations/net",
diff --git a/ios/web_view/internal/DEPS b/ios/web_view/internal/DEPS
index fdb1f20..df5fdc4 100644
--- a/ios/web_view/internal/DEPS
+++ b/ios/web_view/internal/DEPS
@@ -2,6 +2,7 @@
   "+base",
   "+components/autofill",
   "+components/browser_sync",
+  "+components/component_updater",
   "+components/content_settings/core",
   "+components/flags_ui",
   "+components/gcm_driver",
@@ -38,10 +39,13 @@
   "+components/language/ios",
   "+components/unified_consent",
   "+components/url_formatter",
+  "+components/update_client",
   "+components/variations",
   "+components/version_info",
   "+components/webdata_services",
   "+components/web_resource",
+  "+components/services/patch",
+  "+components/services/unzip",
   "+google_apis",
   "+ios/components/credential_provider_extension",
   "+ios/components/io_thread",
diff --git a/ios/web_view/internal/component_updater/web_view_component_updater_configurator.h b/ios/web_view/internal/component_updater/web_view_component_updater_configurator.h
new file mode 100644
index 0000000..05091a4
--- /dev/null
+++ b/ios/web_view/internal/component_updater/web_view_component_updater_configurator.h
@@ -0,0 +1,25 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_VIEW_INTERNAL_COMPONENT_UPDATER_WEB_VIEW_COMPONENT_UPDATER_CONFIGURATOR_H_
+#define IOS_WEB_VIEW_INTERNAL_COMPONENT_UPDATER_WEB_VIEW_COMPONENT_UPDATER_CONFIGURATOR_H_
+
+#include "base/memory/ref_counted.h"
+#include "components/update_client/configurator.h"
+
+namespace base {
+class CommandLine;
+}
+
+namespace ios_web_view {
+
+// Returns a configurator for updating components.
+// See similar implementation at
+// //ios/chrome/browser/component_updater/ios_component_updater_configurator.h
+scoped_refptr<update_client::Configurator> MakeComponentUpdaterConfigurator(
+    const base::CommandLine* cmdline);
+
+}  // namespace ios_web_view
+
+#endif  // IOS_WEB_VIEW_INTERNAL_COMPONENT_UPDATER_WEB_VIEW_COMPONENT_UPDATER_CONFIGURATOR_H_
diff --git a/ios/web_view/internal/component_updater/web_view_component_updater_configurator.mm b/ios/web_view/internal/component_updater/web_view_component_updater_configurator.mm
new file mode 100644
index 0000000..1e83b2b
--- /dev/null
+++ b/ios/web_view/internal/component_updater/web_view_component_updater_configurator.mm
@@ -0,0 +1,238 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/web_view/internal/component_updater/web_view_component_updater_configurator.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/containers/flat_map.h"
+#include "base/version.h"
+#include "components/component_updater/component_updater_command_line_config_policy.h"
+#include "components/component_updater/configurator_impl.h"
+#include "components/services/patch/in_process_file_patcher.h"
+#include "components/services/unzip/in_process_unzipper.h"
+#include "components/update_client/activity_data_service.h"
+#include "components/update_client/crx_downloader_factory.h"
+#include "components/update_client/net/network_chromium.h"
+#include "components/update_client/patch/patch_impl.h"
+#include "components/update_client/patcher.h"
+#include "components/update_client/protocol_handler.h"
+#include "components/update_client/unzip/unzip_impl.h"
+#include "components/update_client/unzipper.h"
+#include "components/update_client/update_query_params.h"
+#include "ios/web_view/internal/app/application_context.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace ios_web_view {
+
+namespace {
+
+// A //ios/web_view specific configurator.
+// See similar implementation at
+// //ios/chrome/browser/component_updater/ios_component_updater_configurator.mm
+class WebViewConfigurator : public update_client::Configurator {
+ public:
+  explicit WebViewConfigurator(const base::CommandLine* cmdline);
+
+  // update_client::Configurator overrides.
+  double InitialDelay() const override;
+  int NextCheckDelay() const override;
+  int OnDemandDelay() const override;
+  int UpdateDelay() const override;
+  std::vector<GURL> UpdateUrl() const override;
+  std::vector<GURL> PingUrl() const override;
+  std::string GetProdId() const override;
+  base::Version GetBrowserVersion() const override;
+  std::string GetChannel() const override;
+  std::string GetLang() const override;
+  std::string GetOSLongName() const override;
+  base::flat_map<std::string, std::string> ExtraRequestParams() const override;
+  std::string GetDownloadPreference() const override;
+  scoped_refptr<update_client::NetworkFetcherFactory> GetNetworkFetcherFactory()
+      override;
+  scoped_refptr<update_client::CrxDownloaderFactory> GetCrxDownloaderFactory()
+      override;
+  scoped_refptr<update_client::UnzipperFactory> GetUnzipperFactory() override;
+  scoped_refptr<update_client::PatcherFactory> GetPatcherFactory() override;
+  bool EnabledDeltas() const override;
+  bool EnabledBackgroundDownloader() const override;
+  bool EnabledCupSigning() const override;
+  PrefService* GetPrefService() const override;
+  update_client::ActivityDataService* GetActivityDataService() const override;
+  bool IsPerUserInstall() const override;
+  std::unique_ptr<update_client::ProtocolHandlerFactory>
+  GetProtocolHandlerFactory() const override;
+  absl::optional<bool> IsMachineExternallyManaged() const override;
+  update_client::UpdaterStateProvider GetUpdaterStateProvider() const override;
+
+ private:
+  friend class base::RefCountedThreadSafe<WebViewConfigurator>;
+
+  component_updater::ConfiguratorImpl configurator_impl_;
+  scoped_refptr<update_client::NetworkFetcherFactory> network_fetcher_factory_;
+  scoped_refptr<update_client::CrxDownloaderFactory> crx_downloader_factory_;
+  scoped_refptr<update_client::UnzipperFactory> unzip_factory_;
+  scoped_refptr<update_client::PatcherFactory> patch_factory_;
+
+  ~WebViewConfigurator() override = default;
+};
+
+// Allows the component updater to use non-encrypted communication with the
+// update backend. The security of the update checks is enforced using
+// a custom message signing protocol and it does not depend on using HTTPS.
+WebViewConfigurator::WebViewConfigurator(const base::CommandLine* cmdline)
+    : configurator_impl_(
+          component_updater::ComponentUpdaterCommandLineConfigPolicy(cmdline),
+          /*require_encryption=*/false) {}
+
+double WebViewConfigurator::InitialDelay() const {
+  return configurator_impl_.InitialDelay();
+}
+
+int WebViewConfigurator::NextCheckDelay() const {
+  return configurator_impl_.NextCheckDelay();
+}
+
+int WebViewConfigurator::OnDemandDelay() const {
+  return configurator_impl_.OnDemandDelay();
+}
+
+int WebViewConfigurator::UpdateDelay() const {
+  return configurator_impl_.UpdateDelay();
+}
+
+std::vector<GURL> WebViewConfigurator::UpdateUrl() const {
+  return configurator_impl_.UpdateUrl();
+}
+
+std::vector<GURL> WebViewConfigurator::PingUrl() const {
+  return configurator_impl_.PingUrl();
+}
+
+std::string WebViewConfigurator::GetProdId() const {
+  return update_client::UpdateQueryParams::GetProdIdString(
+      update_client::UpdateQueryParams::ProdId::WEBVIEW);
+}
+
+base::Version WebViewConfigurator::GetBrowserVersion() const {
+  return configurator_impl_.GetBrowserVersion();
+}
+
+std::string WebViewConfigurator::GetChannel() const {
+  // TODO(crbug.com/1299888): Pass proper channel depending on build type.
+  return "stable";
+}
+
+std::string WebViewConfigurator::GetLang() const {
+  return ApplicationContext::GetInstance()->GetApplicationLocale();
+}
+
+std::string WebViewConfigurator::GetOSLongName() const {
+  return configurator_impl_.GetOSLongName();
+}
+
+base::flat_map<std::string, std::string>
+WebViewConfigurator::ExtraRequestParams() const {
+  return configurator_impl_.ExtraRequestParams();
+}
+
+std::string WebViewConfigurator::GetDownloadPreference() const {
+  return configurator_impl_.GetDownloadPreference();
+}
+
+scoped_refptr<update_client::NetworkFetcherFactory>
+WebViewConfigurator::GetNetworkFetcherFactory() {
+  if (!network_fetcher_factory_) {
+    network_fetcher_factory_ =
+        base::MakeRefCounted<update_client::NetworkFetcherChromiumFactory>(
+            ApplicationContext::GetInstance()->GetSharedURLLoaderFactory(),
+            // Never send cookies for component update downloads.
+            base::BindRepeating([](const GURL& url) { return false; }));
+  }
+  return network_fetcher_factory_;
+}
+
+scoped_refptr<update_client::CrxDownloaderFactory>
+WebViewConfigurator::GetCrxDownloaderFactory() {
+  if (!crx_downloader_factory_) {
+    crx_downloader_factory_ =
+        update_client::MakeCrxDownloaderFactory(GetNetworkFetcherFactory());
+  }
+  return crx_downloader_factory_;
+}
+
+scoped_refptr<update_client::UnzipperFactory>
+WebViewConfigurator::GetUnzipperFactory() {
+  if (!unzip_factory_) {
+    unzip_factory_ = base::MakeRefCounted<update_client::UnzipChromiumFactory>(
+        base::BindRepeating(&unzip::LaunchInProcessUnzipper));
+  }
+  return unzip_factory_;
+}
+
+scoped_refptr<update_client::PatcherFactory>
+WebViewConfigurator::GetPatcherFactory() {
+  if (!patch_factory_) {
+    patch_factory_ = base::MakeRefCounted<update_client::PatchChromiumFactory>(
+        base::BindRepeating(&patch::LaunchInProcessFilePatcher));
+  }
+  return patch_factory_;
+}
+
+bool WebViewConfigurator::EnabledDeltas() const {
+  return configurator_impl_.EnabledDeltas();
+}
+
+bool WebViewConfigurator::EnabledBackgroundDownloader() const {
+  return configurator_impl_.EnabledBackgroundDownloader();
+}
+
+bool WebViewConfigurator::EnabledCupSigning() const {
+  return configurator_impl_.EnabledCupSigning();
+}
+
+PrefService* WebViewConfigurator::GetPrefService() const {
+  return ApplicationContext::GetInstance()->GetLocalState();
+}
+
+update_client::ActivityDataService*
+WebViewConfigurator::GetActivityDataService() const {
+  return nullptr;
+}
+
+bool WebViewConfigurator::IsPerUserInstall() const {
+  return true;
+}
+
+std::unique_ptr<update_client::ProtocolHandlerFactory>
+WebViewConfigurator::GetProtocolHandlerFactory() const {
+  return configurator_impl_.GetProtocolHandlerFactory();
+}
+
+absl::optional<bool> WebViewConfigurator::IsMachineExternallyManaged() const {
+  return configurator_impl_.IsMachineExternallyManaged();
+}
+
+update_client::UpdaterStateProvider
+WebViewConfigurator::GetUpdaterStateProvider() const {
+  return configurator_impl_.GetUpdaterStateProvider();
+}
+
+}  // namespace
+
+scoped_refptr<update_client::Configurator> MakeComponentUpdaterConfigurator(
+    const base::CommandLine* cmdline) {
+  return base::MakeRefCounted<WebViewConfigurator>(cmdline);
+}
+
+}  // namespace ios_web_view
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 6ffc0942..c25a221 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -323,6 +323,7 @@
     ]
     deps += [
       "//media/fuchsia/audio",
+      "//media/fuchsia/common",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media",
       "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
     ]
@@ -479,6 +480,7 @@
   }
 
   if (is_fuchsia) {
+    sources += [ "fuchsia/audio_input_stream_fuchsia_test.cc" ]
     deps += [ "//media/fuchsia/audio:test_support" ]
   }
 
diff --git a/media/audio/fuchsia/audio_input_stream_fuchsia.cc b/media/audio/fuchsia/audio_input_stream_fuchsia.cc
index e5b91652..0bb367e 100644
--- a/media/audio/fuchsia/audio_input_stream_fuchsia.cc
+++ b/media/audio/fuchsia/audio_input_stream_fuchsia.cc
@@ -5,7 +5,9 @@
 #include "media/audio/fuchsia/audio_input_stream_fuchsia.h"
 
 #include <lib/sys/cpp/component_context.h>
+#include <lib/zx/vmo.h>
 
+#include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/process_context.h"
 #include "base/logging.h"
 #include "media/audio/audio_device_description.h"
@@ -13,28 +15,15 @@
 
 namespace media {
 
-class AudioInputStreamFuchsia::CaptureCallbackAdapter
-    : public AudioCapturerSource::CaptureCallback {
- public:
-  CaptureCallbackAdapter(AudioInputCallback* callback) : callback_(callback) {}
+namespace {
 
-  void Capture(const AudioBus* audio_source,
-               base::TimeTicks audio_capture_time,
-               double volume,
-               bool key_pressed) override {
-    callback_->OnData(audio_source, audio_capture_time, volume);
-  }
+// Currently AudioCapturer supports only one payload buffer with id=0.
+constexpr uint32_t kBufferId = 0;
 
-  void OnCaptureError(AudioCapturerSource::ErrorCode code,
-                      const std::string& message) override {
-    callback_->OnError();
-  }
+// Number of audio packets that should fit in the capture buffer.
+constexpr size_t kBufferPacketCapacity = 10;
 
-  void OnCaptureMuted(bool is_muted) override {}
-
- private:
-  AudioInputCallback* callback_;
-};
+}  // namespace
 
 AudioInputStreamFuchsia::AudioInputStreamFuchsia(
     AudioManagerFuchsia* manager,
@@ -47,41 +36,90 @@
          device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId ||
          device_id_ == AudioDeviceDescription::kDefaultDeviceId)
       << "AudioInput from " << device_id_ << " not implemented!";
+  DCHECK(parameters_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY ||
+         parameters_.format() == AudioParameters::AUDIO_PCM_LINEAR);
 }
 
 AudioInputStreamFuchsia::~AudioInputStreamFuchsia() = default;
 
 AudioInputStream::OpenOutcome AudioInputStreamFuchsia::Open() {
-  return OpenOutcome::kSuccess;
-}
+  // Open() can be called only once.
+  DCHECK(!capturer_);
 
-void AudioInputStreamFuchsia::Start(AudioInputCallback* callback) {
-  fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer;
   auto factory = base::ComponentContextForProcess()
                      ->svc()
                      ->Connect<fuchsia::media::Audio>();
   bool is_loopback =
       device_id_ == AudioDeviceDescription::kLoopbackInputDeviceId;
-  factory->CreateAudioCapturer(capturer.NewRequest(), is_loopback);
+  factory->CreateAudioCapturer(capturer_.NewRequest(), is_loopback);
+  capturer_.set_error_handler([this](zx_status_t status) {
+    ZX_LOG(ERROR, status) << "AudioCapturer disconnected";
+    ReportError();
+  });
 
-  capturer_source_ = base::MakeRefCounted<FuchsiaAudioCapturerSource>(
-      std::move(capturer), manager_->GetTaskRunner());
-  callback_adapter_ = std::make_unique<CaptureCallbackAdapter>(callback);
-  capturer_source_->Initialize(parameters_, callback_adapter_.get());
-  capturer_source_->SetAutomaticGainControl(automatic_gain_control_);
-  capturer_source_->Start();
+  // Bind the event for incoming packets.
+  capturer_.events().OnPacketProduced =
+      fit::bind_member(this, &AudioInputStreamFuchsia::OnPacketProduced);
+
+  // Configure stream format.
+  fuchsia::media::AudioStreamType stream_type;
+  stream_type.sample_format = fuchsia::media::AudioSampleFormat::FLOAT;
+  stream_type.channels = parameters_.channels();
+  stream_type.frames_per_second = parameters_.sample_rate();
+  capturer_->SetPcmStreamType(std::move(stream_type));
+
+  // Allocate shared buffer.
+  size_t capture_buffer_size =
+      parameters_.GetBytesPerBuffer(kSampleFormatF32) * kBufferPacketCapacity;
+
+  zx::vmo buffer_vmo;
+  zx_status_t status = zx::vmo::create(capture_buffer_size, 0, &buffer_vmo);
+  ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
+
+  constexpr char kName[] = "cr-audio-capturer";
+  status = buffer_vmo.set_property(ZX_PROP_NAME, kName, base::size(kName) - 1);
+  ZX_DCHECK(status == ZX_OK, status);
+
+  bool mapped =
+      capture_buffer_.Initialize(std::move(buffer_vmo), /*writable=*/false,
+                                 /*offset=*/0, /*size=*/capture_buffer_size,
+                                 fuchsia::sysmem::CoherencyDomain::CPU);
+
+  if (!mapped)
+    return OpenOutcome::kFailed;
+
+  // Pass the buffer to the capturer.
+  capturer_->AddPayloadBuffer(kBufferId,
+                              capture_buffer_.Duplicate(/*writable=*/true));
+
+  return OpenOutcome::kSuccess;
+}
+
+void AudioInputStreamFuchsia::Start(AudioInputCallback* callback) {
+  if (!capturer_) {
+    callback->OnError();
+    return;
+  }
+
+  callback_ = callback;
+
+  if (!is_capturer_started_) {
+    is_capturer_started_ = true;
+    capturer_->StartAsyncCapture(parameters_.frames_per_buffer());
+  }
 }
 
 void AudioInputStreamFuchsia::Stop() {
-  if (capturer_source_) {
-    capturer_source_->Stop();
-    capturer_source_ = nullptr;
-  }
+  // Normally Close() is called immediately after Stop(), so there is no need to
+  // stop the capturer. Just release the |callback_| to ensure it's not called
+  // again.
+  callback_ = nullptr;
 }
 
 void AudioInputStreamFuchsia::Close() {
   Stop();
-  manager_->ReleaseInputStream(this);
+  if (manager_)
+    manager_->ReleaseInputStream(this);
 }
 
 double AudioInputStreamFuchsia::GetMaxVolume() {
@@ -89,32 +127,63 @@
 }
 
 void AudioInputStreamFuchsia::SetVolume(double volume) {
-  capturer_source_->SetVolume(volume);
-  volume_ = volume;
+  NOTIMPLEMENTED();
 }
 
 double AudioInputStreamFuchsia::GetVolume() {
-  return volume_;
+  return 1.0;
 }
 
 bool AudioInputStreamFuchsia::SetAutomaticGainControl(bool enabled) {
-  automatic_gain_control_ = enabled;
-  if (capturer_source_)
-    capturer_source_->SetAutomaticGainControl(automatic_gain_control_);
-  return true;
+  NOTIMPLEMENTED();
+  return false;
 }
 
 bool AudioInputStreamFuchsia::GetAutomaticGainControl() {
-  return automatic_gain_control_;
+  return false;
 }
 
 bool AudioInputStreamFuchsia::IsMuted() {
-  return volume_ == 0.0;
+  return false;
 }
 
 void AudioInputStreamFuchsia::SetOutputDeviceForAec(
     const std::string& output_device_id) {
-  capturer_source_->SetOutputDeviceForAec(output_device_id);
+  NOTIMPLEMENTED();
+}
+
+void AudioInputStreamFuchsia::OnPacketProduced(
+    fuchsia::media::StreamPacket packet) {
+  size_t bytes_per_frame = parameters_.GetBytesPerFrame(kSampleFormatF32);
+
+  if (packet.payload_buffer_id != kBufferId ||
+      packet.payload_offset + packet.payload_size > capture_buffer_.size() ||
+      packet.payload_size % bytes_per_frame != 0 ||
+      packet.payload_size < bytes_per_frame) {
+    LOG(ERROR) << "Received invalid packet from AudioCapturer.";
+    ReportError();
+    return;
+  }
+
+  if (callback_) {
+    int num_frames = packet.payload_size / bytes_per_frame;
+    if (!audio_bus_ || num_frames != audio_bus_->frames())
+      audio_bus_ = AudioBus::Create(parameters_.channels(), num_frames);
+    audio_bus_->FromInterleaved<Float32SampleTypeTraits>(
+        reinterpret_cast<const float*>(capture_buffer_.GetMemory().data() +
+                                       packet.payload_offset),
+        num_frames);
+    callback_->OnData(audio_bus_.get(), base::TimeTicks::FromZxTime(packet.pts),
+                      /*volume=*/1.0);
+  }
+
+  capturer_->ReleasePacket(std::move(packet));
+}
+
+void AudioInputStreamFuchsia::ReportError() {
+  capturer_.Unbind();
+  if (callback_)
+    callback_->OnError();
 }
 
 }  // namespace media
diff --git a/media/audio/fuchsia/audio_input_stream_fuchsia.h b/media/audio/fuchsia/audio_input_stream_fuchsia.h
index d47a46e..23024d37 100644
--- a/media/audio/fuchsia/audio_input_stream_fuchsia.h
+++ b/media/audio/fuchsia/audio_input_stream_fuchsia.h
@@ -5,20 +5,24 @@
 #ifndef MEDIA_AUDIO_FUCHSIA_AUDIO_INPUT_STREAM_FUCHSIA_H_
 #define MEDIA_AUDIO_FUCHSIA_AUDIO_INPUT_STREAM_FUCHSIA_H_
 
+#include <fuchsia/media/cpp/fidl.h>
+
 #include "media/audio/audio_io.h"
 #include "media/base/audio_parameters.h"
-#include "media/fuchsia/audio/fuchsia_audio_capturer_source.h"
+#include "media/base/media_export.h"
+#include "media/fuchsia/common/vmo_buffer.h"
 
 namespace media {
 
 class AudioManagerFuchsia;
 
-class AudioInputStreamFuchsia : public AudioInputStream {
+class MEDIA_EXPORT AudioInputStreamFuchsia : public AudioInputStream {
  public:
   // Caller must ensure that manager outlives the stream.
   AudioInputStreamFuchsia(AudioManagerFuchsia* manager,
                           const AudioParameters& parameters,
                           std::string device_id);
+  ~AudioInputStreamFuchsia() override;
 
   OpenOutcome Open() override;
   void Start(AudioInputCallback* callback) override;
@@ -33,17 +37,28 @@
   void SetOutputDeviceForAec(const std::string& output_device_id) override;
 
  private:
-  class CaptureCallbackAdapter;
+  // OnPacketProduced event handler for the |capturer_|.
+  void OnPacketProduced(fuchsia::media::StreamPacket packet);
 
-  ~AudioInputStreamFuchsia() override;
+  // Reports an error to |callback_| and disconnects |capturer_|.
+  void ReportError();
 
   AudioManagerFuchsia* const manager_;
   AudioParameters parameters_;
   std::string device_id_;
-  std::unique_ptr<CaptureCallbackAdapter> callback_adapter_;
-  scoped_refptr<FuchsiaAudioCapturerSource> capturer_source_;
-  double volume_ = 1.0;
-  bool automatic_gain_control_ = false;
+
+  fuchsia::media::AudioCapturerPtr capturer_;
+
+  // VMO with the AudioCapturer in order to pass the captured data.
+  VmoBuffer capture_buffer_;
+
+  // Indicates that async capture mode has been activated for |capturer_|, i.e.
+  // StartAsyncCapture() has been called.
+  bool is_capturer_started_ = false;
+
+  std::unique_ptr<AudioBus> audio_bus_;
+
+  AudioInputCallback* callback_ = nullptr;
 };
 
 }  // namespace media
diff --git a/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc b/media/audio/fuchsia/audio_input_stream_fuchsia_test.cc
similarity index 66%
rename from media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc
rename to media/audio/fuchsia/audio_input_stream_fuchsia_test.cc
index 4b413b9..5d55209 100644
--- a/media/fuchsia/audio/fuchsia_audio_capturer_source_test.cc
+++ b/media/audio/fuchsia/audio_input_stream_fuchsia_test.cc
@@ -1,15 +1,16 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2022 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "media/fuchsia/audio/fuchsia_audio_capturer_source.h"
+#include "media/audio/fuchsia/audio_input_stream_fuchsia.h"
 
 #include <fuchsia/media/cpp/fidl_test_base.h>
 #include <lib/fidl/cpp/binding.h>
 
 #include "base/fuchsia/fuchsia_logging.h"
+#include "base/fuchsia/test_component_context_for_process.h"
 #include "base/test/task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "media/audio/audio_device_description.h"
 #include "media/base/channel_layout.h"
 #include "media/fuchsia/audio/fake_audio_capturer.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -20,7 +21,7 @@
 
 constexpr size_t kFramesPerPacket = 480;
 
-class TestCaptureCallback final : public AudioCapturerSource::CaptureCallback {
+class TestCaptureCallback final : public AudioInputStream::AudioInputCallback {
  public:
   TestCaptureCallback() = default;
   ~TestCaptureCallback() override = default;
@@ -28,7 +29,6 @@
   TestCaptureCallback(const TestCaptureCallback&) = delete;
   TestCaptureCallback& operator=(const TestCaptureCallback&) = delete;
 
-  bool is_started() const { return is_started_; }
   bool have_error() const { return have_error_; }
 
   const std::vector<std::unique_ptr<AudioBus>>& packets() const {
@@ -36,67 +36,67 @@
   }
 
   // AudioCapturerSource::CaptureCallback implementation.
-  void OnCaptureStarted() override { is_started_ = true; }
-
-  void Capture(const AudioBus* audio_source,
-               base::TimeTicks audio_capture_time,
-               double volume,
-               bool key_pressed) override {
-    EXPECT_TRUE(is_started_);
-    auto bus =
-        AudioBus::Create(audio_source->channels(), audio_source->frames());
-    audio_source->CopyTo(bus.get());
+  void OnData(const AudioBus* source,
+              base::TimeTicks capture_time,
+              double volume) override {
+    auto bus = AudioBus::Create(source->channels(), source->frames());
+    source->CopyTo(bus.get());
     packets_.push_back(std::move(bus));
   }
 
-  void OnCaptureError(AudioCapturerSource::ErrorCode code,
-                      const std::string& message) override {
+  void OnError() override {
     EXPECT_FALSE(have_error_);
     have_error_ = true;
   }
 
-  void OnCaptureMuted(bool is_muted) override { FAIL(); }
-
-  void OnCaptureProcessorCreated(AudioProcessorControls* controls) override {
-    FAIL();
-  }
-
  private:
   std::vector<std::unique_ptr<AudioBus>> packets_;
-  bool is_started_ = false;
   bool have_error_ = false;
 };
 
 }  // namespace
 
-class FuchsiaAudioCapturerSourceTest : public testing::Test {
+class AudioInputStreamFuchsiaTest : public testing::Test {
  public:
-  FuchsiaAudioCapturerSourceTest() {
-    fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer_handle;
-    test_capturer_ = std::make_unique<FakeAudioCapturer>(
-        capturer_handle.NewRequest(),
-        FakeAudioCapturer::DataGeneration::MANUAL);
-    capturer_source_ = base::MakeRefCounted<FuchsiaAudioCapturerSource>(
-        std::move(capturer_handle), base::ThreadTaskRunnerHandle::Get());
-  }
+  AudioInputStreamFuchsiaTest() {}
 
-  ~FuchsiaAudioCapturerSourceTest() override {
-    capturer_source_->Stop();
-    capturer_source_ = nullptr;
+  ~AudioInputStreamFuchsiaTest() override {
+    if (input_stream_) {
+      input_stream_->Stop();
+      input_stream_.reset();
+    }
 
     base::RunLoop().RunUntilIdle();
   }
 
   void InitializeCapturer(ChannelLayout layout) {
-    capturer_source_->Initialize(
+    base::TestComponentContextForProcess test_context;
+    FakeAudioCapturerFactory audio_capturer_factory(
+        test_context.additional_services());
+
+    input_stream_ = std::make_unique<AudioInputStreamFuchsia>(
+        /*manager=*/nullptr,
         AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, layout,
                         /*sample_rate=*/48000, kFramesPerPacket),
-        &callback_);
+        AudioDeviceDescription::kDefaultDeviceId);
+
+    AudioInputStream::OpenOutcome result = input_stream_->Open();
+    EXPECT_EQ(result, AudioInputStream::OpenOutcome::kSuccess);
+
+    base::RunLoop().RunUntilIdle();
+
+    test_capturer_ = audio_capturer_factory.TakeCapturer();
+    ASSERT_TRUE(test_capturer_);
+    test_capturer_->SetDataGeneration(
+        FakeAudioCapturer::DataGeneration::MANUAL);
+
+    // Verify no other capturers were created.
+    ASSERT_FALSE(audio_capturer_factory.TakeCapturer());
   }
 
   void TestCapture(ChannelLayout layout) {
     InitializeCapturer(layout);
-    capturer_source_->Start();
+    input_stream_->Start(&callback_);
     base::RunLoop().RunUntilIdle();
 
     size_t num_channels = ChannelLayoutToChannelCount(layout);
@@ -127,37 +127,36 @@
 
   std::unique_ptr<FakeAudioCapturer> test_capturer_;
   TestCaptureCallback callback_;
-  scoped_refptr<FuchsiaAudioCapturerSource> capturer_source_;
+  std::unique_ptr<AudioInputStreamFuchsia> input_stream_;
 };
 
-TEST_F(FuchsiaAudioCapturerSourceTest, CreateAndDestroy) {}
+TEST_F(AudioInputStreamFuchsiaTest, CreateAndDestroy) {}
 
-TEST_F(FuchsiaAudioCapturerSourceTest, InitializeAndDestroy) {
+TEST_F(AudioInputStreamFuchsiaTest, InitializeAndDestroy) {
   InitializeCapturer(CHANNEL_LAYOUT_MONO);
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, InitializeAndStart) {
+TEST_F(AudioInputStreamFuchsiaTest, InitializeAndStart) {
   const auto kLayout = CHANNEL_LAYOUT_MONO;
   const auto kNumChannels = ChannelLayoutToChannelCount(kLayout);
 
   InitializeCapturer(kLayout);
-  capturer_source_->Start();
+  input_stream_->Start(&callback_);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(test_capturer_->is_active());
   EXPECT_EQ(test_capturer_->GetPacketSize(),
             sizeof(float) * kFramesPerPacket * kNumChannels);
 
-  EXPECT_TRUE(callback_.is_started());
   EXPECT_TRUE(callback_.packets().empty());
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, InitializeStereo) {
+TEST_F(AudioInputStreamFuchsiaTest, InitializeStereo) {
   const auto kLayout = CHANNEL_LAYOUT_STEREO;
   const auto kNumChannels = ChannelLayoutToChannelCount(kLayout);
 
   InitializeCapturer(kLayout);
-  capturer_source_->Start();
+  input_stream_->Start(&callback_);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(test_capturer_->is_active());
@@ -165,28 +164,28 @@
             sizeof(float) * kNumChannels * kFramesPerPacket);
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, StartAndStop) {
+TEST_F(AudioInputStreamFuchsiaTest, StartAndStop) {
   InitializeCapturer(CHANNEL_LAYOUT_MONO);
-  capturer_source_->Start();
+  input_stream_->Start(&callback_);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_TRUE(test_capturer_->is_active());
 
-  capturer_source_->Stop();
+  input_stream_->Stop();
   base::RunLoop().RunUntilIdle();
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, CaptureMono) {
+TEST_F(AudioInputStreamFuchsiaTest, CaptureMono) {
   TestCapture(CHANNEL_LAYOUT_MONO);
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, CaptureStereo) {
+TEST_F(AudioInputStreamFuchsiaTest, CaptureStereo) {
   TestCapture(CHANNEL_LAYOUT_STEREO);
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, CaptureTwoPackets) {
+TEST_F(AudioInputStreamFuchsiaTest, CaptureTwoPackets) {
   InitializeCapturer(CHANNEL_LAYOUT_MONO);
-  capturer_source_->Start();
+  input_stream_->Start(&callback_);
   base::RunLoop().RunUntilIdle();
 
   // Produce two packets.
@@ -214,11 +213,11 @@
   }
 }
 
-TEST_F(FuchsiaAudioCapturerSourceTest, CaptureAfterStop) {
+TEST_F(AudioInputStreamFuchsiaTest, CaptureAfterStop) {
   InitializeCapturer(CHANNEL_LAYOUT_MONO);
-  capturer_source_->Start();
+  input_stream_->Start(&callback_);
   base::RunLoop().RunUntilIdle();
-  capturer_source_->Stop();
+  input_stream_->Stop();
 
   std::vector<float> samples(kFramesPerPacket);
   base::TimeTicks ts = base::TimeTicks::FromZxTime(100);
diff --git a/media/cast/net/rtp/rtp_packetizer.cc b/media/cast/net/rtp/rtp_packetizer.cc
index f477841..40e3263d 100644
--- a/media/cast/net/rtp/rtp_packetizer.cc
+++ b/media/cast/net/rtp/rtp_packetizer.cc
@@ -8,15 +8,39 @@
 
 #include "base/big_endian.h"
 #include "base/check_op.h"
+#include "base/logging.h"
 #include "media/cast/net/pacing/paced_sender.h"
 #include "media/cast/net/rtp/rtp_defines.h"
 
 namespace media {
 namespace cast {
 
+namespace {
+
+// IP headers are 20 bytes, and ICMP headers are 8 bytes.
+constexpr uint16_t kIpAndIcmpHeadersLength = 28;
+
+// We may add an additional header to the first packet to update the playout
+// delay.
+constexpr uint16_t kPlayoutDelayHeaderLength = 4;
+
+// We always include the playout delay in our header length. This does result
+// in *slightly* suboptimal behavior in some edge cases, as we have a slightly
+// lower maximum packet size.
+constexpr uint16_t kHeadersLength =
+    kRtpHeaderLength + kCastHeaderLength + kPlayoutDelayHeaderLength;
+
+// The default max payload size is the maximum transmission unit
+// |kMaxIpPacketSize| minus all of the lower level headers (IP and ICMP
+// specifically).
+constexpr uint16_t kDefaultMaxPayloadLength =
+    kMaxIpPacketSize - kIpAndIcmpHeadersLength;
+
+}  // namespace
+
 RtpPacketizerConfig::RtpPacketizerConfig()
     : payload_type(-1),
-      max_payload_length(kMaxIpPacketSize - 28),  // Default is IP-v4/UDP.
+      max_payload_length(kDefaultMaxPayloadLength),
       sequence_number(0),
       ssrc(0) {}
 
@@ -42,13 +66,16 @@
 }
 
 void RtpPacketizer::SendFrameAsPackets(const EncodedFrame& frame) {
-  uint16_t rtp_header_length = kRtpHeaderLength + kCastHeaderLength;
-  uint16_t max_length = config_.max_payload_length - rtp_header_length - 1;
+  // We don't packetize empty packets.
+  if (frame.data.empty())
+    return;
 
+  const uint16_t max_length = config_.max_payload_length - kHeadersLength;
   // Split the payload evenly (round number up).
-  size_t num_packets = (frame.data.size() + max_length) / max_length;
-  size_t payload_length = (frame.data.size() + num_packets) / num_packets;
-  DCHECK_LE(payload_length, max_length) << "Invalid argument";
+  size_t num_packets = (frame.data.size() + max_length - 1) / max_length;
+  DCHECK_LE(num_packets, std::numeric_limits<uint16_t>::max());
+  size_t payload_length = (frame.data.size() + num_packets - 1) / num_packets;
+  DCHECK_LE(payload_length, max_length);
 
   SendPacketVector packets;
 
@@ -67,11 +94,10 @@
       payload_length = remaining_size;
     }
     remaining_size -= payload_length;
-    BuildCommonRTPheader(
-        &packet->data, remaining_size == 0, frame.rtp_timestamp);
+    BuildCommonRtpHeader(&packet->data, remaining_size == 0,
+                         frame.rtp_timestamp);
 
     // Build Cast header.
-    // TODO(miu): Should we always set the ref frame bit and the ref_frame_id?
     DCHECK_NE(frame.dependency, EncodedFrame::UNKNOWN_DEPENDENCY);
     uint8_t byte0 = kCastReferenceFrameIdBitMask;
     if (frame.dependency == EncodedFrame::KEY)
@@ -89,7 +115,8 @@
     big_endian_writer.WriteU16(packet_id);
     big_endian_writer.WriteU16(static_cast<uint16_t>(num_packets - 1));
     packet->data.push_back(frame.referenced_frame_id.lower_8_bits());
-    // Add extension details only on the first packet of the frame
+
+    // Add extension details only on the first packet of the frame.
     if (packet_id == 0 && frame.new_playout_delay_ms) {
       packet->data.push_back(kCastRtpExtensionAdaptiveLatency << 2);
       packet->data.push_back(2);  // 2 bytes
@@ -97,6 +124,7 @@
           static_cast<uint8_t>(frame.new_playout_delay_ms >> 8));
       packet->data.push_back(static_cast<uint8_t>(frame.new_playout_delay_ms));
     }
+    DCHECK_LE(packet->data.size(), kHeadersLength);
 
     // Copy payload data.
     packet->data.insert(packet->data.end(),
@@ -104,6 +132,10 @@
                         data_iter + payload_length);
     data_iter += payload_length;
 
+    // If packets are too large, meaning that the payload size plus all headers
+    // is larger than the MTU size of the network, this packet will get
+    // fragmented.
+    DCHECK(packet->data.size() <= config_.max_payload_length);
     packets.push_back(make_pair(PacketKey(frame.reference_time, config_.ssrc,
                                           frame.frame_id, packet_id),
                                 packet));
@@ -112,7 +144,7 @@
     ++send_packet_count_;
     send_octet_count_ += payload_length;
   }
-  DCHECK_EQ(num_packets, packets.size()) << "Invalid state";
+  DCHECK_EQ(num_packets, packets.size());
 
   packet_storage_->StoreFrame(frame.frame_id, packets);
 
@@ -120,13 +152,13 @@
   transport_->SendPackets(packets);
 }
 
-void RtpPacketizer::BuildCommonRTPheader(Packet* packet,
+void RtpPacketizer::BuildCommonRtpHeader(Packet* packet,
                                          bool marker_bit,
                                          RtpTimeTicks rtp_timestamp) {
   packet->push_back(0x80);
   packet->push_back(static_cast<uint8_t>(config_.payload_type) |
                     (marker_bit ? kRtpMarkerBitMask : 0));
-  size_t start_size = packet->size();
+  const size_t start_size = packet->size();
   packet->resize(start_size + 10);
   base::BigEndianWriter big_endian_writer(
       reinterpret_cast<char*>(&((*packet)[start_size])), 10);
diff --git a/media/cast/net/rtp/rtp_packetizer.h b/media/cast/net/rtp/rtp_packetizer.h
index 8d7d3b8..4480aee 100644
--- a/media/cast/net/rtp/rtp_packetizer.h
+++ b/media/cast/net/rtp/rtp_packetizer.h
@@ -52,7 +52,7 @@
   size_t send_octet_count() const { return send_octet_count_; }
 
  private:
-  void BuildCommonRTPheader(Packet* packet,
+  void BuildCommonRtpHeader(Packet* packet,
                             bool marker_bit,
                             RtpTimeTicks rtp_timestamp);
 
diff --git a/media/cast/net/rtp/rtp_packetizer_unittest.cc b/media/cast/net/rtp/rtp_packetizer_unittest.cc
index eee2a83..89a0bf1 100644
--- a/media/cast/net/rtp/rtp_packetizer_unittest.cc
+++ b/media/cast/net/rtp/rtp_packetizer_unittest.cc
@@ -20,12 +20,25 @@
 namespace cast {
 
 namespace {
-static const int kPayload = 127;
-static const uint32_t kTimestampMs = 10;
-static const uint16_t kSeqNum = 33;
-static const int kMaxPacketLength = 1500;
-static const int kSsrc = 0x12345;
-static const unsigned int kFrameSize = 5000;
+
+constexpr int kPayload = 127;
+constexpr uint32_t kTimestampMs = 10;
+constexpr uint16_t kSeqNum = 33;
+constexpr int kSsrc = 0x12345;
+constexpr unsigned int kFrameSize = 5000;
+
+// The maximum packet length is the internet MTU (1500) minus the IP and ICMP
+// header size.
+constexpr int kMaxPacketLength = 1472;
+
+// The maximum payload size is the maximum packet size (set using the internet
+// standard MTU of 1500) minus the size of all layers' headers combined.
+constexpr int kMaxPayloadSize = 1449;
+
+// Allows for enough time to execute packets for a video frame of size
+// |kFrameSize|.
+static int kTaskExecutionMilliseconds = 34;
+
 }  // namespace
 
 class TestRtpPacketTransport : public PacketTransport {
@@ -134,14 +147,23 @@
     video_frame_.rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(0x0055aa11));
   }
 
-  void RunTasks(int during_ms) {
-    for (int i = 0; i < during_ms; ++i) {
+  void RunTasks() {
+    for (int i = 0; i < kTaskExecutionMilliseconds; ++i) {
       // Call process the timers every 1 ms.
       testing_clock_.Advance(base::Milliseconds(1));
       task_runner_->RunTasks();
     }
   }
 
+  // Sends |video_frame_| to the |rtp_packetizer_|.
+  void SendFrame() {
+    transport_->set_rtp_timestamp(video_frame_.rtp_timestamp);
+    testing_clock_.Advance(base::Milliseconds(kTimestampMs));
+    video_frame_.reference_time = testing_clock_.NowTicks();
+    rtp_packetizer_->SendFrameAsPackets(video_frame_);
+    RunTasks();
+  }
+
   base::SimpleTestTickClock testing_clock_;
   scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
   EncodedFrame video_frame_;
@@ -155,43 +177,56 @@
 TEST_F(RtpPacketizerTest, SendStandardPackets) {
   size_t expected_num_of_packets = kFrameSize / kMaxPacketLength + 1;
   transport_->set_expected_number_of_packets(expected_num_of_packets);
-  transport_->set_rtp_timestamp(video_frame_.rtp_timestamp);
-
-  testing_clock_.Advance(base::Milliseconds(kTimestampMs));
-  video_frame_.reference_time = testing_clock_.NowTicks();
-  rtp_packetizer_->SendFrameAsPackets(video_frame_);
-  RunTasks(33 + 1);
+  SendFrame();
   EXPECT_EQ(expected_num_of_packets, transport_->number_of_packets_received());
 }
 
+TEST_F(RtpPacketizerTest, SendEmptyPacket) {
+  video_frame_.data.clear();
+  transport_->set_expected_number_of_packets(0);
+  SendFrame();
+  EXPECT_EQ(0u, transport_->number_of_packets_received());
+}
+
+TEST_F(RtpPacketizerTest, SendPacketOfMaximumSize) {
+  video_frame_.data.assign(kMaxPayloadSize, 88);
+  transport_->set_expected_number_of_packets(1);
+  SendFrame();
+  EXPECT_EQ(1u, transport_->number_of_packets_received());
+}
+
+TEST_F(RtpPacketizerTest, SendPacketJustAboveMaximumSize) {
+  video_frame_.data.assign(kMaxPayloadSize + 1, 88);
+  transport_->set_expected_number_of_packets(2);
+  SendFrame();
+  EXPECT_EQ(2u, transport_->number_of_packets_received());
+}
+
+TEST_F(RtpPacketizerTest, SendPacketExactMultipleOfMaximumSize) {
+  video_frame_.data.assign(kMaxPayloadSize * 3, 88);
+  transport_->set_expected_number_of_packets(3);
+  SendFrame();
+  EXPECT_EQ(3u, transport_->number_of_packets_received());
+}
+
 TEST_F(RtpPacketizerTest, SendPacketsWithAdaptivePlayoutExtension) {
   size_t expected_num_of_packets = kFrameSize / kMaxPacketLength + 1;
   transport_->set_expected_number_of_packets(expected_num_of_packets);
-  transport_->set_rtp_timestamp(video_frame_.rtp_timestamp);
-
-  testing_clock_.Advance(base::Milliseconds(kTimestampMs));
-  video_frame_.reference_time = testing_clock_.NowTicks();
   video_frame_.new_playout_delay_ms = 500;
-  rtp_packetizer_->SendFrameAsPackets(video_frame_);
-  RunTasks(33 + 1);
+  SendFrame();
   EXPECT_EQ(expected_num_of_packets, transport_->number_of_packets_received());
 }
 
 TEST_F(RtpPacketizerTest, Stats) {
   EXPECT_FALSE(rtp_packetizer_->send_packet_count());
   EXPECT_FALSE(rtp_packetizer_->send_octet_count());
-  // Insert packets at varying lengths.
-  size_t expected_num_of_packets = kFrameSize / kMaxPacketLength + 1;
-  transport_->set_expected_number_of_packets(expected_num_of_packets);
-  transport_->set_rtp_timestamp(video_frame_.rtp_timestamp);
+  constexpr size_t kExpectedNumOfPackets = kFrameSize / kMaxPacketLength + 1;
+  transport_->set_expected_number_of_packets(kExpectedNumOfPackets);
+  SendFrame();
 
-  testing_clock_.Advance(base::Milliseconds(kTimestampMs));
-  video_frame_.reference_time = testing_clock_.NowTicks();
-  rtp_packetizer_->SendFrameAsPackets(video_frame_);
-  RunTasks(33 + 1);
-  EXPECT_EQ(expected_num_of_packets, rtp_packetizer_->send_packet_count());
+  EXPECT_EQ(kExpectedNumOfPackets, rtp_packetizer_->send_packet_count());
   EXPECT_EQ(kFrameSize, rtp_packetizer_->send_octet_count());
-  EXPECT_EQ(expected_num_of_packets, transport_->number_of_packets_received());
+  EXPECT_EQ(kExpectedNumOfPackets, transport_->number_of_packets_received());
 }
 
 }  // namespace cast
diff --git a/media/fuchsia/audio/BUILD.gn b/media/fuchsia/audio/BUILD.gn
index cba7667..0d3fcaa6 100644
--- a/media/fuchsia/audio/BUILD.gn
+++ b/media/fuchsia/audio/BUILD.gn
@@ -18,8 +18,6 @@
   configs += [ "//media:subcomponent_config" ]
 
   sources = [
-    "fuchsia_audio_capturer_source.cc",
-    "fuchsia_audio_capturer_source.h",
     "fuchsia_audio_output_device.cc",
     "fuchsia_audio_output_device.h",
   ]
@@ -27,6 +25,7 @@
 
 source_set("test_support") {
   testonly = true
+  deps = [ "//testing/gtest" ]
   public_deps = [
     "//base",
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media",
@@ -55,8 +54,5 @@
     "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media.audio",
   ]
 
-  sources = [
-    "fuchsia_audio_capturer_source_test.cc",
-    "fuchsia_audio_output_device_test.cc",
-  ]
+  sources = [ "fuchsia_audio_output_device_test.cc" ]
 }
diff --git a/media/fuchsia/audio/fake_audio_capturer.cc b/media/fuchsia/audio/fake_audio_capturer.cc
index 8621c14..e73b169e 100644
--- a/media/fuchsia/audio/fake_audio_capturer.cc
+++ b/media/fuchsia/audio/fake_audio_capturer.cc
@@ -11,30 +11,43 @@
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
 
 FakeAudioCapturer::FakeAudioCapturer(
-    fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request,
-    DataGeneration data_generation)
-    : data_generation_(data_generation), binding_(this, std::move(request)) {}
+    fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request)
+    : binding_(this) {
+  if (request)
+    Bind(std::move(request));
+}
 
 FakeAudioCapturer::~FakeAudioCapturer() = default;
 
+void FakeAudioCapturer::Bind(
+    fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request) {
+  binding_.Bind(std::move(request));
+}
+
 size_t FakeAudioCapturer::GetPacketSize() const {
   return frames_per_packet_ * stream_type_->channels * sizeof(float);
 }
 
+void FakeAudioCapturer::SetDataGeneration(DataGeneration data_generation) {
+  EXPECT_TRUE(!is_active());
+  data_generation_ = data_generation;
+}
+
 void FakeAudioCapturer::SendData(base::TimeTicks timestamp, void* data) {
-  CHECK(buffer_vmo_);
-  CHECK(is_active_);
+  EXPECT_TRUE(buffer_vmo_);
+  EXPECT_TRUE(is_active_);
 
   // Find unused packet.
   auto it = std::find(packets_usage_.begin(), packets_usage_.end(), false);
 
   // Currently tests don't try to send more than 2 packets and the buffer
   // always will have space for at least 2 packets.
-  CHECK(it != packets_usage_.end());
+  EXPECT_TRUE(it != packets_usage_.end());
 
   size_t buffer_index = it - packets_usage_.begin();
   size_t buffer_pos = buffer_index * GetPacketSize();
@@ -57,16 +70,17 @@
 // fuchsia::media::AudioCapturer implementation.
 void FakeAudioCapturer::SetPcmStreamType(
     fuchsia::media::AudioStreamType stream_type) {
-  CHECK(!stream_type_.has_value());
-  CHECK_EQ(stream_type.sample_format, fuchsia::media::AudioSampleFormat::FLOAT);
+  EXPECT_TRUE(!stream_type_.has_value());
+  EXPECT_EQ(stream_type.sample_format,
+            fuchsia::media::AudioSampleFormat::FLOAT);
 
   stream_type_ = std::move(stream_type);
 }
 
 void FakeAudioCapturer::AddPayloadBuffer(uint32_t id, zx::vmo payload_buffer) {
-  CHECK_EQ(id, kBufferId);
-  CHECK(!buffer_vmo_);
-  CHECK(stream_type_.has_value());
+  EXPECT_EQ(id, kBufferId);
+  EXPECT_TRUE(!buffer_vmo_);
+  EXPECT_TRUE(stream_type_.has_value());
 
   buffer_vmo_ = std::move(payload_buffer);
   zx_status_t status = buffer_vmo_.get_size(&buffer_size_);
@@ -74,16 +88,16 @@
 }
 
 void FakeAudioCapturer::StartAsyncCapture(uint32_t frames_per_packet) {
-  CHECK(buffer_vmo_);
-  CHECK(!is_active_);
+  EXPECT_TRUE(buffer_vmo_);
+  EXPECT_TRUE(!is_active_);
 
   is_active_ = true;
   frames_per_packet_ = frames_per_packet;
   size_t num_packets = buffer_size_ / GetPacketSize();
 
   // AudioCapturer protocol requires that we can fit at least 2 packets in the
-  // buffer in async mode.
-  CHECK_GE(num_packets, 2U);
+  // buffer in async data_generation.
+  EXPECT_GE(num_packets, 2U);
 
   packets_usage_.clear();
   packets_usage_.resize(num_packets, false);
@@ -94,18 +108,22 @@
   }
 }
 
+void FakeAudioCapturer::StopAsyncCaptureNoReply() {
+  is_active_ = false;
+  timer_.Stop();
+}
+
 void FakeAudioCapturer::ReleasePacket(fuchsia::media::StreamPacket packet) {
-  CHECK_EQ(packet.payload_buffer_id, kBufferId);
-  CHECK_EQ(packet.payload_offset % GetPacketSize(), 0U);
+  EXPECT_EQ(packet.payload_buffer_id, kBufferId);
+  EXPECT_EQ(packet.payload_offset % GetPacketSize(), 0U);
   size_t buffer_index = packet.payload_offset / GetPacketSize();
-  CHECK_LT(buffer_index, packets_usage_.size());
-  CHECK(packets_usage_[buffer_index]);
+  EXPECT_LT(buffer_index, packets_usage_.size());
+  EXPECT_TRUE(packets_usage_[buffer_index]);
   packets_usage_[buffer_index] = false;
 }
 
-// No other methods are expected to be called.
 void FakeAudioCapturer::NotImplemented_(const std::string& name) {
-  NOTREACHED();
+  ADD_FAILURE() << "Unexpected FakeAudioCapturer call: " << name;
 }
 
 void FakeAudioCapturer::ProducePackets() {
@@ -127,4 +145,29 @@
                this, &FakeAudioCapturer::ProducePackets);
 }
 
+FakeAudioCapturerFactory::FakeAudioCapturerFactory(
+    sys::OutgoingDirectory* outgoing_directory)
+    : binding_(outgoing_directory, this) {}
+
+FakeAudioCapturerFactory::~FakeAudioCapturerFactory() = default;
+
+std::unique_ptr<FakeAudioCapturer> FakeAudioCapturerFactory::TakeCapturer() {
+  if (capturers_.empty())
+    return nullptr;
+  auto result = std::move(capturers_.front());
+  capturers_.pop_front();
+  return result;
+}
+
+void FakeAudioCapturerFactory::CreateAudioCapturer(
+    fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request,
+    bool loopback) {
+  capturers_.push_back(std::make_unique<FakeAudioCapturer>());
+  capturers_.back()->Bind(std::move(request));
+}
+
+void FakeAudioCapturerFactory::NotImplemented_(const std::string& name) {
+  ADD_FAILURE() << "Unexpected FakeAudioCapturerFactory call: " << name;
+}
+
 }  // namespace media
diff --git a/media/fuchsia/audio/fake_audio_capturer.h b/media/fuchsia/audio/fake_audio_capturer.h
index baf72133..004943b3 100644
--- a/media/fuchsia/audio/fake_audio_capturer.h
+++ b/media/fuchsia/audio/fake_audio_capturer.h
@@ -8,8 +8,10 @@
 #include <fuchsia/media/cpp/fidl_test_base.h>
 #include <lib/fidl/cpp/binding.h>
 
+#include <list>
 #include <vector>
 
+#include "base/fuchsia/scoped_service_binding.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
@@ -33,18 +35,21 @@
   static constexpr uint32_t kBufferId = 0;
 
   explicit FakeAudioCapturer(
-      fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request,
-      DataGeneration data_generation = DataGeneration::AUTOMATIC);
+      fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request = {});
   ~FakeAudioCapturer() override;
 
   FakeAudioCapturer(const FakeAudioCapturer&) = delete;
   FakeAudioCapturer& operator=(const FakeAudioCapturer&) = delete;
 
+  void Bind(fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request);
+
   bool is_active() const { return is_active_; }
 
   // Size of a single packet in bytes.
   size_t GetPacketSize() const;
 
+  void SetDataGeneration(DataGeneration data_generation);
+
   // Send the given data to the client. |data| length must be |GetPacketSize()|.
   void SendData(base::TimeTicks timestamp, void* data);
 
@@ -52,6 +57,7 @@
   void SetPcmStreamType(fuchsia::media::AudioStreamType stream_type) override;
   void AddPayloadBuffer(uint32_t id, zx::vmo payload_buffer) override;
   void StartAsyncCapture(uint32_t frames_per_packet) override;
+  void StopAsyncCaptureNoReply() override;
   void ReleasePacket(fuchsia::media::StreamPacket packet) override;
 
   // No other methods are expected to be called.
@@ -60,7 +66,7 @@
  private:
   void ProducePackets();
 
-  DataGeneration data_generation_;
+  DataGeneration data_generation_ = DataGeneration::AUTOMATIC;
   fidl::Binding<fuchsia::media::AudioCapturer> binding_;
 
   zx::vmo buffer_vmo_;
@@ -75,6 +81,29 @@
   base::OneShotTimer timer_;
 };
 
+class FakeAudioCapturerFactory final
+    : public fuchsia::media::testing::Audio_TestBase {
+ public:
+  explicit FakeAudioCapturerFactory(sys::OutgoingDirectory* outgoing_directory);
+  ~FakeAudioCapturerFactory() override;
+
+  // Returns a capturer created by this class. Returns |nullptr| if there are no
+  // new instances.
+  std::unique_ptr<FakeAudioCapturer> TakeCapturer();
+
+  // fuchsia::media::Audio overrides.
+  void CreateAudioCapturer(
+      fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request,
+      bool loopback) override;
+
+  // No other methods are expected to be called.
+  void NotImplemented_(const std::string& name) override;
+
+ private:
+  base::ScopedServiceBinding<fuchsia::media::Audio> binding_;
+  std::list<std::unique_ptr<FakeAudioCapturer>> capturers_;
+};
+
 }  // namespace media
 
 #endif  // MEDIA_FUCHSIA_AUDIO_FAKE_AUDIO_CAPTURER_H_
diff --git a/media/fuchsia/audio/fuchsia_audio_capturer_source.cc b/media/fuchsia/audio/fuchsia_audio_capturer_source.cc
deleted file mode 100644
index 480bc867..0000000
--- a/media/fuchsia/audio/fuchsia_audio_capturer_source.cc
+++ /dev/null
@@ -1,267 +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.
-
-#include "media/fuchsia/audio/fuchsia_audio_capturer_source.h"
-
-#include <lib/zx/vmar.h>
-#include <lib/zx/vmo.h>
-
-#include "base/bind.h"
-#include "base/bits.h"
-#include "base/cxx17_backports.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/koid.h"
-#include "base/location.h"
-#include "base/task/task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "media/base/audio_parameters.h"
-
-namespace media {
-
-namespace {
-
-// Currently AudioCapturer supports only one payload buffer with id=0.
-constexpr uint32_t kBufferId = 0;
-
-// Number of audio packets that should fit in the capture buffer.
-constexpr size_t kBufferPacketCapacity = 10;
-
-}  // namespace
-
-FuchsiaAudioCapturerSource::FuchsiaAudioCapturerSource(
-    fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer_handle,
-    scoped_refptr<base::SingleThreadTaskRunner> capturer_task_runner)
-    : capturer_handle_(std::move(capturer_handle)),
-      capturer_task_runner_(capturer_task_runner) {
-  DCHECK(capturer_handle_);
-}
-
-FuchsiaAudioCapturerSource::~FuchsiaAudioCapturerSource() {
-  DCHECK(!callback_)
-      << "Stop() must be called before FuchsiaAudioCapturerSource is released.";
-
-  if (capture_buffer_) {
-    zx_status_t status = zx::vmar::root_self()->unmap(
-        reinterpret_cast<uint64_t>(capture_buffer_), capture_buffer_size_);
-    ZX_DCHECK(status == ZX_OK, status) << "zx_vmar_unmap";
-  }
-}
-
-void FuchsiaAudioCapturerSource::Initialize(const AudioParameters& params,
-                                            CaptureCallback* callback) {
-  DCHECK(!capture_buffer_);
-  DCHECK(!callback_);
-  DCHECK(callback);
-
-  main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
-  params_ = params;
-  callback_ = callback;
-
-  if (params_.format() != AudioParameters::AUDIO_PCM_LOW_LATENCY) {
-    ReportError("Only AUDIO_PCM_LOW_LATENCY format is supported");
-    return;
-  }
-  capturer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FuchsiaAudioCapturerSource::InitializeOnCapturerThread,
-                     this));
-}
-
-void FuchsiaAudioCapturerSource::Start() {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-  DCHECK(callback_);
-
-  capturer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FuchsiaAudioCapturerSource::StartOnCapturerThread, this));
-}
-
-void FuchsiaAudioCapturerSource::Stop() {
-  // Nothing to do if Initialize() hasn't been called.
-  if (!main_task_runner_)
-    return;
-
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-
-  {
-    base::AutoLock lock(callback_lock_);
-
-    if (!callback_)
-      return;
-
-    callback_ = nullptr;
-  }
-
-  capturer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FuchsiaAudioCapturerSource::StopOnCapturerThread, this));
-}
-
-void FuchsiaAudioCapturerSource::SetVolume(double volume) {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-  NOTIMPLEMENTED();
-}
-
-void FuchsiaAudioCapturerSource::SetAutomaticGainControl(bool enable) {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-  NOTIMPLEMENTED();
-}
-
-void FuchsiaAudioCapturerSource::SetOutputDeviceForAec(
-    const std::string& output_device_id) {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-  NOTIMPLEMENTED();
-}
-
-void FuchsiaAudioCapturerSource::InitializeOnCapturerThread() {
-  DCHECK(capturer_task_runner_->BelongsToCurrentThread());
-
-  // Bind AudioCapturer.
-  capturer_.Bind(std::move(capturer_handle_));
-  capturer_.set_error_handler([this](zx_status_t status) {
-    ZX_LOG(ERROR, status) << "AudioCapturer disconnected";
-    ReportError("AudioCapturer disconnected");
-  });
-
-  // Bind the event for incoming packets.
-  capturer_.events().OnPacketProduced =
-      fit::bind_member(this, &FuchsiaAudioCapturerSource::OnPacketCaptured);
-
-  // TODO(crbug.com/1065207): Enable/disable stream processing based on
-  // |params.effects()| when support is added to fuchsia.media.AudioCapturer.
-
-  // Configure stream format.
-  fuchsia::media::AudioStreamType stream_type;
-  stream_type.sample_format = fuchsia::media::AudioSampleFormat::FLOAT;
-  stream_type.channels = params_.channels();
-  stream_type.frames_per_second = params_.sample_rate();
-  capturer_->SetPcmStreamType(std::move(stream_type));
-
-  // Allocate shared buffer.
-  capture_buffer_size_ =
-      params_.GetBytesPerBuffer(kSampleFormatF32) * kBufferPacketCapacity;
-  capture_buffer_size_ =
-      base::bits::AlignUp(capture_buffer_size_, ZX_PAGE_SIZE);
-
-  zx::vmo buffer_vmo;
-  zx_status_t status = zx::vmo::create(capture_buffer_size_, 0, &buffer_vmo);
-  ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
-
-  constexpr char kName[] = "cr-audio-capturer";
-  status = buffer_vmo.set_property(ZX_PROP_NAME, kName, base::size(kName) - 1);
-  ZX_DCHECK(status == ZX_OK, status);
-
-  // Map the buffer.
-  uint64_t addr;
-  status = zx::vmar::root_self()->map(
-      ZX_VM_PERM_READ, /*vmar_offset=*/0, buffer_vmo, /*vmo_offset=*/0,
-      capture_buffer_size_, &addr);
-  if (status != ZX_OK) {
-    ZX_DLOG(ERROR, status) << "zx_vmar_map";
-    ReportError("Failed to map capture buffer");
-    return;
-  }
-  capture_buffer_ = reinterpret_cast<uint8_t*>(addr);
-
-  // Pass the buffer to the capturer.
-  capturer_->AddPayloadBuffer(kBufferId, std::move(buffer_vmo));
-}
-
-void FuchsiaAudioCapturerSource::StartOnCapturerThread() {
-  DCHECK(capturer_task_runner_->BelongsToCurrentThread());
-
-  // Errors are reported asynchronously, so Start() may be called after an error
-  // has occurred.
-  if (!capturer_)
-    return;
-
-  if (!is_capturer_started_) {
-    is_capturer_started_ = true;
-    capturer_->StartAsyncCapture(params_.frames_per_buffer());
-  }
-
-  main_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(&FuchsiaAudioCapturerSource::NotifyCaptureStarted, this));
-}
-
-void FuchsiaAudioCapturerSource::StopOnCapturerThread() {
-  DCHECK(capturer_task_runner_->BelongsToCurrentThread());
-  capturer_.Unbind();
-}
-
-void FuchsiaAudioCapturerSource::NotifyCaptureError(
-    const std::string& message) {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-
-  // Nothing to do if Stop() was called.
-  if (!callback_)
-    return;
-
-  // `Stop()` cannot be called on other threads, so `callback_lock_` doesn't
-  // need to be held.
-  callback_->OnCaptureError(AudioCapturerSource::ErrorCode::kUnknown, message);
-}
-
-void FuchsiaAudioCapturerSource::NotifyCaptureStarted() {
-  DCHECK(main_task_runner_->BelongsToCurrentThread());
-
-  // Nothing to do if Stop() was called.
-  if (!callback_)
-    return;
-
-  // `Stop()` cannot be called on other threads, so `callback_lock_` doesn't
-  // need to be held.
-  callback_->OnCaptureStarted();
-}
-
-void FuchsiaAudioCapturerSource::OnPacketCaptured(
-    fuchsia::media::StreamPacket packet) {
-  DCHECK(capturer_task_runner_->BelongsToCurrentThread());
-
-  size_t bytes_per_frame = params_.GetBytesPerFrame(kSampleFormatF32);
-
-  if (packet.payload_buffer_id != kBufferId ||
-      packet.payload_offset + packet.payload_size > capture_buffer_size_ ||
-      packet.payload_size % bytes_per_frame != 0 ||
-      packet.payload_size < bytes_per_frame) {
-    ReportError("AudioCapturer produced invalid packet");
-    return;
-  }
-
-  // Keep the lock when calling `Capture()` to ensure that we don't call the
-  // callback after `Stop()`. If `Stop()` is called on the main thread while the
-  // lock is held it will wait until we release the lock below. This is
-  // acceptable because `CaptureCallback::Capture()` is expected to return
-  // quickly.
-  base::AutoLock lock(callback_lock_);
-
-  // If `Stop()` was called then we can drop the capturer - it won't be used
-  // again.
-  if (!callback_)
-    capturer_.Unbind();
-
-  size_t num_frames = packet.payload_size / bytes_per_frame;
-  auto audio_bus = AudioBus::Create(params_.channels(), num_frames);
-  audio_bus->FromInterleaved<Float32SampleTypeTraits>(
-      reinterpret_cast<const float*>(capture_buffer_ + packet.payload_offset),
-      num_frames);
-  callback_->Capture(audio_bus.get(), base::TimeTicks::FromZxTime(packet.pts),
-                     /*volume=*/1.0,
-                     /*key_pressed=*/false);
-
-  capturer_->ReleasePacket(std::move(packet));
-}
-
-void FuchsiaAudioCapturerSource::ReportError(const std::string& message) {
-  DCHECK(capturer_task_runner_->BelongsToCurrentThread());
-
-  capturer_.Unbind();
-
-  main_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&FuchsiaAudioCapturerSource::NotifyCaptureError,
-                                this, message));
-}
-
-}  // namespace media
diff --git a/media/fuchsia/audio/fuchsia_audio_capturer_source.h b/media/fuchsia/audio/fuchsia_audio_capturer_source.h
deleted file mode 100644
index ca3cdfa..0000000
--- a/media/fuchsia/audio/fuchsia_audio_capturer_source.h
+++ /dev/null
@@ -1,85 +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 MEDIA_FUCHSIA_AUDIO_FUCHSIA_AUDIO_CAPTURER_SOURCE_H_
-#define MEDIA_FUCHSIA_AUDIO_FUCHSIA_AUDIO_CAPTURER_SOURCE_H_
-
-#include <fuchsia/media/cpp/fidl.h>
-
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "media/base/audio_capturer_source.h"
-#include "media/base/media_export.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}  // namespace base
-
-namespace media {
-
-class MEDIA_EXPORT FuchsiaAudioCapturerSource final
-    : public AudioCapturerSource {
- public:
-  FuchsiaAudioCapturerSource(
-      fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer_handle,
-      scoped_refptr<base::SingleThreadTaskRunner> capturer_task_runner);
-
-  FuchsiaAudioCapturerSource(const FuchsiaAudioCapturerSource&) = delete;
-  FuchsiaAudioCapturerSource& operator=(const FuchsiaAudioCapturerSource&) =
-      delete;
-
-  // AudioCaptureSource implementation.
-  void Initialize(const AudioParameters& params,
-                  CaptureCallback* callback) override;
-  void Start() override;
-  void Stop() override;
-  void SetVolume(double volume) override;
-  void SetAutomaticGainControl(bool enable) override;
-  void SetOutputDeviceForAec(const std::string& output_device_id) override;
-
- private:
-  ~FuchsiaAudioCapturerSource() override;
-
-  void InitializeOnCapturerThread();
-  void StartOnCapturerThread();
-  void StopOnCapturerThread();
-  void NotifyCaptureError(const std::string& error);
-  void NotifyCaptureStarted();
-  void OnPacketCaptured(fuchsia::media::StreamPacket packet);
-  void ReportError(const std::string& message);
-
-  // AudioCapturer handle before it's bound to |capturer_| in Initialize().
-  // Normally FuchsiaAudioCapturerSource is created on a thread different from
-  // the main thread on which it is used, so |capturer_| cannot be initialized
-  // in the constructor.
-  fidl::InterfaceHandle<fuchsia::media::AudioCapturer> capturer_handle_;
-
-  // Task runner for the thread that's used for the |capturer_|.
-  scoped_refptr<base::SingleThreadTaskRunner> capturer_task_runner_;
-
-  // Main thread on which the object was initialized.
-  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-
-  fuchsia::media::AudioCapturerPtr capturer_;
-
-  AudioParameters params_;
-  CaptureCallback* callback_ = nullptr;
-
-  // `callback_lock_` is used to synchronize `Stop()` called on the main thread
-  // and `CaptureCallback::Capture()` called on the capturer thread. All other
-  // `CaptureCallback` methods are called on the main thread.
-  base::Lock callback_lock_;
-
-  // Shared VMO mapped to the current address space.
-  uint8_t* capture_buffer_ = nullptr;
-  size_t capture_buffer_size_ = 0;
-
-  // Indicates that async capture mode has been activated for |capturer_|, i.e.
-  // StartAsyncCapture() has been called.
-  bool is_capturer_started_ = false;
-};
-
-}  // namespace media
-
-#endif  // MEDIA_FUCHSIA_AUDIO_FUCHSIA_AUDIO_CAPTURER_SOURCE_H_
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index e5ca25b..898afbaf 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -162,13 +162,9 @@
 
 V4L2VideoEncodeAccelerator::InputFrameInfo::~InputFrameInfo() = default;
 
-// static
-base::AtomicRefCount V4L2VideoEncodeAccelerator::num_instances_(0);
-
 V4L2VideoEncodeAccelerator::V4L2VideoEncodeAccelerator(
     scoped_refptr<V4L2Device> device)
-    : can_use_encoder_(num_instances_.Increment() < kMaxNumOfInstances),
-      child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+    : child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       native_input_mode_(false),
       output_buffer_byte_size_(0),
       output_format_fourcc_(0),
@@ -196,8 +192,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
   DCHECK(!device_poll_thread_.IsRunning());
   VLOGF(2);
-
-  num_instances_.Decrement();
 }
 
 bool V4L2VideoEncodeAccelerator::Initialize(const Config& config,
@@ -208,11 +202,6 @@
   TRACE_EVENT0("media,gpu", "V4L2VEA::Initialize");
   VLOGF(2) << ": " << config.AsHumanReadableString();
 
-  if (!can_use_encoder_) {
-    VLOGF(1) << "Too many encoders are allocated";
-    return false;
-  }
-
   // V4L2VEA doesn't support temporal layers but we let it pass here to support
   // simulcast.
   if (config.HasSpatialLayer()) {
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.h b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
index b51c4ab5..a8f0693 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.h
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.h
@@ -260,14 +260,6 @@
   // Initializes input_memory_type_.
   bool InitInputMemoryType(const Config& config);
 
-  // Having too many encoder instances at once may cause us to run out of FDs
-  // and subsequently crash (crbug.com/1289465). To avoid that, we limit the
-  // maximum number of encoder instances that can exist at once.
-  // |num_instances_| tracks that number.
-  static constexpr int kMaxNumOfInstances = 10;
-  static base::AtomicRefCount num_instances_;
-  const bool can_use_encoder_;
-
   // Our original calling task runner for the child thread and its checker.
   const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_;
   SEQUENCE_CHECKER(child_sequence_checker_);
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
index 7ebeecd..6aa8af8 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.cc
@@ -139,9 +139,6 @@
   const off_t offset;
 };
 
-// static
-base::AtomicRefCount VaapiVideoEncodeAccelerator::num_instances_(0);
-
 VideoEncodeAccelerator::SupportedProfiles
 VaapiVideoEncodeAccelerator::GetSupportedProfiles() {
   if (IsConfiguredForTesting())
@@ -150,8 +147,7 @@
 }
 
 VaapiVideoEncodeAccelerator::VaapiVideoEncodeAccelerator()
-    : can_use_encoder_(num_instances_.Increment() < kMaxNumOfInstances),
-      output_buffer_byte_size_(0),
+    : output_buffer_byte_size_(0),
       state_(kUninitialized),
       child_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       // TODO(akahuang): Change to use SequencedTaskRunner to see if the
@@ -177,11 +173,8 @@
 VaapiVideoEncodeAccelerator::~VaapiVideoEncodeAccelerator() {
   VLOGF(2);
   DCHECK_CALLED_ON_VALID_SEQUENCE(encoder_sequence_checker_);
-
   base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
       this);
-
-  num_instances_.Decrement();
 }
 
 bool VaapiVideoEncodeAccelerator::Initialize(const Config& config,
@@ -195,11 +188,6 @@
     return false;
   }
 
-  if (!can_use_encoder_) {
-    VLOGF(1) << "Too many encoders are allocated";
-    return false;
-  }
-
   client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client));
   client_ = client_ptr_factory_->GetWeakPtr();
 
diff --git a/media/gpu/vaapi/vaapi_video_encode_accelerator.h b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
index 5e846974a..6a5a827 100644
--- a/media/gpu/vaapi/vaapi_video_encode_accelerator.h
+++ b/media/gpu/vaapi/vaapi_video_encode_accelerator.h
@@ -212,14 +212,6 @@
     return !supported_profiles_for_testing_.empty();
   }
 
-  // Having too many encoder instances at once may cause us to run out of FDs
-  // and subsequently crash (crbug.com/1289465). To avoid that, we limit the
-  // maximum number of encoder instances that can exist at once.
-  // |num_instances_| tracks that number.
-  static constexpr int kMaxNumOfInstances = 10;
-  static base::AtomicRefCount num_instances_;
-  const bool can_use_encoder_;
-
   // The unchanged values are filled upon the construction. The varied values
   // are filled properly during encoding.
   VideoEncoderInfo encoder_info_;
diff --git a/mojo/public/cpp/bindings/clone_traits.h b/mojo/public/cpp/bindings/clone_traits.h
index 7b88192..7c3a70f 100644
--- a/mojo/public/cpp/bindings/clone_traits.h
+++ b/mojo/public/cpp/bindings/clone_traits.h
@@ -6,6 +6,7 @@
 #define MOJO_PUBLIC_CPP_BINDINGS_CLONE_TRAITS_H_
 
 #include <type_traits>
+#include <utility>
 #include <vector>
 
 #include "base/containers/flat_map.h"
@@ -14,36 +15,32 @@
 
 namespace mojo {
 
-template <typename T>
-struct HasCloneMethod {
-  template <typename U>
-  static char Test(decltype(&U::Clone));
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  internal::EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename SFINAE = void>
+struct HasCloneMethod : std ::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <typename T, bool has_clone_method = HasCloneMethod<T>::value>
-struct CloneTraits;
+template <typename T>
+struct HasCloneMethod<T,
+                      std::void_t<decltype(std::declval<const T&>().Clone())>>
+    : std::true_type {};
 
 template <typename T>
 T Clone(const T& input);
 
 template <typename T>
-struct CloneTraits<T, true> {
-  static T Clone(const T& input) { return input.Clone(); }
+struct CloneTraits {
+  static T Clone(const T& input) {
+    if constexpr (HasCloneMethod<T>::value) {
+      return input.Clone();
+    } else {
+      return input;
+    }
+  }
 };
 
 template <typename T>
-struct CloneTraits<T, false> {
-  static T Clone(const T& input) { return input; }
-};
-
-template <typename T>
-struct CloneTraits<absl::optional<T>, false> {
+struct CloneTraits<absl::optional<T>> {
   static absl::optional<T> Clone(const absl::optional<T>& input) {
     if (!input)
       return absl::nullopt;
@@ -53,7 +50,7 @@
 };
 
 template <typename T>
-struct CloneTraits<std::vector<T>, false> {
+struct CloneTraits<std::vector<T>> {
   static std::vector<T> Clone(const std::vector<T>& input) {
     std::vector<T> result;
     result.reserve(input.size());
@@ -65,7 +62,7 @@
 };
 
 template <typename K, typename V>
-struct CloneTraits<base::flat_map<K, V>, false> {
+struct CloneTraits<base::flat_map<K, V>> {
   static base::flat_map<K, V> Clone(const base::flat_map<K, V>& input) {
     base::flat_map<K, V> result;
     for (const auto& element : input) {
diff --git a/mojo/public/cpp/bindings/equals_traits.h b/mojo/public/cpp/bindings/equals_traits.h
index 8e958ce..fc130f01 100644
--- a/mojo/public/cpp/bindings/equals_traits.h
+++ b/mojo/public/cpp/bindings/equals_traits.h
@@ -6,6 +6,7 @@
 #define MOJO_PUBLIC_CPP_BINDINGS_EQUALS_TRAITS_H_
 
 #include <type_traits>
+#include <utility>
 #include <vector>
 
 #include "base/containers/flat_map.h"
@@ -18,36 +19,32 @@
 // objects. By default objects can be compared if they implement operator==()
 // or have a method named Equals().
 
-template <typename T>
-struct HasEqualsMethod {
-  template <typename U>
-  static char Test(decltype(&U::Equals));
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  internal::EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename SFINAE = void>
+struct HasEqualsMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <typename T, bool has_equals_method = HasEqualsMethod<T>::value>
-struct EqualsTraits;
+template <typename T>
+struct HasEqualsMethod<T,
+                       std::void_t<decltype(std::declval<const T&>().Equals(
+                           std::declval<const T&>()))>> : std::true_type {};
 
 template <typename T>
 bool Equals(const T& a, const T& b);
 
 template <typename T>
-struct EqualsTraits<T, true> {
-  static bool Equals(const T& a, const T& b) { return a.Equals(b); }
+struct EqualsTraits {
+  static bool Equals(const T& a, const T& b) {
+    if constexpr (HasEqualsMethod<T>::value) {
+      return a.Equals(b);
+    } else {
+      return a == b;
+    }
+  }
 };
 
 template <typename T>
-struct EqualsTraits<T, false> {
-  static bool Equals(const T& a, const T& b) { return a == b; }
-};
-
-template <typename T>
-struct EqualsTraits<absl::optional<T>, false> {
+struct EqualsTraits<absl::optional<T>> {
   static bool Equals(const absl::optional<T>& a, const absl::optional<T>& b) {
     if (!a && !b)
       return true;
@@ -61,7 +58,7 @@
 };
 
 template <typename T>
-struct EqualsTraits<std::vector<T>, false> {
+struct EqualsTraits<std::vector<T>> {
   static bool Equals(const std::vector<T>& a, const std::vector<T>& b) {
     if (a.size() != b.size())
       return false;
@@ -74,7 +71,7 @@
 };
 
 template <typename K, typename V>
-struct EqualsTraits<base::flat_map<K, V>, false> {
+struct EqualsTraits<base::flat_map<K, V>> {
   static bool Equals(const base::flat_map<K, V>& a,
                      const base::flat_map<K, V>& b) {
     if (a.size() != b.size())
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h
index a0966ec0..9a072f72 100644
--- a/mojo/public/cpp/bindings/lib/array_serialization.h
+++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -37,28 +37,22 @@
 template <typename Traits, typename MaybeConstUserType>
 class ArrayIterator<Traits, MaybeConstUserType, true> {
  public:
-  using IteratorType = decltype(
-      CallGetBeginIfExists<Traits>(std::declval<MaybeConstUserType&>()));
+  using IteratorType =
+      decltype(Traits::GetBegin(std::declval<MaybeConstUserType&>()));
 
   explicit ArrayIterator(MaybeConstUserType& input)
-      : input_(input), iter_(CallGetBeginIfExists<Traits>(input)) {}
+      : input_(input), iter_(Traits::GetBegin(input)) {}
   ~ArrayIterator() {}
 
   size_t GetSize() const { return Traits::GetSize(input_); }
 
-  using GetNextResult =
-      decltype(Traits::GetValue(std::declval<IteratorType&>()));
-  GetNextResult GetNext() {
-    GetNextResult value = Traits::GetValue(iter_);
+  decltype(auto) GetNext() {
+    decltype(auto) value = Traits::GetValue(iter_);
     Traits::AdvanceIterator(iter_);
     return value;
   }
 
-  using GetDataIfExistsResult = decltype(
-      CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
-  GetDataIfExistsResult GetDataIfExists() {
-    return CallGetDataIfExists<Traits>(input_);
-  }
+  const MaybeConstUserType& input() const { return input_; }
 
  private:
   MaybeConstUserType& input_;
@@ -74,18 +68,12 @@
 
   size_t GetSize() const { return Traits::GetSize(input_); }
 
-  using GetNextResult =
-      decltype(Traits::GetAt(std::declval<MaybeConstUserType&>(), 0));
-  GetNextResult GetNext() {
+  decltype(auto) GetNext() {
     DCHECK_LT(iter_, Traits::GetSize(input_));
     return Traits::GetAt(input_, iter_++);
   }
 
-  using GetDataIfExistsResult = decltype(
-      CallGetDataIfExists<Traits>(std::declval<MaybeConstUserType&>()));
-  GetDataIfExistsResult GetDataIfExists() {
-    return CallGetDataIfExists<Traits>(input_);
-  }
+  const MaybeConstUserType& input() const { return input_; }
 
  private:
   MaybeConstUserType& input_;
@@ -138,9 +126,9 @@
     if (size == 0)
       return;
 
-    auto data = input->GetDataIfExists();
     Data* output = fragment.data();
-    if (data) {
+    if constexpr (HasGetDataMethod<Traits, MaybeConstUserType>::value) {
+      auto data = Traits::GetData(input->input());
       memcpy(output->storage(), data, size * sizeof(DataElement));
     } else {
       for (size_t i = 0; i < size; ++i)
@@ -153,12 +141,12 @@
                                   Message* message) {
     if (!Traits::Resize(*output, input->size()))
       return false;
-    ArrayIterator<Traits, UserType> iterator(*output);
     if (input->size()) {
-      auto data = iterator.GetDataIfExists();
-      if (data) {
+      if constexpr (HasGetDataMethod<Traits, UserType>::value) {
+        auto data = Traits::GetData(*output);
         memcpy(data, input->storage(), input->size() * sizeof(DataElement));
       } else {
+        ArrayIterator<Traits, UserType> iterator(*output);
         for (size_t i = 0; i < input->size(); ++i)
           iterator.GetNext() = input->at(i);
       }
@@ -287,7 +275,7 @@
     Data* output = fragment.data();
     size_t size = input->GetSize();
     for (size_t i = 0; i < size; ++i) {
-      typename UserTypeIterator::GetNextResult next = input->GetNext();
+      decltype(auto) next = input->GetNext();
       Serialize<Element>(next, &output->at(i), &fragment.message());
 
       static const ValidationError kError =
@@ -346,7 +334,7 @@
     size_t size = input->GetSize();
     for (size_t i = 0; i < size; ++i) {
       MessageFragment<ElementData> data_fragment(fragment.message());
-      typename UserTypeIterator::GetNextResult next = input->GetNext();
+      decltype(auto) next = input->GetNext();
       SerializeCaller<Element>::Run(next, data_fragment,
                                     validate_params->element_validate_params);
       fragment->at(i).Set(data_fragment.is_null() ? nullptr
@@ -422,7 +410,7 @@
     for (size_t i = 0; i < size; ++i) {
       MessageFragment<DataElement> inlined_union_element(fragment.message());
       inlined_union_element.Claim(fragment->storage() + i);
-      typename UserTypeIterator::GetNextResult next = input->GetNext();
+      decltype(auto) next = input->GetNext();
       Serialize<Element>(next, inlined_union_element, true);
       MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
           !validate_params->element_is_nullable &&
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h
index ce0d3be..26bc05a 100644
--- a/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -169,20 +169,14 @@
   return temp;
 }
 
+template <typename T, typename SFINAE = void>
+struct IsUnionDataType : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
+};
+
 template <typename T>
-struct IsUnionDataType {
- private:
-  template <typename U>
-  static YesType Test(const typename U::MojomUnionDataType*);
-
-  template <typename U>
-  static NoType Test(...);
-
-  EnsureTypeIsComplete<T> check_t_;
-
- public:
-  static const bool value =
-      sizeof(Test<T>(0)) == sizeof(YesType) && !IsConst<T>::value;
+struct IsUnionDataType<T, typename T::MojomUnionDataType> {
+  static const bool value = !std::is_const_v<T>;
 };
 
 enum class MojomTypeCategory : uint32_t {
diff --git a/mojo/public/cpp/bindings/lib/hash_util.h b/mojo/public/cpp/bindings/lib/hash_util.h
index db0c541..b9c3953 100644
--- a/mojo/public/cpp/bindings/lib/hash_util.h
+++ b/mojo/public/cpp/bindings/lib/hash_util.h
@@ -23,18 +23,16 @@
   return seed ^ (std::hash<T>()(value) + (seed << 6) + (seed >> 2));
 }
 
-template <typename T>
-struct HasHashMethod {
-  template <typename U>
-  static char Test(decltype(&U::Hash));
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename SFINAE = void>
+struct HasHashMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
+template <typename T>
+struct HasHashMethod<T,
+                     std::void_t<decltype(std::declval<T>().Hash(size_t{0}))>>
+    : std::true_type {};
+
 template <typename T, bool has_hash_method = HasHashMethod<T>::value>
 struct HashTraits;
 
diff --git a/mojo/public/cpp/bindings/lib/serialization_util.h b/mojo/public/cpp/bindings/lib/serialization_util.h
index d4e34ec6..4384f4c 100644
--- a/mojo/public/cpp/bindings/lib/serialization_util.h
+++ b/mojo/public/cpp/bindings/lib/serialization_util.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <type_traits>
+#include <utility>
 
 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
 #include "mojo/public/cpp/bindings/lib/serialization_forward.h"
@@ -16,59 +17,45 @@
 namespace mojo {
 namespace internal {
 
-template <typename T>
-struct HasIsNullMethod {
-  template <typename U>
-  static char Test(decltype(U::IsNull) *);
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename U, typename SFINAE = void>
+struct HasIsNullMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <
-    typename Traits,
-    typename UserType,
-    typename std::enable_if<HasIsNullMethod<Traits>::value>::type* = nullptr>
+template <typename T, typename U>
+struct HasIsNullMethod<
+    T,
+    U,
+    std::void_t<decltype(T::IsNull(std::declval<const U&>()))>>
+    : std::true_type {};
+
+template <typename Traits, typename UserType>
 bool CallIsNullIfExists(const UserType& input) {
-  return Traits::IsNull(input);
+  if constexpr (HasIsNullMethod<Traits, UserType>::value) {
+    return Traits::IsNull(input);
+  } else {
+    return false;
+  }
 }
 
-template <
-    typename Traits,
-    typename UserType,
-    typename std::enable_if<!HasIsNullMethod<Traits>::value>::type* = nullptr>
-bool CallIsNullIfExists(const UserType& input) {
-  return false;
-}
-template <typename T>
-struct HasSetToNullMethod {
-  template <typename U>
-  static char Test(decltype(U::SetToNull) *);
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename U, typename SFINAE = void>
+struct HasSetToNullMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <
-    typename Traits,
-    typename UserType,
-    typename std::enable_if<HasSetToNullMethod<Traits>::value>::type* = nullptr>
-bool CallSetToNullIfExists(UserType* output) {
-  Traits::SetToNull(output);
-  return true;
-}
+template <typename T, typename U>
+struct HasSetToNullMethod<
+    T,
+    U,
+    std::void_t<decltype(T::SetToNull(std::declval<U*>()))>> : std::true_type {
+};
 
-template <typename Traits,
-          typename UserType,
-          typename std::enable_if<!HasSetToNullMethod<Traits>::value>::type* =
-              nullptr>
+template <typename Traits, typename UserType>
 bool CallSetToNullIfExists(UserType* output) {
+  if constexpr (HasSetToNullMethod<Traits, UserType>::value) {
+    Traits::SetToNull(output);
+  }
+
   // Note that it is not considered an error to attempt to read a null value
   // into a non-nullable `output` object. In such cases, the caller must have
   // used a DataView's corresponding MaybeRead[FieldName] method, thus
@@ -109,85 +96,39 @@
   using Traits = MapTraits<UserType>;
 };
 
-template <typename MojomType,
-          typename UserType,
-          typename std::enable_if<IsOptionalWrapper<UserType>::value>::type* =
-              nullptr>
+template <typename MojomType, typename UserType>
 constexpr bool IsValidUserTypeForOptionalValue() {
-  return true;
+  if constexpr (IsOptionalWrapper<UserType>::value) {
+    return true;
+  } else {
+    using Traits = typename TraitsFinder<MojomType, UserType>::Traits;
+    return HasSetToNullMethod<Traits, UserType>::value;
+  }
 }
 
-template <typename MojomType,
-          typename UserType,
-          typename std::enable_if<!IsOptionalWrapper<UserType>::value>::type* =
-              nullptr>
-constexpr bool IsValidUserTypeForOptionalValue() {
-  using Traits = typename TraitsFinder<MojomType, UserType>::Traits;
-  return HasSetToNullMethod<Traits>::value;
-}
-
-template <typename T, typename MaybeConstUserType>
-struct HasGetBeginMethod {
-  template <typename U>
-  static char Test(
-      decltype(U::GetBegin(std::declval<MaybeConstUserType&>())) *);
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename U, typename SFINAE = void>
+struct HasGetBeginMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <
-    typename Traits,
-    typename MaybeConstUserType,
-    typename std::enable_if<
-        HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
-decltype(Traits::GetBegin(std::declval<MaybeConstUserType&>()))
-CallGetBeginIfExists(MaybeConstUserType& input) {
-  return Traits::GetBegin(input);
-}
+template <typename T, typename U>
+struct HasGetBeginMethod<T,
+                         U,
+                         std::void_t<decltype(T::GetBegin(std::declval<U&>()))>>
+    : std::true_type {};
 
-template <
-    typename Traits,
-    typename MaybeConstUserType,
-    typename std::enable_if<
-        !HasGetBeginMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
-size_t CallGetBeginIfExists(MaybeConstUserType& input) {
-  return 0;
-}
-
-template <typename T, typename MaybeConstUserType>
-struct HasGetDataMethod {
-  template <typename U>
-  static char Test(decltype(U::GetData(std::declval<MaybeConstUserType&>())) *);
-  template <typename U>
-  static int Test(...);
-  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
-  EnsureTypeIsComplete<T> check_t_;
+template <typename T, typename U, typename SFINAE = void>
+struct HasGetDataMethod : std::false_type {
+  static_assert(sizeof(T), "T must be a complete type.");
 };
 
-template <
-    typename Traits,
-    typename MaybeConstUserType,
-    typename std::enable_if<
-        HasGetDataMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
-decltype(Traits::GetData(std::declval<MaybeConstUserType&>()))
-CallGetDataIfExists(MaybeConstUserType& input) {
-  return Traits::GetData(input);
-}
-
-template <
-    typename Traits,
-    typename MaybeConstUserType,
-    typename std::enable_if<
-        !HasGetDataMethod<Traits, MaybeConstUserType>::value>::type* = nullptr>
-void* CallGetDataIfExists(MaybeConstUserType& input) {
-  return nullptr;
-}
+// TODO(dcheng): Figure out why the `&` below is load-bearing and document it or
+// improve this and remove the hack.
+template <typename T, typename U>
+struct HasGetDataMethod<T,
+                        U,
+                        std::void_t<decltype(&T::GetData(std::declval<U&>()))>>
+    : std::true_type {};
 
 }  // namespace internal
 }  // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/template_util.h b/mojo/public/cpp/bindings/lib/template_util.h
index 383eb91..c22f6bf 100644
--- a/mojo/public/cpp/bindings/lib/template_util.h
+++ b/mojo/public/cpp/bindings/lib/template_util.h
@@ -10,109 +10,20 @@
 namespace mojo {
 namespace internal {
 
-template <class T, T v>
-struct IntegralConstant {
-  static const T value = v;
-};
-
-template <class T, T v>
-const T IntegralConstant<T, v>::value;
-
-typedef IntegralConstant<bool, true> TrueType;
-typedef IntegralConstant<bool, false> FalseType;
-
-template <class T>
-struct IsConst : FalseType {};
-template <class T>
-struct IsConst<const T> : TrueType {};
-
-template <class T>
-struct IsPointer : FalseType {};
-template <class T>
-struct IsPointer<T*> : TrueType {};
-
-template <bool B, typename T = void>
-struct EnableIf {};
-
-template <typename T>
-struct EnableIf<true, T> {
-  typedef T type;
-};
-
-// Types YesType and NoType are guaranteed such that sizeof(YesType) <
-// sizeof(NoType).
-typedef char YesType;
-
-struct NoType {
-  YesType dummy[2];
-};
-
 // A helper template to determine if given type is non-const move-only-type,
 // i.e. if a value of the given type should be passed via std::move() in a
 // destructive way.
 template <typename T>
 struct IsMoveOnlyType {
-  static const bool value = std::is_constructible<T, T&&>::value &&
-                            !std::is_constructible<T, const T&>::value;
-};
-
-// This goop is a trick used to implement a template that can be used to
-// determine if a given class is the base class of another given class.
-template <typename, typename>
-struct IsSame {
-  static bool const value = false;
-};
-template <typename A>
-struct IsSame<A, A> {
-  static bool const value = true;
-};
-
-template <typename T>
-struct EnsureTypeIsComplete {
-  // sizeof() cannot be applied to incomplete types, this line will fail
-  // compilation if T is forward declaration.
-  using CheckSize = char (*)[sizeof(T)];
-};
-
-template <typename Base, typename Derived>
-struct IsBaseOf {
- private:
-  static Derived* CreateDerived();
-  static char(&Check(Base*))[1];
-  static char(&Check(...))[2];
-
-  EnsureTypeIsComplete<Base> check_base_;
-  EnsureTypeIsComplete<Derived> check_derived_;
-
- public:
-  static bool const value = sizeof Check(CreateDerived()) == 1 &&
-                            !IsSame<Base const, void const>::value;
-};
-
-template <class T>
-struct RemovePointer {
-  typedef T type;
-};
-template <class T>
-struct RemovePointer<T*> {
-  typedef T type;
+  static const bool value =
+      std::is_constructible_v<T, T&&> && !std::is_constructible_v<T, const T&>;
 };
 
 template <template <typename...> class Template, typename T>
-struct IsSpecializationOf : FalseType {};
+struct IsSpecializationOf : std::false_type {};
 
 template <template <typename...> class Template, typename... Args>
-struct IsSpecializationOf<Template, Template<Args...>> : TrueType {};
-
-template <bool B, typename T, typename F>
-struct Conditional {
-  typedef T type;
-};
-
-template <typename T, typename F>
-struct Conditional<false, T, F> {
-  typedef F type;
-};
+struct IsSpecializationOf<Template, Template<Args...>> : std::true_type {};
 
 template <typename T>
 struct AlwaysFalse {
diff --git a/mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h b/mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h
index 8882eec..6a5b3753 100644
--- a/mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h
+++ b/mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h
@@ -16,7 +16,7 @@
 namespace mojo {
 
 template <typename T>
-struct CloneTraits<WTF::Vector<T>, false> {
+struct CloneTraits<WTF::Vector<T>> {
   static WTF::Vector<T> Clone(const WTF::Vector<T>& input) {
     WTF::Vector<T> result;
     result.ReserveCapacity(input.size());
@@ -28,7 +28,7 @@
 };
 
 template <typename K, typename V>
-struct CloneTraits<WTF::HashMap<K, V>, false> {
+struct CloneTraits<WTF::HashMap<K, V>> {
   static WTF::HashMap<K, V> Clone(const WTF::HashMap<K, V>& input) {
     WTF::HashMap<K, V> result;
     for (const auto& element : input)
@@ -39,7 +39,7 @@
 };
 
 template <typename T>
-struct EqualsTraits<WTF::Vector<T>, false> {
+struct EqualsTraits<WTF::Vector<T>> {
   static bool Equals(const WTF::Vector<T>& a, const WTF::Vector<T>& b) {
     if (a.size() != b.size())
       return false;
@@ -52,7 +52,7 @@
 };
 
 template <typename K, typename V>
-struct EqualsTraits<WTF::HashMap<K, V>, false> {
+struct EqualsTraits<WTF::HashMap<K, V>> {
   static bool Equals(const WTF::HashMap<K, V>& a, const WTF::HashMap<K, V>& b) {
     if (a.size() != b.size())
       return false;
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc
index b009fa6..37153bf 100644
--- a/net/http/bidirectional_stream.cc
+++ b/net/http/bidirectional_stream.cc
@@ -237,7 +237,7 @@
 void BidirectionalStream::OnHeadersReceived(
     const spdy::Http2HeaderBlock& response_headers) {
   HttpResponseInfo response_info;
-  if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) {
+  if (SpdyHeadersToHttpResponse(response_headers, &response_info) != OK) {
     DLOG(WARNING) << "Invalid headers";
     NotifyFailed(ERR_FAILED);
     return;
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index aaa22ac..0637a502b 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -52,24 +52,6 @@
   return cr_separated_headers;
 }
 
-// Return true if |headers| contain multiple |field_name| fields with different
-// values.
-bool HeadersContainMultipleCopiesOfField(const HttpResponseHeaders& headers,
-                                         const std::string& field_name) {
-  size_t it = 0;
-  std::string field_value;
-  if (!headers.EnumerateHeader(&it, field_name, &field_value))
-    return false;
-  // There's at least one |field_name| header.  Check if there are any more
-  // such headers, and if so, return true if they have different values.
-  std::string field_value2;
-  while (headers.EnumerateHeader(&it, field_name, &field_value2)) {
-    if (field_value != field_value2)
-      return true;
-  }
-  return false;
-}
-
 base::Value NetLogSendRequestBodyParams(uint64_t length,
                                         bool is_chunked,
                                         bool did_merge) {
@@ -1049,15 +1031,17 @@
   // chunked-encoded.  If they exist, and have distinct values, it's a potential
   // response smuggling attack.
   if (!headers->IsChunkEncoded()) {
-    if (HeadersContainMultipleCopiesOfField(*headers, "Content-Length"))
+    if (HttpUtil::HeadersContainMultipleCopiesOfField(*headers,
+                                                      "Content-Length"))
       return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH;
   }
 
   // Check for multiple Content-Disposition or Location headers.  If they exist,
   // it's also a potential response smuggling attack.
-  if (HeadersContainMultipleCopiesOfField(*headers, "Content-Disposition"))
+  if (HttpUtil::HeadersContainMultipleCopiesOfField(*headers,
+                                                    "Content-Disposition"))
     return ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION;
-  if (HeadersContainMultipleCopiesOfField(*headers, "Location"))
+  if (HttpUtil::HeadersContainMultipleCopiesOfField(*headers, "Location"))
     return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION;
 
   response_->headers = headers;
diff --git a/net/http/http_util.cc b/net/http/http_util.cc
index 32948a3b..0978147 100644
--- a/net/http/http_util.cc
+++ b/net/http/http_util.cc
@@ -23,6 +23,7 @@
 #include "net/base/mime_util.h"
 #include "net/base/parse_number.h"
 #include "net/base/url_util.h"
+#include "net/http/http_response_headers.h"
 
 namespace net {
 
@@ -1122,4 +1123,21 @@
   return true;
 }
 
+bool HttpUtil::HeadersContainMultipleCopiesOfField(
+    const HttpResponseHeaders& headers,
+    const std::string& field_name) {
+  size_t it = 0;
+  std::string field_value;
+  if (!headers.EnumerateHeader(&it, field_name, &field_value))
+    return false;
+  // There's at least one `field_name` header.  Check if there are any more
+  // such headers, and if so, return true if they have different values.
+  std::string field_value2;
+  while (headers.EnumerateHeader(&it, field_name, &field_value2)) {
+    if (field_value != field_value2)
+      return true;
+  }
+  return false;
+}
+
 }  // namespace net
diff --git a/net/http/http_util.h b/net/http/http_util.h
index 7494ae8..65f64279 100644
--- a/net/http/http_util.h
+++ b/net/http/http_util.h
@@ -29,6 +29,8 @@
 
 namespace net {
 
+class HttpResponseHeaders;
+
 class NET_EXPORT HttpUtil {
  public:
   // Returns the absolute URL, to be used for the http request. This url is
@@ -260,6 +262,12 @@
   static bool ParseContentEncoding(const std::string& content_encoding,
                                    std::set<std::string>* used_encodings);
 
+  // Return true if `headers` contain multiple `field_name` fields with
+  // different values.
+  static bool HeadersContainMultipleCopiesOfField(
+      const HttpResponseHeaders& headers,
+      const std::string& field_name);
+
   // Used to iterate over the name/value pairs of HTTP headers.  To iterate
   // over the values in a multi-value header, use ValuesIterator.
   // See AssembleRawHeaders for joining line continuations (this iterator
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 3d5ff481..670683986 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -600,7 +600,8 @@
                                          &client_request_info.extra_headers);
 
   HttpResponseInfo promise_response_info;
-  if (!SpdyHeadersToHttpResponse(promise_response, &promise_response_info)) {
+  if (SpdyHeadersToHttpResponse(promise_response, &promise_response_info) !=
+      OK) {
     DLOG(WARNING) << "Invalid headers";
     return false;
   }
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc
index 50175ac..dbb4ab4d 100644
--- a/net/quic/quic_http_stream.cc
+++ b/net/quic/quic_http_stream.cc
@@ -700,10 +700,10 @@
 
 int QuicHttpStream::ProcessResponseHeaders(
     const spdy::Http2HeaderBlock& headers) {
-  const bool header_valid = SpdyHeadersToHttpResponse(headers, response_info_);
+  const bool rv = SpdyHeadersToHttpResponse(headers, response_info_);
   base::UmaHistogramBoolean("Net.QuicHttpStream.ProcessResponseHeaderSuccess",
-                            header_valid);
-  if (!header_valid) {
+                            rv == OK);
+  if (rv != OK) {
     DLOG(WARNING) << "Invalid headers";
     return ERR_QUIC_PROTOCOL_ERROR;
   }
diff --git a/net/quic/quic_proxy_client_socket.cc b/net/quic/quic_proxy_client_socket.cc
index 274b867..44e1abe 100644
--- a/net/quic/quic_proxy_client_socket.cc
+++ b/net/quic/quic_proxy_client_socket.cc
@@ -450,7 +450,7 @@
 
 int QuicProxyClientSocket::ProcessResponseHeaders(
     const spdy::Http2HeaderBlock& headers) {
-  if (!SpdyHeadersToHttpResponse(headers, &response_)) {
+  if (SpdyHeadersToHttpResponse(headers, &response_) != OK) {
     DLOG(WARNING) << "Invalid headers";
     return ERR_QUIC_PROTOCOL_ERROR;
   }
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index 32a6c2c1..d5e1749 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -396,8 +396,8 @@
   DCHECK(response_info_);
   DCHECK_EQ(stream_->type(), SPDY_REQUEST_RESPONSE_STREAM);
 
-  const bool headers_valid = SpdyHeadersToHttpResponse(headers, response_info_);
-  CHECK(headers_valid);
+  const int rv = SpdyHeadersToHttpResponse(headers, response_info_);
+  CHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
 
   if (!response_callback_.is_null()) {
     DoResponseCallback(OK);
@@ -416,15 +416,21 @@
     response_info_ = push_response_info_.get();
   }
 
-  const bool headers_valid =
-      SpdyHeadersToHttpResponse(response_headers, response_info_);
-  DCHECK(headers_valid);
+  const int rv = SpdyHeadersToHttpResponse(response_headers, response_info_);
+  DCHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
+
+  if (rv == ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION) {
+    // Cancel will call OnClose, which might call callbacks and might destroy
+    // `this`.
+    stream_->Cancel(rv);
+    return;
+  }
 
   if (pushed_request_headers &&
       !ValidatePushedHeaders(*request_info_, *pushed_request_headers,
                              response_headers, *response_info_)) {
     // Cancel will call OnClose, which might call callbacks and might destroy
-    // |this|.
+    // `this`.
     stream_->Cancel(ERR_HTTP2_PUSHED_RESPONSE_DOES_NOT_MATCH);
 
     return;
diff --git a/net/spdy/spdy_http_utils.cc b/net/spdy/spdy_http_utils.cc
index 3592f9ec..cc55ea3 100644
--- a/net/spdy/spdy_http_utils.cc
+++ b/net/spdy/spdy_http_utils.cc
@@ -41,14 +41,15 @@
 
 }  // namespace
 
-bool SpdyHeadersToHttpResponse(const spdy::Http2HeaderBlock& headers,
-                               HttpResponseInfo* response) {
+int SpdyHeadersToHttpResponse(const spdy::Http2HeaderBlock& headers,
+                              HttpResponseInfo* response) {
   // The ":status" header is required.
   spdy::Http2HeaderBlock::const_iterator it =
       headers.find(spdy::kHttp2StatusHeader);
   if (it == headers.end())
-    return false;
-  auto status = std::string(it->second);
+    return ERR_INCOMPLETE_HTTP2_HEADERS;
+
+  std::string status(it->second);
   std::string raw_headers("HTTP/1.1 ");
   raw_headers.append(status);
   raw_headers.push_back('\0');
@@ -88,8 +89,16 @@
   }
 
   response->headers = new HttpResponseHeaders(raw_headers);
+
+  // When there are multiple location headers the response is a potential
+  // response smuggling attack.
+  if (HttpUtil::HeadersContainMultipleCopiesOfField(*response->headers,
+                                                    "location")) {
+    return ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION;
+  }
+
   response->was_fetched_via_spdy = true;
-  return true;
+  return OK;
 }
 
 void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
diff --git a/net/spdy/spdy_http_utils.h b/net/spdy/spdy_http_utils.h
index d2319e17..ecf3995e 100644
--- a/net/spdy/spdy_http_utils.h
+++ b/net/spdy/spdy_http_utils.h
@@ -18,13 +18,14 @@
 struct HttpRequestInfo;
 class HttpRequestHeaders;
 
-// Convert a spdy::Http2HeaderBlock into an HttpResponseInfo.
-// |headers| input parameter with the spdy::Http2HeaderBlock.
-// |response| output parameter for the HttpResponseInfo.
-// Returns true if successfully converted.  False if the spdy::Http2HeaderBlock
-// is incomplete (e.g. missing 'status' or 'version').
-NET_EXPORT bool SpdyHeadersToHttpResponse(const spdy::Http2HeaderBlock& headers,
-                                          HttpResponseInfo* response);
+// Convert a spdy::Http2HeaderBlock into an HttpResponseInfo with some checks.
+// `headers` input parameter with the spdy::Http2HeaderBlock.
+// `response` output parameter for the HttpResponseInfo.
+// Returns OK if successfully converted.  An error is returned if the
+// spdy::Http2HeaderBlock is incomplete (e.g. missing 'status' or 'version') or
+// checks fail.
+NET_EXPORT int SpdyHeadersToHttpResponse(const spdy::Http2HeaderBlock& headers,
+                                         HttpResponseInfo* response);
 
 // Create a spdy::Http2HeaderBlock from HttpRequestInfo and HttpRequestHeaders.
 NET_EXPORT void CreateSpdyHeadersFromHttpRequest(
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index c15f4b72..59afe0c 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -2618,6 +2618,39 @@
   EXPECT_TRUE(data1.AllWriteDataConsumed());
 }
 
+TEST_F(SpdyNetworkTransactionTest, RedirectMultipleLocations) {
+  const spdy::SpdyStreamId kStreamId = 1;
+  // Construct the request and the RST frame.
+  spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyGet(
+      /*extra_headers=*/nullptr, /*extra_header_count=*/0, kStreamId, LOWEST));
+  spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
+      kStreamId, spdy::ERROR_CODE_PROTOCOL_ERROR));
+  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 4)};
+
+  // Construct the response.
+  const char* const kExtraResponseHeaders[] = {
+      "location",
+      "https://example1.test",
+      "location",
+      "https://example2.test",
+  };
+  spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
+      "301", kExtraResponseHeaders, base::size(kExtraResponseHeaders) / 2,
+      kStreamId));
+  spdy::SpdySerializedFrame body(
+      spdy_util_.ConstructSpdyDataFrame(kStreamId, /*fin=*/true));
+  MockRead reads[] = {
+      CreateMockRead(resp, 1), CreateMockRead(body, 2),
+      MockRead(ASYNC, 0, 3)  // EOF
+  };
+
+  SequencedSocketData data(reads, writes);
+  NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, nullptr);
+  helper.RunToCompletion(&data);
+  TransactionHelperResult out = helper.output();
+  EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
+}
+
 TEST_F(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
   spdy::SpdySerializedFrame stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index 50860ce..8138abac 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -468,9 +468,8 @@
     return;
 
   // Save the response
-  const bool headers_valid =
-      SpdyHeadersToHttpResponse(response_headers, &response_);
-  DCHECK(headers_valid);
+  const int rv = SpdyHeadersToHttpResponse(response_headers, &response_);
+  DCHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
 
   OnIOComplete(OK);
 }
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 3284777c..009aa51 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -9978,9 +9978,8 @@
 
   GURL hsts_http_url(base::StringPrintf("http://example.net:%d/somehstssite",
                                         test_server.host_port_pair().port()));
-  url::Replacements<char> replacements;
-  const char kNewScheme[] = "https";
-  replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme)));
+  GURL::Replacements replacements;
+  replacements.SetSchemeStr("https");
   GURL hsts_https_url = hsts_http_url.ReplaceComponents(replacements);
 
   TestDelegate d;
diff --git a/net/websockets/websocket_http2_handshake_stream.cc b/net/websockets/websocket_http2_handshake_stream.cc
index 03fc2dc3..b709d51 100644
--- a/net/websockets/websocket_http2_handshake_stream.cc
+++ b/net/websockets/websocket_http2_handshake_stream.cc
@@ -281,9 +281,9 @@
 
   response_headers_complete_ = true;
 
-  const bool headers_valid =
+  const int rv =
       SpdyHeadersToHttpResponse(response_headers, http_response_info_);
-  DCHECK(headers_valid);
+  DCHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
 
   http_response_info_->response_time = stream_->response_time();
   // Do not store SSLInfo in the response here, HttpNetworkTransaction will take
diff --git a/pdf/BUILD.gn b/pdf/BUILD.gn
index 4594bcad..dba13b2 100644
--- a/pdf/BUILD.gn
+++ b/pdf/BUILD.gn
@@ -350,6 +350,7 @@
       "post_message_receiver.h",
       "post_message_sender.cc",
       "post_message_sender.h",
+      "v8_value_converter.h",
     ]
 
     configs += [ ":strict" ]
@@ -365,7 +366,6 @@
       "//base",
       "//base:i18n",
       "//cc/paint",
-      "//content/public/renderer",
       "//gin",
       "//ppapi/cpp:objects",  # TODO(crbug.com/1114263): PDFEngine::Client only.
       "//printing",
diff --git a/pdf/DEPS b/pdf/DEPS
index afd5d53..6c8815e 100644
--- a/pdf/DEPS
+++ b/pdf/DEPS
@@ -1,6 +1,5 @@
 include_rules = [
   "+cc/paint",
-  "+content/public/renderer/v8_value_converter.h",
   "+gin",
   "+mojo/core/embedder",
   "+mojo/public/cpp/bindings",
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
index 34af3f2..7181b1f5 100644
--- a/pdf/pdf_view_web_plugin.cc
+++ b/pdf/pdf_view_web_plugin.cc
@@ -292,6 +292,7 @@
     : client_(std::move(client)),
       pdf_service_remote_(std::move(pdf_service_remote)),
       initial_params_(params),
+      post_message_sender_(client_.get()),
       pdf_accessibility_data_handler_(
           client_->CreateAccessibilityDataHandler(this)) {
   auto* service = GetPdfService();
@@ -395,9 +396,9 @@
     // TODO(crbug.com/1123731): Messages should not be handled on the renderer
     // main thread.
     scriptable_receiver_.Reset(
-        isolate,
-        PostMessageReceiver::Create(isolate, weak_factory_.GetWeakPtr(),
-                                    base::SequencedTaskRunnerHandle::Get()));
+        isolate, PostMessageReceiver::Create(
+                     isolate, client_->GetWeakPtr(), weak_factory_.GetWeakPtr(),
+                     base::SequencedTaskRunnerHandle::Get()));
   }
 
   return scriptable_receiver_.Get(isolate);
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h
index 4eb0e68..01cc7b7 100644
--- a/pdf/pdf_view_web_plugin.h
+++ b/pdf/pdf_view_web_plugin.h
@@ -23,6 +23,7 @@
 #include "pdf/post_message_sender.h"
 #include "pdf/ppapi_migration/graphics.h"
 #include "pdf/ppapi_migration/url_loader.h"
+#include "pdf/v8_value_converter.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_text_input_type.h"
 #include "third_party/blink/public/web/web_plugin.h"
@@ -142,10 +143,12 @@
   };
 
   // Allows for dependency injections into `PdfViewWebPlugin`.
-  class Client {
+  class Client : public V8ValueConverter {
    public:
     virtual ~Client() = default;
 
+    virtual base::WeakPtr<Client> GetWeakPtr() = 0;
+
     // Prints the given `element`.
     virtual void Print(const blink::WebElement& element) {}
 
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc
index 8477158e..07c2c21 100644
--- a/pdf/pdf_view_web_plugin_unittest.cc
+++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "base/location.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "base/test/bind.h"
@@ -242,7 +243,19 @@
   ~FakePdfViewWebPluginClient() override = default;
 
   // PdfViewWebPlugin::Client:
+  MOCK_METHOD(std::unique_ptr<base::Value>,
+              FromV8Value,
+              (v8::Local<v8::Value>, v8::Local<v8::Context>),
+              (override));
+  MOCK_METHOD(v8::Local<v8::Value>,
+              ToV8Value,
+              (const base::Value&, v8::Local<v8::Context>),
+              (override));
+  MOCK_METHOD(base::WeakPtr<Client>, GetWeakPtr, (), (override));
   MOCK_METHOD(bool, IsUseZoomForDSFEnabled, (), (const, override));
+
+ private:
+  base::WeakPtrFactory<FakePdfViewWebPluginClient> weak_factory_{this};
 };
 
 }  // namespace
diff --git a/pdf/post_message_receiver.cc b/pdf/post_message_receiver.cc
index c97d9b4..97be655 100644
--- a/pdf/post_message_receiver.cc
+++ b/pdf/post_message_receiver.cc
@@ -16,13 +16,13 @@
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/values.h"
-#include "content/public/renderer/v8_value_converter.h"
 #include "gin/function_template.h"
 #include "gin/handle.h"
 #include "gin/interceptor.h"
 #include "gin/object_template_builder.h"
 #include "gin/public/wrapper_info.h"
 #include "gin/wrappable.h"
+#include "pdf/v8_value_converter.h"
 #include "v8/include/v8.h"
 
 namespace chrome_pdf {
@@ -39,11 +39,13 @@
 // static
 v8::Local<v8::Object> PostMessageReceiver::Create(
     v8::Isolate* isolate,
+    base::WeakPtr<V8ValueConverter> v8_value_converter,
     base::WeakPtr<Client> client,
     scoped_refptr<base::SequencedTaskRunner> client_task_runner) {
   return gin::CreateHandle(
-             isolate, new PostMessageReceiver(isolate, std::move(client),
-                                              std::move(client_task_runner)))
+             isolate, new PostMessageReceiver(
+                          isolate, std::move(v8_value_converter),
+                          std::move(client), std::move(client_task_runner)))
       .ToV8()
       .As<v8::Object>();
 }
@@ -52,9 +54,11 @@
 
 PostMessageReceiver::PostMessageReceiver(
     v8::Isolate* isolate,
+    base::WeakPtr<V8ValueConverter> v8_value_converter,
     base::WeakPtr<Client> client,
     scoped_refptr<base::SequencedTaskRunner> client_task_runner)
     : gin::NamedPropertyInterceptor(isolate, this),
+      v8_value_converter_(std::move(v8_value_converter)),
       isolate_(isolate),
       client_(std::move(client)),
       client_task_runner_(std::move(client_task_runner)) {}
@@ -113,20 +117,12 @@
   return function_template_.Get(isolate_);
 }
 
-std::unique_ptr<base::Value> PostMessageReceiver::ConvertMessage(
-    v8::Local<v8::Value> message) {
-  if (!v8_value_converter_)
-    v8_value_converter_ = content::V8ValueConverter::Create();
-
-  return v8_value_converter_->FromV8Value(message,
-                                          isolate_->GetCurrentContext());
-}
-
 void PostMessageReceiver::PostMessage(v8::Local<v8::Value> message) {
-  if (!client_)
+  if (!client_ || !v8_value_converter_)
     return;
 
-  std::unique_ptr<base::Value> converted_message = ConvertMessage(message);
+  std::unique_ptr<base::Value> converted_message =
+      v8_value_converter_->FromV8Value(message, isolate_->GetCurrentContext());
   DCHECK(converted_message) << "The PDF Viewer UI should not be sending "
                                "messages that cannot be converted.";
 
diff --git a/pdf/post_message_receiver.h b/pdf/post_message_receiver.h
index e255c75c..03964d8 100644
--- a/pdf/post_message_receiver.h
+++ b/pdf/post_message_receiver.h
@@ -20,16 +20,14 @@
 class Value;
 }  // namespace base
 
-namespace content {
-class V8ValueConverter;
-}  // namespace content
-
 namespace gin {
 class ObjectTemplateBuilder;
 }  // namespace gin
 
 namespace chrome_pdf {
 
+class V8ValueConverter;
+
 // Implements the `postMessage()` API exposed to the plugin embedder. The
 // received messages are converted and forwarded to the `Client`.
 // `PostMessageReceiver`'s lifetime is managed by the V8 garbage collector,
@@ -55,6 +53,7 @@
   // Messages are posted asynchronously to `client` using `client_task_runner`.
   static v8::Local<v8::Object> Create(
       v8::Isolate* isolate,
+      base::WeakPtr<V8ValueConverter> v8_value_converter,
       base::WeakPtr<Client> client,
       scoped_refptr<base::SequencedTaskRunner> client_task_runner);
 
@@ -67,6 +66,7 @@
  private:
   PostMessageReceiver(
       v8::Isolate* isolate,
+      base::WeakPtr<V8ValueConverter> v8_value_converter,
       base::WeakPtr<Client> client,
       scoped_refptr<base::SequencedTaskRunner> client_task_runner);
 
@@ -84,13 +84,10 @@
   // Lazily creates and retrieves `function_template_`.
   v8::Local<v8::FunctionTemplate> GetFunctionTemplate();
 
-  // Converts `message` so it can be consumed by `client_`.
-  std::unique_ptr<base::Value> ConvertMessage(v8::Local<v8::Value> message);
-
   // Implements the `postMessage()` method called by the embedder.
   void PostMessage(v8::Local<v8::Value> message);
 
-  std::unique_ptr<content::V8ValueConverter> v8_value_converter_;
+  base::WeakPtr<V8ValueConverter> v8_value_converter_;
 
   v8::Persistent<v8::FunctionTemplate> function_template_;
 
diff --git a/pdf/post_message_sender.cc b/pdf/post_message_sender.cc
index 16fa7686..e9fb753 100644
--- a/pdf/post_message_sender.cc
+++ b/pdf/post_message_sender.cc
@@ -8,7 +8,7 @@
 
 #include "base/check_op.h"
 #include "base/values.h"
-#include "content/public/renderer/v8_value_converter.h"
+#include "pdf/v8_value_converter.h"
 #include "third_party/blink/public/web/blink.h"
 #include "third_party/blink/public/web/web_document.h"
 #include "third_party/blink/public/web/web_dom_message_event.h"
@@ -19,7 +19,9 @@
 
 namespace chrome_pdf {
 
-PostMessageSender::PostMessageSender() : isolate_(blink::MainThreadIsolate()) {}
+PostMessageSender::PostMessageSender(V8ValueConverter* v8_value_converter)
+    : v8_value_converter_(v8_value_converter),
+      isolate_(blink::MainThreadIsolate()) {}
 
 PostMessageSender::~PostMessageSender() = default;
 
@@ -40,11 +42,8 @@
   DCHECK_EQ(isolate_, context->GetIsolate());
   v8::Context::Scope context_scope(context);
 
-  if (!v8_value_converter_)
-    v8_value_converter_ = content::V8ValueConverter::Create();
-
   v8::Local<v8::Value> converted_message =
-      v8_value_converter_->ToV8Value(&message, context);
+      v8_value_converter_->ToV8Value(message, context);
 
   container_->EnqueueMessageEvent(
       blink::WebSerializedScriptValue::Serialize(isolate_, converted_message));
diff --git a/pdf/post_message_sender.h b/pdf/post_message_sender.h
index f04097d9..d1ed2ddc 100644
--- a/pdf/post_message_sender.h
+++ b/pdf/post_message_sender.h
@@ -5,9 +5,8 @@
 #ifndef PDF_POST_MESSAGE_SENDER_H_
 #define PDF_POST_MESSAGE_SENDER_H_
 
-#include <memory>
-
 #include "base/memory/raw_ptr.h"
+#include "v8/include/v8-forward.h"
 
 namespace base {
 class Value;
@@ -17,20 +16,14 @@
 class WebPluginContainer;
 }  // namespace blink
 
-namespace content {
-class V8ValueConverter;
-}  // namespace content
-
-namespace v8 {
-class Isolate;
-}  // namespace v8
-
 namespace chrome_pdf {
 
+class V8ValueConverter;
+
 // Manages messages sent from the plugin to its embedder.
 class PostMessageSender final {
  public:
-  PostMessageSender();
+  explicit PostMessageSender(V8ValueConverter* v8_value_converter);
   PostMessageSender(const PostMessageSender&) = delete;
   PostMessageSender& operator=(const PostMessageSender&) = delete;
   ~PostMessageSender();
@@ -47,11 +40,11 @@
   }
 
  private:
-  std::unique_ptr<content::V8ValueConverter> v8_value_converter_;
+  const raw_ptr<V8ValueConverter> v8_value_converter_;
 
-  raw_ptr<v8::Isolate> isolate_;
+  const raw_ptr<v8::Isolate> isolate_;
 
-  raw_ptr<blink::WebPluginContainer> container_ = nullptr;
+  raw_ptr<blink::WebPluginContainer> container_;
 };
 
 }  // namespace chrome_pdf
diff --git a/pdf/v8_value_converter.h b/pdf/v8_value_converter.h
new file mode 100644
index 0000000..4b36afe
--- /dev/null
+++ b/pdf/v8_value_converter.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_V8_VALUE_CONVERTER_H_
+#define PDF_V8_VALUE_CONVERTER_H_
+
+#include <memory>
+
+#include "v8/include/v8-forward.h"
+
+namespace base {
+class Value;
+}  // namespace base
+
+namespace chrome_pdf {
+
+// Abstraction layer for base::Value from/to V8::Value conversions.
+// Necessary because //pdf should not directly depend on //content. If the V8
+// V8 value conversion code ever moves into Blink, remove this and use the
+// conversion code from Blink directly.
+
+class V8ValueConverter {
+ public:
+  virtual std::unique_ptr<base::Value> FromV8Value(
+      v8::Local<v8::Value> value,
+      v8::Local<v8::Context> context) = 0;
+  virtual v8::Local<v8::Value> ToV8Value(const base::Value& value,
+                                         v8::Local<v8::Context> context) = 0;
+
+ protected:
+  ~V8ValueConverter() = default;
+};
+
+}  // namespace chrome_pdf
+
+#endif  // PDF_V8_VALUE_CONVERTER_H_
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc
index 0e552ef8..b4cab9f 100644
--- a/printing/backend/print_backend_win.cc
+++ b/printing/backend/print_backend_win.cc
@@ -31,6 +31,22 @@
 
 namespace {
 
+// Wrapper class to close provider automatically.
+class ScopedProvider {
+ public:
+  explicit ScopedProvider(HPTPROVIDER provider) : provider_(provider) {}
+
+  // Once the object is destroyed, it automatically closes the provider by
+  // calling the XPSModule API.
+  ~ScopedProvider() {
+    if (provider_)
+      XPSModule::CloseProvider(provider_);
+  }
+
+ private:
+  HPTPROVIDER provider_;
+};
+
 // `GetResultCodeFromSystemErrorCode()` is only ever invoked when something has
 // gone wrong while interacting with the OS printing system.  If the cause of
 // the failure was not of the type to register and be and available from
@@ -470,9 +486,9 @@
   std::wstring wide_printer_name = base::UTF8ToWide(printer_name);
   HRESULT hr =
       XPSModule::OpenProvider(wide_printer_name, /*version=*/1, &provider);
+  ScopedProvider scoped_provider(provider);
   if (FAILED(hr) || !provider) {
     LOG(ERROR) << "Failed to open provider";
-    XPSModule::CloseProvider(provider);
     return mojom::ResultCode::kFailed;
   }
   Microsoft::WRL::ComPtr<IStream> print_capabilities_stream;
@@ -480,7 +496,6 @@
                              &print_capabilities_stream);
   if (FAILED(hr) || !print_capabilities_stream.Get()) {
     LOG(ERROR) << "Failed to create stream";
-    XPSModule::CloseProvider(provider);
     return mojom::ResultCode::kFailed;
   }
   base::win::ScopedBstr error;
@@ -489,7 +504,6 @@
                                        error.Receive());
   if (FAILED(hr)) {
     LOG(ERROR) << "Failed to get print capabilities";
-    XPSModule::CloseProvider(provider);
 
     // Failures from getting print capabilities don't give a system error,
     // so just indicate general failure.
@@ -501,7 +515,6 @@
 
   if (FAILED(hr)) {
     LOG(ERROR) << "Failed to convert stream to string";
-    XPSModule::CloseProvider(provider);
     return mojom::ResultCode::kFailed;
   }
   DVLOG(2) << "Printer capabilities info: Name = " << printer_name
@@ -510,7 +523,6 @@
   // TODO(crbug.com/1291257)  Need to parse the XML to extract
   // capabilities. More work expected here.
 
-  XPSModule::CloseProvider(provider);
   return mojom::ResultCode::kSuccess;
 }
 
diff --git a/printing/common/metafile_utils.cc b/printing/common/metafile_utils.cc
index 4f89c06..5e10c367 100644
--- a/printing/common/metafile_utils.cc
+++ b/printing/common/metafile_utils.cc
@@ -158,8 +158,13 @@
           kPDFTableAttributeOwner, kPDFTableCellHeadersAttribute, header_ids);
       break;
     }
-    case ax::mojom::Role::kFigure:
-    case ax::mojom::Role::kImage: {
+    case ax::mojom::Role::kImage:
+      // TODO(thestig): Figure out if the `ax::mojom::Role::kFigure` case should
+      // share code with the `ax::mojom::Role::kImage` case, and if `valid`
+      // should be set.
+      valid = true;
+      [[fallthrough]];
+    case ax::mojom::Role::kFigure: {
       tag->fTypeString = kPDFStructureTypeFigure;
       std::string alt =
           ax_node->GetStringAttribute(ax::mojom::StringAttribute::kName);
@@ -167,9 +172,6 @@
       break;
     }
     case ax::mojom::Role::kStaticText:
-      // Currently we're only marking text content, so we can't generate
-      // a nonempty structure tree unless we have at least one kStaticText
-      // node in the tree.
       tag->fTypeString = kPDFStructureTypeNonStruct;
       valid = true;
       break;
diff --git a/remoting/base/breakpad_win.cc b/remoting/base/breakpad_win.cc
index 62d3fee..ede0d98 100644
--- a/remoting/base/breakpad_win.cc
+++ b/remoting/base/breakpad_win.cc
@@ -17,7 +17,6 @@
 
 #include "base/atomicops.h"
 #include "base/check.h"
-#include "base/cxx17_backports.h"
 #include "base/file_version_info.h"
 #include "base/lazy_instance.h"
 #include "base/notreached.h"
@@ -169,7 +168,7 @@
   static google_breakpad::CustomInfoEntry entries[] = {
       ver_entry, prod_entry, plat_entry  };
   static google_breakpad::CustomClientInfo custom_info = {entries,
-                                                          base::size(entries)};
+                                                          std::size(entries)};
   return &custom_info;
 }
 
diff --git a/remoting/base/capabilities_unittest.cc b/remoting/base/capabilities_unittest.cc
index 5d804b6..24625cc 100644
--- a/remoting/base/capabilities_unittest.cc
+++ b/remoting/base/capabilities_unittest.cc
@@ -2,16 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "remoting/base/capabilities.h"
+
 #include <stddef.h>
 
 #include <algorithm>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
-#include "remoting/base/capabilities.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -65,7 +65,7 @@
 
   // Verify that HasCapability(|capabilities|, |key|) returns |result|.
   // |result|.
-  for (size_t i = 0; i < base::size(data); ++i) {
+  for (size_t i = 0; i < std::size(data); ++i) {
     std::vector<base::StringPiece> caps =
         base::SplitStringPiece(data[i].capabilities, " ", base::KEEP_WHITESPACE,
                                base::SPLIT_WANT_NONEMPTY);
@@ -97,7 +97,7 @@
 
   // Verify that intersection of |right| with all permutations of |left| yields
   // |result|.
-  for (size_t i = 0; i < base::size(data); ++i) {
+  for (size_t i = 0; i < std::size(data); ++i) {
     std::vector<base::StringPiece> caps = base::SplitStringPiece(
         data[i].left, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
     do {
diff --git a/remoting/base/rate_counter_unittest.cc b/remoting/base/rate_counter_unittest.cc
index 170c27c0..b9e3c50 100644
--- a/remoting/base/rate_counter_unittest.cc
+++ b/remoting/base/rate_counter_unittest.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "remoting/base/rate_counter.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
 #include "base/test/simple_test_tick_clock.h"
-#include "remoting/base/rate_counter.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -22,7 +22,7 @@
   base::SimpleTestTickClock tick_clock;
   rate_counter.set_tick_clock_for_tests(&tick_clock);
 
-  for (size_t i = 0; i < base::size(kTestValues); ++i) {
+  for (size_t i = 0; i < std::size(kTestValues); ++i) {
     tick_clock.Advance(base::Seconds(1));
     rate_counter.Record(kTestValues[i]);
     EXPECT_EQ(static_cast<double>(kTestValues[i]), rate_counter.Rate());
@@ -38,7 +38,7 @@
   rate_counter.set_tick_clock_for_tests(&tick_clock);
 
   double expected = 0.0;
-  for (size_t i = 0; i < base::size(kTestValues); ++i) {
+  for (size_t i = 0; i < std::size(kTestValues); ++i) {
     rate_counter.Record(kTestValues[i]);
     expected += kTestValues[i];
   }
@@ -56,7 +56,7 @@
   base::SimpleTestTickClock tick_clock;
   rate_counter.set_tick_clock_for_tests(&tick_clock);
 
-  for (size_t i = 0; i < base::size(kTestValues); ++i) {
+  for (size_t i = 0; i < std::size(kTestValues); ++i) {
     tick_clock.Advance(base::Seconds(1));
     rate_counter.Record(kTestValues[i]);
     double expected = kTestValues[i];
@@ -70,7 +70,7 @@
 // Sample over a window one second shorter than the number of samples.
 // Rate should be the average of all but the first sample.
 TEST(RateCounterTest, LongWindow) {
-  const size_t kWindowSeconds = base::size(kTestValues) - 1;
+  const size_t kWindowSeconds = std::size(kTestValues) - 1;
 
   RateCounter rate_counter(base::Seconds(kWindowSeconds));
   EXPECT_EQ(0, rate_counter.Rate());
@@ -79,7 +79,7 @@
   rate_counter.set_tick_clock_for_tests(&tick_clock);
 
   double expected = 0.0;
-  for (size_t i = 0; i < base::size(kTestValues); ++i) {
+  for (size_t i = 0; i < std::size(kTestValues); ++i) {
     tick_clock.Advance(base::Seconds(1));
     rate_counter.Record(kTestValues[i]);
     if (i != 0)
diff --git a/remoting/base/running_samples_unittest.cc b/remoting/base/running_samples_unittest.cc
index a156559..830f02f 100644
--- a/remoting/base/running_samples_unittest.cc
+++ b/remoting/base/running_samples_unittest.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "remoting/base/running_samples.h"
+
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
-#include "remoting/base/running_samples.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -22,7 +22,7 @@
   EXPECT_EQ(0, samples.Average());
   EXPECT_EQ(0, samples.Max());
 
-  for (size_t i = 0; i < base::size(kTestValues); ++i) {
+  for (size_t i = 0; i < std::size(kTestValues); ++i) {
     samples.Record(kTestValues[i]);
     testFn(i, samples);
   }
@@ -48,7 +48,7 @@
 
 // Average across all the elements if the window size exceeds the element count.
 TEST(RunningSamplesTest, AverageLongWindow) {
-  TestFramework(base::size(kTestValues) + 1,
+  TestFramework(std::size(kTestValues) + 1,
                 [](size_t i, RunningSamples& samples) {
                   double expected = 0.0;
                   for (size_t j = 0; j <= i; ++j)
@@ -80,7 +80,7 @@
 // Max of all the elements if the window size exceeds the element count.
 TEST(RunningSamplesTest, MaxLongWindow) {
   TestFramework(
-      base::size(kTestValues) + 1, [](size_t i, RunningSamples& samples) {
+      std::size(kTestValues) + 1, [](size_t i, RunningSamples& samples) {
         int64_t expected = -1;
         for (size_t j = 0; j <= i; ++j)
           expected = expected > kTestValues[j] ? expected : kTestValues[j];
diff --git a/remoting/base/weighted_samples_unittest.cc b/remoting/base/weighted_samples_unittest.cc
index 2229367..5ae992c 100644
--- a/remoting/base/weighted_samples_unittest.cc
+++ b/remoting/base/weighted_samples_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "remoting/base/weighted_samples.h"
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -18,7 +17,7 @@
     2.6312881651642916,
   };
   WeightedSamples samples(kWeightFactor);
-  for (size_t i = 0; i < base::size(kExpected); i++) {
+  for (size_t i = 0; i < std::size(kExpected); i++) {
     samples.Record(i + 1);
     EXPECT_DOUBLE_EQ(kExpected[i], samples.WeightedAverage());
   }
diff --git a/remoting/client/audio/audio_player_android.cc b/remoting/client/audio/audio_player_android.cc
index aca53e4f..242b0c3d 100644
--- a/remoting/client/audio/audio_player_android.cc
+++ b/remoting/client/audio/audio_player_android.cc
@@ -4,7 +4,6 @@
 
 #include "remoting/client/audio/audio_player_android.h"
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -82,7 +81,7 @@
   const SLboolean reqs[] = {SL_BOOLEAN_TRUE};
 
   if ((*engine_)->CreateAudioPlayer(engine_, &player_object_, &source, &sink,
-                                    base::size(ids), ids,
+                                    std::size(ids), ids,
                                     reqs) != SL_RESULT_SUCCESS ||
       (*player_object_)->Realize(player_object_, SL_BOOLEAN_FALSE) !=
           SL_RESULT_SUCCESS ||
diff --git a/remoting/client/client_telemetry_logger.cc b/remoting/client/client_telemetry_logger.cc
index 0ebd67fac..d1fdc37 100644
--- a/remoting/client/client_telemetry_logger.cc
+++ b/remoting/client/client_telemetry_logger.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/cxx17_backports.h"
 #include "base/format_macros.h"
 #include "base/logging.h"
 #include "base/rand_util.h"
@@ -256,7 +255,7 @@
 void ClientTelemetryLogger::GenerateSessionId() {
   session_id_.resize(kSessionIdLength);
   for (int i = 0; i < kSessionIdLength; i++) {
-    const int alphabet_size = base::size(kSessionIdAlphabet) - 1;
+    const int alphabet_size = std::size(kSessionIdAlphabet) - 1;
     session_id_[i] = kSessionIdAlphabet[base::RandGenerator(alphabet_size)];
   }
   session_id_generation_time_ = base::TimeTicks::Now();
diff --git a/remoting/codec/audio_decoder_opus.cc b/remoting/codec/audio_decoder_opus.cc
index 26106285..c07eb5f 100644
--- a/remoting/codec/audio_decoder_opus.cc
+++ b/remoting/codec/audio_decoder_opus.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/time/time.h"
 #include "remoting/proto/audio.pb.h"
@@ -108,12 +107,12 @@
 
   for (int i = 0; i < packet->data_size(); ++i) {
     int16_t* pcm_buffer =
-        reinterpret_cast<int16_t*>(base::data(*decoded_data) + buffer_pos);
+        reinterpret_cast<int16_t*>(std::data(*decoded_data) + buffer_pos);
     CHECK_LE(buffer_pos + max_frame_bytes,
              static_cast<int>(decoded_data->size()));
     std::string* frame = packet->mutable_data(i);
     unsigned char* frame_data =
-        reinterpret_cast<unsigned char*>(base::data(*frame));
+        reinterpret_cast<unsigned char*>(std::data(*frame));
     int result = opus_decode(decoder_, frame_data, frame->size(),
                              pcm_buffer, max_frame_samples, 0);
     if (result < 0) {
diff --git a/remoting/codec/audio_encoder_opus.cc b/remoting/codec/audio_encoder_opus.cc
index 77beba87..d7b2f66 100644
--- a/remoting/codec/audio_encoder_opus.cc
+++ b/remoting/codec/audio_encoder_opus.cc
@@ -5,7 +5,6 @@
 #include "remoting/codec/audio_encoder_opus.h"
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/time/time.h"
 #include "media/base/audio_bus.h"
@@ -199,7 +198,7 @@
     data->resize(kFrameSamples * kBytesPerSample * channels_);
 
     // Encode.
-    unsigned char* buffer = reinterpret_cast<unsigned char*>(base::data(*data));
+    unsigned char* buffer = reinterpret_cast<unsigned char*>(std::data(*data));
     int result = opus_encode(encoder_, pcm_buffer, kFrameSamples,
                              buffer, data->length());
     if (result < 0) {
diff --git a/remoting/codec/codec_test.cc b/remoting/codec/codec_test.cc
index 43e380e..55b9aa77 100644
--- a/remoting/codec/codec_test.cc
+++ b/remoting/codec/codec_test.cc
@@ -12,7 +12,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
 #include "remoting/base/util.h"
@@ -228,8 +227,8 @@
 
   VideoEncoderTester tester;
 
-  for (size_t xi = 0; xi < base::size(kSizes); ++xi) {
-    for (size_t yi = 0; yi < base::size(kSizes); ++yi) {
+  for (size_t xi = 0; xi < std::size(kSizes); ++xi) {
+    for (size_t yi = 0; yi < std::size(kSizes); ++yi) {
       DesktopSize size(kSizes[xi], kSizes[yi]);
       std::unique_ptr<DesktopFrame> frame = PrepareFrame(size);
       for (const DesktopRegion& region : MakeTestRegionLists(size)) {
diff --git a/remoting/codec/video_encoder_verbatim.cc b/remoting/codec/video_encoder_verbatim.cc
index b217af7..720b05c 100644
--- a/remoting/codec/video_encoder_verbatim.cc
+++ b/remoting/codec/video_encoder_verbatim.cc
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/check.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"
@@ -19,7 +18,7 @@
 
 static uint8_t* GetPacketOutputBuffer(VideoPacket* packet, size_t size) {
   packet->mutable_data()->resize(size);
-  return reinterpret_cast<uint8_t*>(base::data(*packet->mutable_data()));
+  return reinterpret_cast<uint8_t*>(std::data(*packet->mutable_data()));
 }
 
 VideoEncoderVerbatim::VideoEncoderVerbatim() = default;
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index c8dd2fe..6e88041d 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -574,10 +574,7 @@
       "touch_injector_win.h",
       "usage_stats_consent_win.cc",
     ]
-    libs += [
-      "crypt32.lib",
-      "Wintrust.lib",
-    ]
+    libs += [ "crypt32.lib" ]
     deps += [
       # On Windows, we use //media/gpu/MediaFoundationVideoEncodeAcceleratorWin
       # to detect whether HW encoder is supported by the system.
@@ -588,6 +585,7 @@
       "//remoting/host/win",
       "//remoting/host/win:messages",
       "//remoting/host/win:remoting_lib_idl",
+      "//remoting/host/win:trust_util",
     ]
 
     public_deps += [ "//remoting/host/win" ]
diff --git a/remoting/host/audio_silence_detector_unittest.cc b/remoting/host/audio_silence_detector_unittest.cc
index c898364f..3f20de3 100644
--- a/remoting/host/audio_silence_detector_unittest.cc
+++ b/remoting/host/audio_silence_detector_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -48,24 +47,24 @@
   const int16_t kSamples[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
   AudioSilenceDetector target(0);
-  TestSilenceDetector(&target, kSamples, base::size(kSamples), true);
+  TestSilenceDetector(&target, kSamples, std::size(kSamples), true);
 }
 
 TEST(AudioSilenceDetectorTest, Sound) {
   const int16_t kSamples[] = {65, 73, 83, 89, 92, -1, 5, 9, 123, 0};
 
   AudioSilenceDetector target(0);
-  TestSilenceDetector(&target, kSamples, base::size(kSamples), false);
+  TestSilenceDetector(&target, kSamples, std::size(kSamples), false);
 }
 
 TEST(AudioSilenceDetectorTest, Threshold) {
   const int16_t kSamples[] = {0, 0, 0, 0, 1, 0, 0, -1, 0, 0};
 
   AudioSilenceDetector target1(0);
-  TestSilenceDetector(&target1, kSamples, base::size(kSamples), false);
+  TestSilenceDetector(&target1, kSamples, std::size(kSamples), false);
 
   AudioSilenceDetector target2(1);
-  TestSilenceDetector(&target2, kSamples, base::size(kSamples), true);
+  TestSilenceDetector(&target2, kSamples, std::size(kSamples), true);
 }
 
 }  // namespace remoting
diff --git a/remoting/host/audio_volume_filter_unittest.cc b/remoting/host/audio_volume_filter_unittest.cc
index 62bf7ba5..bd957f0 100644
--- a/remoting/host/audio_volume_filter_unittest.cc
+++ b/remoting/host/audio_volume_filter_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "remoting/host/audio_volume_filter.h"
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -37,7 +36,7 @@
   // After applying the audio volume, the |samples| should still pass the
   // AudioSilenceDetector, AudioVolumeFilter::Apply() returns true under this
   // condition. Ditto.
-  ASSERT_TRUE(filter.Apply(samples, base::size(samples) / 2));
+  ASSERT_TRUE(filter.Apply(samples, std::size(samples) / 2));
 }
 
 TEST(AudioVolumeFilterTest, ThreeChannels) {
@@ -46,7 +45,7 @@
   FakeAudioVolumeFilter filter(0);
   filter.set_audio_level(0.5f);
   filter.Initialize(6, 3);
-  ASSERT_TRUE(filter.Apply(samples, base::size(samples) / 3));
+  ASSERT_TRUE(filter.Apply(samples, std::size(samples) / 3));
 }
 
 TEST(AudioVolumeFilterTest, SilentSamples) {
@@ -55,7 +54,7 @@
   FakeAudioVolumeFilter filter(0);
   filter.set_audio_level(0.5f);
   filter.Initialize(9, 2);
-  ASSERT_FALSE(filter.Apply(samples, base::size(samples) / 2));
+  ASSERT_FALSE(filter.Apply(samples, std::size(samples) / 2));
 }
 
 TEST(AudioVolumeFilterTest, AudioLevel0) {
@@ -64,7 +63,7 @@
   FakeAudioVolumeFilter filter(0);
   filter.set_audio_level(0);
   filter.Initialize(9, 2);
-  ASSERT_FALSE(filter.Apply(samples, base::size(samples) / 2));
+  ASSERT_FALSE(filter.Apply(samples, std::size(samples) / 2));
 }
 
 TEST(AudioVolumeFilterTest, SilentAfterApplying) {
@@ -73,7 +72,7 @@
   FakeAudioVolumeFilter filter(0);
   filter.set_audio_level(0.9f);
   filter.Initialize(9, 2);
-  ASSERT_TRUE(filter.Apply(samples, base::size(samples) / 2));
+  ASSERT_TRUE(filter.Apply(samples, std::size(samples) / 2));
 }
 
 }  // namespace remoting
diff --git a/remoting/host/daemon_process_win.cc b/remoting/host/daemon_process_win.cc
index d1af148c..178ed470 100644
--- a/remoting/host/daemon_process_win.cc
+++ b/remoting/host/daemon_process_win.cc
@@ -13,7 +13,6 @@
 #include "base/base_switches.h"
 #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/ref_counted.h"
@@ -269,7 +268,7 @@
   std::unique_ptr<base::CommandLine> target(new base::CommandLine(host_binary));
   target->AppendSwitchASCII(kProcessTypeSwitchName, kProcessTypeHost);
   target->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
-                           kCopiedSwitchNames, base::size(kCopiedSwitchNames));
+                           kCopiedSwitchNames, std::size(kCopiedSwitchNames));
 
   std::unique_ptr<UnprivilegedProcessDelegate> delegate(
       new UnprivilegedProcessDelegate(io_task_runner(), std::move(target)));
diff --git a/remoting/host/desktop_resizer_mac.cc b/remoting/host/desktop_resizer_mac.cc
index cac0864..f767e5d 100644
--- a/remoting/host/desktop_resizer_mac.cc
+++ b/remoting/host/desktop_resizer_mac.cc
@@ -7,7 +7,6 @@
 #include <Carbon/Carbon.h>
 #include <stdint.h>
 
-#include "base/cxx17_backports.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_cftyperef.h"
@@ -158,7 +157,7 @@
   CGDirectDisplayID displays[2];
   uint32_t num_displays;
   CGError err =
-      CGGetActiveDisplayList(base::size(displays), displays, &num_displays);
+      CGGetActiveDisplayList(std::size(displays), displays, &num_displays);
   if (err != kCGErrorSuccess || num_displays != 1) {
     return false;
   }
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index 76d64b9..3df52a2 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -346,9 +346,8 @@
 
   // Generate fake responses to keep the video capturer in sync.
   while (pending_capture_frame_requests_) {
-    --pending_capture_frame_requests_;
-    video_capturer_->OnCaptureResult(
-        webrtc::DesktopCapturer::Result::ERROR_TEMPORARY, nullptr);
+    OnCaptureResult(mojom::CaptureResult::NewCaptureError(
+        webrtc::DesktopCapturer::Result::ERROR_TEMPORARY));
   }
 
   if (client_session_events_) {
diff --git a/remoting/host/desktop_session_win.cc b/remoting/host/desktop_session_win.cc
index 86c72e1..63065519 100644
--- a/remoting/host/desktop_session_win.cc
+++ b/remoting/host/desktop_session_win.cc
@@ -42,130 +42,19 @@
 // MIDL-generated declarations and definitions.
 #include "remoting/host/win/chromoting_lib.h"
 #include "remoting/host/win/host_service.h"
+#include "remoting/host/win/trust_util.h"
 #include "remoting/host/win/worker_process_launcher.h"
 #include "remoting/host/win/wts_session_process_delegate.h"
 #include "remoting/host/win/wts_terminal_monitor.h"
 #include "remoting/host/win/wts_terminal_observer.h"
 #include "remoting/host/worker_process_ipc_delegate.h"
 
-// These are Windows headers which would typically be listed first in the
-// include list however they conflict with ipc_message_macros.h if placed there.
-// TODO(joedow): Move these includes to the top of the file after
-// ipc_message_macros.h is no longer needed.
-#include <Softpub.h>
-#include <wintrust.h>
-
 using base::win::ScopedHandle;
 
 namespace remoting {
 
 namespace {
 
-// This function uses the WinVerifyTrust function to validate the signature for
-// the provided |binary_path|. More information on the structures and function
-// used here can be found at:
-// https://docs.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-winverifytrust
-bool IsBinaryTrusted(const base::FilePath& binary_path) {
-#if defined(OFFICIAL_BUILD)
-  WINTRUST_FILE_INFO file_info = {0};
-  file_info.cbStruct = sizeof(file_info);
-  file_info.pcwszFilePath = binary_path.value().c_str();
-  file_info.hFile = NULL;
-  file_info.pgKnownSubject = NULL;
-
-  WINTRUST_DATA wintrust_data = {0};
-  wintrust_data.cbStruct = sizeof(wintrust_data);
-  wintrust_data.pPolicyCallbackData = NULL;
-  wintrust_data.pSIPClientData = NULL;
-  wintrust_data.dwUIChoice = WTD_UI_NONE;
-  wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE;
-  wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
-  wintrust_data.dwStateAction = WTD_STATEACTION_VERIFY;
-  wintrust_data.hWVTStateData = NULL;
-  wintrust_data.pwszURLReference = NULL;
-  wintrust_data.dwUIContext = WTD_UICONTEXT_EXECUTE;
-  wintrust_data.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL;
-  wintrust_data.pFile = &file_info;
-
-  GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
-
-  LONG trust_status = WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE),
-                                     &policy_guid, &wintrust_data);
-
-  DWORD dwLastError;
-  switch (trust_status) {
-    case ERROR_SUCCESS:
-      // Indicates that the binary is trusted:
-      //   - The hash that represents the subject is trusted
-      //   - The publisher is trusted
-      //   - No verification or time stamp chain errors
-      LOG(INFO) << "Signature verified for " << binary_path.value();
-      return true;
-
-    case TRUST_E_NOSIGNATURE:
-      // The file was not signed or had a signature that was not valid.
-      // The reason for this status is retrieved via GetLastError(). Note that
-      // the last error is a DWORD but the expected values set by this function
-      // are HRESULTS so we need to cast.
-      dwLastError = GetLastError();
-      switch (static_cast<HRESULT>(dwLastError)) {
-        case TRUST_E_NOSIGNATURE:
-          LOG(ERROR) << "No signature found for " << binary_path.value()
-                     << ". ErrorReason: 0x" << std::hex << dwLastError;
-          break;
-        case TRUST_E_SUBJECT_FORM_UNKNOWN:
-          LOG(ERROR) << "The trust provider does not support the form "
-                     << "specified for the subject for " << binary_path.value()
-                     << ". ErrorReason: 0x" << std::hex << dwLastError;
-          break;
-        case TRUST_E_PROVIDER_UNKNOWN:
-          LOG(ERROR) << "The trust provider is not recognized on this system "
-                     << "for " << binary_path.value() << ". ErrorReason: 0x"
-                     << std::hex << dwLastError;
-          break;
-        default:
-          // The signature was not valid or there was an error opening the file.
-          LOG(ERROR) << "Could not verify signature for " << binary_path.value()
-                     << ". ErrorReason: " << dwLastError << ", 0x" << std::hex
-                     << dwLastError;
-          break;
-      }
-      return false;
-
-    case TRUST_E_EXPLICIT_DISTRUST:
-      // The hash that represents the subject or the publisher is not allowed by
-      // the admin or user.
-      LOG(ERROR) << "Signature for " << binary_path.value() << " is present, "
-                 << "but is explicitly distrusted.";
-      return false;
-
-    case TRUST_E_SUBJECT_NOT_TRUSTED:
-      LOG(ERROR) << "Signature for " << binary_path.value() << " is present, "
-                 << "but not trusted.";
-      return false;
-
-    case CRYPT_E_SECURITY_SETTINGS:
-      LOG(ERROR) << "Verification failed for " << binary_path.value() << ". "
-                 << "The hash representing the subject or the publisher wasn't "
-                 << "explicitly trusted by the admin and admin policy has "
-                 << "disabled user trust. No signature, publisher or timestamp "
-                 << "errors.";
-      return false;
-
-    default:
-      LOG(ERROR) << "Signature verification error for " << binary_path.value()
-                 << ": 0x" << std::hex << trust_status;
-      return false;
-  }
-#else
-  // Binaries are only signed in official builds so running the code above for
-  // local builds won't work w/o setting up a test certificate and signing the
-  // binaries using it. To simplify local development, bypass the signature
-  // checks.
-  return true;
-#endif
-}
-
 // The security descriptor of the daemon IPC endpoint. It gives full access
 // to SYSTEM and denies access by anyone else.
 const wchar_t kDaemonIpcSecurityDescriptor[] =
@@ -792,7 +681,7 @@
   target->AppendSwitchASCII(kProcessTypeSwitchName, kProcessTypeDesktop);
   // Copy the command line switches enabling verbose logging.
   target->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
-                           kCopiedSwitchNames, base::size(kCopiedSwitchNames));
+                           kCopiedSwitchNames, std::size(kCopiedSwitchNames));
 
   // Create a delegate capable of launching a process in a different session.
   std::unique_ptr<WtsSessionProcessDelegate> delegate(
diff --git a/remoting/host/disconnect_window_win.cc b/remoting/host/disconnect_window_win.cc
index 3e49653..2ab1f5a8 100644
--- a/remoting/host/disconnect_window_win.cc
+++ b/remoting/host/disconnect_window_win.cc
@@ -10,7 +10,6 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/memory/weak_ptr.h"
@@ -141,7 +140,7 @@
   // GetWindowText truncates the text if it is longer than can fit into
   // the buffer.
   WCHAR buffer[256];
-  int result = GetWindowText(control, buffer, base::size(buffer));
+  int result = GetWindowText(control, buffer, std::size(buffer));
   if (!result)
     return false;
 
diff --git a/remoting/host/host_attributes.cc b/remoting/host/host_attributes.cc
index a54f32b1..53aad87 100644
--- a/remoting/host/host_attributes.cc
+++ b/remoting/host/host_attributes.cc
@@ -10,7 +10,6 @@
 
 #include "base/atomicops.h"
 #include "base/check_op.h"
-#include "base/cxx17_backports.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "build/branding_buildflags.h"
@@ -69,7 +68,7 @@
   return !IsOfficialBuild();
 }
 
-// By using base::size() macro in base/macros.h, it's illegal to have empty
+// By using std::size() macro in base/macros.h, it's illegal to have empty
 // arrays.
 //
 // error: no matching function for call to 'ArraySizeHelper'
diff --git a/remoting/host/installer/win/BUILD.gn b/remoting/host/installer/win/BUILD.gn
index 2accf5cf..33d05d6 100644
--- a/remoting/host/installer/win/BUILD.gn
+++ b/remoting/host/installer/win/BUILD.gn
@@ -18,6 +18,7 @@
     "//remoting/host/it2me:remote_assistance_host",
     "//remoting/host/it2me:remote_assistance_host_uiaccess",
     "//remoting/host/remote_open_url",
+    "//remoting/host/webauthn:remote_webauthn",
     "//remoting/host/win:remoting_core",
     "//remoting/host/win:remoting_desktop",
     "//remoting/host/win:remoting_me2me_host",
@@ -56,6 +57,7 @@
     "$root_out_dir/remote_assistance_host_uiaccess.exe",
     "$root_out_dir/remote_open_url.exe",
     "$root_out_dir/remote_security_key.exe",
+    "$root_out_dir/remote_webauthn.exe",
     "$root_out_dir/remoting_core.dll",
     "$root_out_dir/remoting_desktop.exe",
     "$root_out_dir/remoting_host.exe",
@@ -66,6 +68,7 @@
     "$root_out_dir/remoting/com.google.chrome.remote_assistance-firefox.json",
     "$root_out_dir/remoting/com.google.chrome.remote_desktop.json",
     "$root_out_dir/remoting/com.google.chrome.remote_desktop-firefox.json",
+    "$root_out_dir/remoting/com.google.chrome.remote_webauthn.json",
     "$root_out_dir/icudtl.dat",
   ]
 
@@ -86,6 +89,7 @@
     "files/remote_assistance_host_uiaccess.exe",
     "files/remote_open_url.exe",
     "files/remote_security_key.exe",
+    "files/remote_webauthn.exe",
     "files/remoting_core.dll",
     "files/remoting_desktop.exe",
     "files/remoting_host.exe",
@@ -96,6 +100,7 @@
     "files/com.google.chrome.remote_assistance-firefox.json",
     "files/com.google.chrome.remote_desktop.json",
     "files/com.google.chrome.remote_desktop-firefox.json",
+    "files/com.google.chrome.remote_webauthn.json",
     "files/icudtl.dat",
     "files/chromoting.ico",
   ]
diff --git a/remoting/host/installer/win/chromoting.wxs b/remoting/host/installer/win/chromoting.wxs
index 2c05254..b409b3a 100644
--- a/remoting/host/installer/win/chromoting.wxs
+++ b/remoting/host/installer/win/chromoting.wxs
@@ -225,6 +225,14 @@
               Vital="yes"/>
       </Component>
 
+      <Component Id="remote_webauthn" Guid="*">
+        <File Id="remote_webauthn.exe"
+              DiskId="1"
+              KeyPath="yes"
+              Name="remote_webauthn.exe"
+              Vital="yes"/>
+      </Component>
+
       <Component Id="remote_open_url_registration" Guid="*">
         <!-- ProgID -->
         <RegistryKey Id="remote_open_url_prog_id_reg_key"
@@ -312,6 +320,14 @@
               Vital="yes"/>
       </Component>
 
+      <Component Id="remote_webauthn_manifest" Guid="*">
+        <File Id="com.google.chrome.remote_webauthn.json"
+              DiskId="1"
+              KeyPath="yes"
+              Name="com.google.chrome.remote_webauthn.json"
+              Vital="yes"/>
+      </Component>
+
       <Component Id="icudtl" Guid="*">
         <File Id="icudtl.dat"
               DiskId="1"
@@ -668,6 +684,20 @@
         <CreateFolder/>
       </Component>
 
+      <Component Id="remote_webauthn_registry" Guid="*">
+        <RegistryKey Root="HKLM"
+                     Key="SOFTWARE\Google\chrome\NativeMessagingHosts"
+                     Action="create">
+          <RegistryKey Key="com.google.chrome.remote_webauthn"
+                       Action="create">
+            <RegistryValue
+                Type="string"
+                Value="[binaries]com.google.chrome.remote_webauthn.json"/>
+          </RegistryKey>
+        </RegistryKey>
+        <CreateFolder/>
+      </Component>
+
       <Component Id="remoting_logging_registry"
                  Guid="b640a025-18dd-49b9-b26d-b31252a12f8a">
         <RegistryKey Root="HKLM"
@@ -763,6 +793,9 @@
       <ComponentRef Id="remote_assistance_host_manifest"/>
       <ComponentRef Id="remote_assistance_host_registry"/>
       <ComponentRef Id="remote_assistance_host_uiaccess"/>
+      <ComponentRef Id="remote_webauthn"/>
+      <ComponentRef Id="remote_webauthn_manifest"/>
+      <ComponentRef Id="remote_webauthn_registry"/>
 
       <ComponentRef Id="remote_open_url"/>
       <ComponentRef Id="remote_open_url_registration"/>
diff --git a/remoting/host/it2me/it2me_native_messaging_host_allowed_origins.cc b/remoting/host/it2me/it2me_native_messaging_host_allowed_origins.cc
index f68295e3..4803b69 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_allowed_origins.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_allowed_origins.cc
@@ -4,7 +4,7 @@
 
 #include "remoting/host/it2me/it2me_native_messaging_host_allowed_origins.h"
 
-#include "base/cxx17_backports.h"
+#include <iterator>
 
 namespace remoting {
 
@@ -15,7 +15,7 @@
     "chrome-extension://inomeogfingihgjfjlpeplalcfajhgai/",
     "chrome-extension://hpodccmdligbeohchckkeajbfohibipg/"};
 
-const size_t kIt2MeOriginsSize = base::size(kIt2MeOrigins);
+const size_t kIt2MeOriginsSize = std::size(kIt2MeOrigins);
 
 const char kIt2MeNativeMessageHostName[] =
     "com.google.chrome.remote_assistance";
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
index ea9c18d5..48a8d63 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -11,7 +11,6 @@
 
 #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"
@@ -371,7 +370,7 @@
 
     std::string message_json(length, '\0');
     read_result =
-        output_read_file_.ReadAtCurrentPos(base::data(message_json), length);
+        output_read_file_.ReadAtCurrentPos(std::data(message_json), length);
     if (read_result != static_cast<int>(length)) {
       LOG(ERROR) << "Message size (" << read_result
                  << ") doesn't match the header (" << length << ").";
diff --git a/remoting/host/keyboard_layout_monitor_mac.cc b/remoting/host/keyboard_layout_monitor_mac.cc
index 88797bb..f68c9a8 100644
--- a/remoting/host/keyboard_layout_monitor_mac.cc
+++ b/remoting/host/keyboard_layout_monitor_mac.cc
@@ -189,7 +189,7 @@
                          CFDataGetBytePtr(layout_data)),
                      keycode, kUCKeyActionDown, modifier_state >> 8,
                      keyboard_type, kUCKeyTranslateNoDeadKeysMask,
-                     &deadkey_state, base::size(result_array), &result_length,
+                     &deadkey_state, std::size(result_array), &result_length,
                      result_array);
 
       if (result_length == 0) {
diff --git a/remoting/host/keyboard_layout_monitor_win.cc b/remoting/host/keyboard_layout_monitor_win.cc
index a48fb5b..11dbadb 100644
--- a/remoting/host/keyboard_layout_monitor_win.cc
+++ b/remoting/host/keyboard_layout_monitor_win.cc
@@ -14,7 +14,6 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/utf_string_conversions.h"
@@ -255,7 +254,7 @@
       // scancode into whatever format ToUnicodeEx expects, passing 0 seems to
       // work just fine.
       int size = ToUnicodeEx(translated_key, 0, key_state, char_buffer,
-                             base::size(char_buffer), 0, layout);
+                             std::size(char_buffer), 0, layout);
       if (size < 0) {
         // We don't handle dead keys specially for the layout, but we do
         // need to clear them from the system keyboard state.
@@ -383,7 +382,7 @@
   WCHAR char_buffer[16];
   ToUnicodeEx(VK_SPACE,
               ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::SPACE),
-              key_state, char_buffer, base::size(char_buffer), 0, layout);
+              key_state, char_buffer, std::size(char_buffer), 0, layout);
 }
 
 bool IsNumpadKey(ui::DomCode code) {
diff --git a/remoting/host/linux/audio_pipe_reader.cc b/remoting/host/linux/audio_pipe_reader.cc
index 6f5f039..7a12e5c 100644
--- a/remoting/host/linux/audio_pipe_reader.cc
+++ b/remoting/host/linux/audio_pipe_reader.cc
@@ -13,7 +13,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 
@@ -158,7 +157,7 @@
 
   while (pos < data.size()) {
     int read_result =
-        pipe_.ReadAtCurrentPos(base::data(data) + pos, data.size() - pos);
+        pipe_.ReadAtCurrentPos(std::data(data) + pos, data.size() - pos);
     if (read_result > 0) {
       pos += read_result;
     } else {
diff --git a/remoting/host/linux/remoting_user_session.cc b/remoting/host/linux/remoting_user_session.cc
index 92706a2..8b7589f 100644
--- a/remoting/host/linux/remoting_user_session.cc
+++ b/remoting/host/linux/remoting_user_session.cc
@@ -14,24 +14,22 @@
 //                   running as root, not allowed when running as a normal user.
 //   SCRIPT_ARGS   - Arguments following -- are passed to the script verbatim.
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
 #include <fcntl.h>
 #include <grp.h>
 #include <limits.h>
 #include <pwd.h>
-#include <signal.h>
-#include <unistd.h>
-
 #include <security/pam_appl.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
 
 #include <cerrno>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <ctime>
-
 #include <map>
 #include <memory>
 #include <string>
@@ -39,7 +37,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -289,7 +286,7 @@
 // executable. Should be called at program start.
 void DetermineExecutablePath() {
   ssize_t path_size =
-      readlink(kExeSymlink, gExecutablePath, base::size(gExecutablePath));
+      readlink(kExeSymlink, gExecutablePath, std::size(gExecutablePath));
   PCHECK(path_size >= 0) << "Failed to determine executable location";
   CHECK(path_size < PATH_MAX) << "Executable path too long";
   gExecutablePath[path_size] = '\0';
@@ -603,7 +600,7 @@
       "Interrupted. The daemon is still running in the background.\n";
   // Use write since fputs isn't async-signal-handler safe.
   std::ignore = write(STDERR_FILENO, kInterruptedMessage,
-                      base::size(kInterruptedMessage) - 1);
+                      std::size(kInterruptedMessage) - 1);
   raise(signal);
 }
 
@@ -614,7 +611,7 @@
       "be running in the background.\n";
   // Use write since fputs isn't async-signal-handler safe.
   std::ignore =
-      write(STDERR_FILENO, kTimeoutMessage, base::size(kTimeoutMessage) - 1);
+      write(STDERR_FILENO, kTimeoutMessage, std::size(kTimeoutMessage) - 1);
   // A slow system or directory replication delay may cause the host to take
   // longer than expected to start. Since it may still succeed, optimistically
   // return success to prevent the host from being automatically unregistered.
diff --git a/remoting/host/linux/unicode_to_keysym.cc b/remoting/host/linux/unicode_to_keysym.cc
index 40624ef0..aaf23be 100644
--- a/remoting/host/linux/unicode_to_keysym.cc
+++ b/remoting/host/linux/unicode_to_keysym.cc
@@ -6,7 +6,6 @@
 
 #include <algorithm>
 
-#include "base/cxx17_backports.h"
 #include "ui/gfx/x/keysyms/keysyms.h"
 
 namespace remoting {
@@ -811,7 +810,7 @@
     keysyms.push_back(unicode);
   }
 
-  const CodePair* map_end = kKeySymUnicodeMap + base::size(kKeySymUnicodeMap);
+  const CodePair* map_end = kKeySymUnicodeMap + std::size(kKeySymUnicodeMap);
   const CodePair* pair =
       std::lower_bound(kKeySymUnicodeMap, map_end, unicode, &CompareCodePair);
   while (pair != map_end && pair->unicode == unicode) {
diff --git a/remoting/host/linux/unicode_to_keysym_unittest.cc b/remoting/host/linux/unicode_to_keysym_unittest.cc
index 01e2a79..22cc0b8 100644
--- a/remoting/host/linux/unicode_to_keysym_unittest.cc
+++ b/remoting/host/linux/unicode_to_keysym_unittest.cc
@@ -9,7 +9,6 @@
 
 #include <algorithm>
 
-#include "base/cxx17_backports.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace remoting {
@@ -36,7 +35,7 @@
     { 0x4444, { 0x01004444, 0 } },
   };
 
-  for (size_t i = 0; i < base::size(kTests); ++i) {
+  for (size_t i = 0; i < std::size(kTests); ++i) {
     std::vector<uint32_t> keysyms = GetKeySymsForUnicode(kTests[i].code_point);
 
     std::vector<uint32_t> expected(
diff --git a/remoting/host/linux/x_server_clipboard.cc b/remoting/host/linux/x_server_clipboard.cc
index 7478e071..8730fcf 100644
--- a/remoting/host/linux/x_server_clipboard.cc
+++ b/remoting/host/linux/x_server_clipboard.cc
@@ -7,7 +7,6 @@
 #include <limits>
 
 #include "base/callback.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_util.h"
@@ -53,7 +52,7 @@
   static const char* const kAtomNames[] = {"CLIPBOARD",        "INCR",
                                            "SELECTION_STRING", "TARGETS",
                                            "TIMESTAMP",        "UTF8_STRING"};
-  static const int kNumAtomNames = base::size(kAtomNames);
+  static const int kNumAtomNames = std::size(kAtomNames);
 
   x11::Future<x11::InternAtomReply> futures[kNumAtomNames];
   for (size_t i = 0; i < kNumAtomNames; i++)
@@ -257,7 +256,7 @@
       .property = property,
       .type = x11::Atom::ATOM,
       .format = CHAR_BIT * sizeof(x11::Atom),
-      .data_len = base::size(targets),
+      .data_len = std::size(targets),
       .data = base::MakeRefCounted<base::RefCountedStaticMemory>(
           &targets[0], sizeof(targets)),
   });
diff --git a/remoting/host/mojo_ipc/BUILD.gn b/remoting/host/mojo_ipc/BUILD.gn
index 6ca64a7..d7f3ed33 100644
--- a/remoting/host/mojo_ipc/BUILD.gn
+++ b/remoting/host/mojo_ipc/BUILD.gn
@@ -5,6 +5,7 @@
 static_library("mojo_ipc") {
   sources = [
     "ipc_server.h",
+    "mojo_caller_security_checker.cc",
     "mojo_caller_security_checker.h",
     "mojo_ipc_server.cc",
     "mojo_ipc_server.h",
@@ -12,9 +13,14 @@
     "mojo_ipc_util.h",
     "mojo_server_endpoint_connector.h",
   ]
+  deps = [
+    "//base",
+    "//mojo/public/cpp/bindings",
+    "//mojo/public/cpp/platform",
+    "//mojo/public/cpp/system",
+  ]
   if (is_linux) {
     sources += [
-      "mojo_caller_security_checker_linux.cc",
       "mojo_server_endpoint_connector_linux.cc",
       "mojo_server_endpoint_connector_linux.h",
     ]
@@ -23,18 +29,10 @@
       "mojo_server_endpoint_connector_win.cc",
       "mojo_server_endpoint_connector_win.h",
     ]
+    deps += [ "//remoting/host/win:trust_util" ]
   } else {
     sources += [ "mojo_server_endpoint_connector_unsupported.cc" ]
   }
-  if (!is_linux) {
-    sources += [ "bypass_mojo_caller_security_checker.cc" ]
-  }
-  deps = [
-    "//base",
-    "//mojo/public/cpp/bindings",
-    "//mojo/public/cpp/platform",
-    "//mojo/public/cpp/system",
-  ]
 }
 
 static_library("test_support") {
diff --git a/remoting/host/mojo_ipc/bypass_mojo_caller_security_checker.cc b/remoting/host/mojo_ipc/bypass_mojo_caller_security_checker.cc
deleted file mode 100644
index 542bb06..0000000
--- a/remoting/host/mojo_ipc/bypass_mojo_caller_security_checker.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/host/mojo_ipc/mojo_caller_security_checker.h"
-
-namespace remoting {
-
-// An implementation that unconditionally returns true in the CheckCaller()
-// method. This is to allow platforms that don't have MojoCallerSecurityChecker
-// implemented to still be able to handle incoming IPCs.
-// TODO(yuweih): Implement MojoCallerSecurityChecker for Windows.
-bool IsTrustedMojoEndpoint(base::ProcessId caller_pid) {
-  return true;
-}
-
-}  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_caller_security_checker_linux.cc b/remoting/host/mojo_ipc/mojo_caller_security_checker.cc
similarity index 60%
rename from remoting/host/mojo_ipc/mojo_caller_security_checker_linux.cc
rename to remoting/host/mojo_ipc/mojo_caller_security_checker.cc
index 2ee1746..20525a49 100644
--- a/remoting/host/mojo_ipc/mojo_caller_security_checker_linux.cc
+++ b/remoting/host/mojo_ipc/mojo_caller_security_checker.cc
@@ -4,26 +4,43 @@
 
 #include "remoting/host/mojo_ipc/mojo_caller_security_checker.h"
 
+#include <array>
+
 #include "base/containers/fixed_flat_set.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
+#include "base/notreached.h"
 #include "base/process/process_handle.h"
-#include "base/strings/string_piece_forward.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "build/build_config.h"
+
+#if BUILDFLAG(IS_WIN)
+#include <windows.h>
+
+#include "base/win/scoped_handle.h"
+#include "remoting/host/win/trust_util.h"
+#endif
 
 namespace remoting {
 namespace {
 
 constexpr auto kAllowedCallerProgramNames =
-    base::MakeFixedFlatSet<base::StringPiece>({
-        "remote-open-url",
-        "remote-webauthn",
+    base::MakeFixedFlatSet<base::FilePath::StringPieceType>({
+#if BUILDFLAG(IS_LINUX)
+      "remote-open-url", "remote-webauthn",
+#elif BUILDFLAG(IS_WIN)
+      L"remote_open_url.exe", L"remote_webauthn.exe",
+#else
+      // MakeFixedFlatSet() requires at least one element.
+      "unsupported",
+#endif
     });
 
 base::FilePath GetProcessImagePath(base::ProcessId pid) {
+#if BUILDFLAG(IS_LINUX)
   // We don't get the image path from the command line, since it's spoofable by
   // the process itself.
   base::FilePath process_exe_path(
@@ -31,6 +48,23 @@
   base::FilePath process_image_path;
   base::ReadSymbolicLink(process_exe_path, &process_image_path);
   return process_image_path;
+#elif BUILDFLAG(IS_WIN)
+  base::win::ScopedHandle process_handle(
+      OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid));
+  std::array<wchar_t, MAX_PATH + 1> buffer;
+  DWORD size = buffer.size();
+  if (!QueryFullProcessImageName(process_handle.Get(), 0, buffer.data(),
+                                 &size)) {
+    PLOG(ERROR) << "QueryFullProcessImageName failed";
+    return base::FilePath();
+  }
+  DCHECK_GT(size, 0u);
+  DCHECK_LT(size, buffer.size());
+  return base::FilePath(base::FilePath::StringPieceType(buffer.data(), size));
+#else
+  NOTIMPLEMENTED();
+  return base::FilePath();
+#endif
 }
 
 }  // namespace
@@ -53,10 +87,11 @@
                << " is not under " << current_process_image_path->DirName();
     return false;
   }
-  std::string program_name = caller_process_image_path.BaseName().value();
+  base::FilePath::StringType program_name =
+      caller_process_image_path.BaseName().value();
   if (!kAllowedCallerProgramNames.contains(program_name)) {
-#if !defined(NDEBUG)
-    // Binaries generated in out/Debug are underscore-separated. To make
+#if BUILDFLAG(IS_LINUX) && !defined(NDEBUG)
+    // Linux binaries generated in out/Debug are underscore-separated. To make
     // debugging easier, we just check the name again with underscores replaced
     // with hyphens.
     std::string program_name_hyphenated;
@@ -64,12 +99,17 @@
     if (kAllowedCallerProgramNames.contains(program_name_hyphenated)) {
       return true;
     }
-#endif  // !defined(NDEBUG)
+#endif  // BUILDFLAG(IS_LINUX) && !defined(NDEBUG)
     LOG(ERROR) << caller_process_image_path.BaseName()
                << " is not in the list of allowed caller programs.";
     return false;
   }
+#if BUILDFLAG(IS_WIN)
+  return IsBinaryTrusted(caller_process_image_path);
+#else
+  // Linux binaries are not code-signed, so we just return true.
   return true;
+#endif
 }
 
 }  // namespace remoting
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc
index bfe6916697..3ff0a01 100644
--- a/remoting/host/native_messaging/native_messaging_reader.cc
+++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -10,7 +10,6 @@
 #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"
@@ -116,7 +115,7 @@
 
     std::string message_json(message_length, '\0');
     read_result =
-        read_stream_.ReadAtCurrentPos(base::data(message_json), message_length);
+        read_stream_.ReadAtCurrentPos(std::data(message_json), message_length);
     if (read_result != static_cast<int>(message_length)) {
       LOG(ERROR) << "Failed to read message body, read returned "
                  << read_result;
diff --git a/remoting/host/native_messaging/native_messaging_writer_unittest.cc b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
index 2dc515a9..087caac 100644
--- a/remoting/host/native_messaging/native_messaging_writer_unittest.cc
+++ b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 #include <utility>
 
-#include "base/cxx17_backports.h"
 #include "base/json/json_reader.h"
 #include "base/values.h"
 #include "remoting/host/setup/test_util.h"
@@ -48,7 +47,7 @@
   int read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4);
   EXPECT_EQ(4, read);
   std::string content(length, '\0');
-  read = read_file_.ReadAtCurrentPos(base::data(content), length);
+  read = read_file_.ReadAtCurrentPos(std::data(content), length);
   EXPECT_EQ(static_cast<int>(length), read);
 
   // |content| should now contain serialized |message|.
@@ -80,7 +79,7 @@
     read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4);
     EXPECT_EQ(4, read) << "i = " << i;
     content.resize(length);
-    read = read_file_.ReadAtCurrentPos(base::data(content), length);
+    read = read_file_.ReadAtCurrentPos(std::data(content), length);
     EXPECT_EQ(static_cast<int>(length), read) << "i = " << i;
   }
 
diff --git a/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc b/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
index 1a3f8b4..bf15594 100644
--- a/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
+++ b/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
@@ -11,7 +11,6 @@
 #include <ios>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/notreached.h"
 #include "base/process/launch.h"
 #include "base/strings/string_util.h"
@@ -32,7 +31,7 @@
 std::wstring GetLaunchBrowserCommand(const std::wstring& browser_prog_id,
                                      const GURL& url) {
   wchar_t open_cmd_buf[MAX_PATH];
-  DWORD open_cmd_buf_len = base::size(open_cmd_buf);
+  DWORD open_cmd_buf_len = std::size(open_cmd_buf);
   HRESULT hr =
       AssocQueryString(ASSOCF_NONE, ASSOCSTR_COMMAND, browser_prog_id.c_str(),
                        L"open", open_cmd_buf, &open_cmd_buf_len);
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index c626c87..205b2fa 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -1697,11 +1697,8 @@
   // The feature is enabled for all Googlers using a supported platform.
   desktop_environment_options_.set_enable_remote_open_url(is_googler_);
 
-#if BUILDFLAG(IS_LINUX) || !defined(NDEBUG)
-  // Experimental feature. Enabled on Linux for easier testing.
-  if (is_googler_) {
-    desktop_environment_options_.set_enable_remote_webauthn(true);
-  }
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
+  desktop_environment_options_.set_enable_remote_webauthn(is_googler_);
 #endif
 
   if (max_clipboard_size_.has_value()) {
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 d10ba566..f8abc787 100644
--- a/remoting/host/security_key/security_key_message_reader_impl.cc
+++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/files/file.h"
 #include "base/logging.h"
 #include "base/message_loop/message_pump_type.h"
@@ -77,7 +76,7 @@
     }
 
     std::string message_data(message_length_bytes, '\0');
-    if (!ReadFromStream(base::data(message_data), message_data.size())) {
+    if (!ReadFromStream(std::data(message_data), message_data.size())) {
       NotifyError();
       return;
     }
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 ac48cc0..1df43b2 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,7 +9,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/run_loop.h"
 #include "base/task/task_runner_util.h"
 #include "base/test/task_environment.h"
@@ -69,16 +68,16 @@
 std::string SecurityKeyMessageWriterImplTest::ReadMessage(
     int payload_length_bytes) {
   std::string message_header(SecurityKeyMessage::kHeaderSizeBytes, '\0');
-  read_file_.ReadAtCurrentPos(base::data(message_header),
+  read_file_.ReadAtCurrentPos(std::data(message_header),
                               SecurityKeyMessage::kHeaderSizeBytes);
 
   std::string message_type(SecurityKeyMessage::kMessageTypeSizeBytes, '\0');
-  read_file_.ReadAtCurrentPos(base::data(message_type),
+  read_file_.ReadAtCurrentPos(std::data(message_type),
                               SecurityKeyMessage::kMessageTypeSizeBytes);
 
   std::string message_data(payload_length_bytes, '\0');
   if (payload_length_bytes) {
-    read_file_.ReadAtCurrentPos(base::data(message_data), payload_length_bytes);
+    read_file_.ReadAtCurrentPos(std::data(message_data), payload_length_bytes);
   }
 
   return message_header + message_type + message_data;
@@ -178,7 +177,7 @@
     // Retrieve and verify the message type.
     std::string message_type(length, '\0');
     int bytes_read =
-        read_file_.ReadAtCurrentPos(base::data(message_type), length);
+        read_file_.ReadAtCurrentPos(std::data(message_type), length);
     ASSERT_EQ(length, bytes_read);
 
     SecurityKeyMessageType type =
diff --git a/remoting/host/security_key/security_key_socket.cc b/remoting/host/security_key/security_key_socket.cc
index aa14bdb..bfc6972 100644
--- a/remoting/host/security_key/security_key_socket.cc
+++ b/remoting/host/security_key/security_key_socket.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/timer/timer.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -75,7 +74,7 @@
 void SecurityKeySocket::SendSshError() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  SendResponse(std::string(kSshError, base::size(kSshError)));
+  SendResponse(std::string(kSshError, std::size(kSshError)));
 }
 
 void SecurityKeySocket::StartReadingRequest(
diff --git a/remoting/host/setup/daemon_controller_delegate_win.cc b/remoting/host/setup/daemon_controller_delegate_win.cc
index 7bc9038..5146965 100644
--- a/remoting/host/setup/daemon_controller_delegate_win.cc
+++ b/remoting/host/setup/daemon_controller_delegate_win.cc
@@ -8,7 +8,6 @@
 
 #include <tuple>
 
-#include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
@@ -384,7 +383,7 @@
     std::unique_ptr<base::DictionaryValue> config,
     DaemonController::CompletionCallback done) {
   // Check for bad keys.
-  for (size_t i = 0; i < base::size(kReadonlyKeys); ++i) {
+  for (size_t i = 0; i < std::size(kReadonlyKeys); ++i) {
     if (config->HasKey(kReadonlyKeys[i])) {
       LOG(ERROR) << "Cannot update config: '" << kReadonlyKeys[i]
                  << "' is read only.";
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
index 09c33d6..96697a1 100644
--- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -13,7 +13,6 @@
 
 #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/memory/ptr_util.h"
@@ -428,7 +427,7 @@
 
     std::string message_json(length, '\0');
     read_result =
-        output_read_file_.ReadAtCurrentPos(base::data(message_json), length);
+        output_read_file_.ReadAtCurrentPos(std::data(message_json), length);
     if (read_result != static_cast<int>(length)) {
       return nullptr;
     }
@@ -553,7 +552,7 @@
       &VerifyStartDaemonResponse,
       &VerifyGetCredentialsFromAuthCodeResponse,
   };
-  ASSERT_EQ(base::size(verify_routines), static_cast<size_t>(next_id));
+  ASSERT_EQ(std::size(verify_routines), static_cast<size_t>(next_id));
 
   // Read all responses from output pipe, and verify them.
   for (int i = 0; i < next_id; ++i) {
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn
index 36f985a..dd3a719 100644
--- a/remoting/host/win/BUILD.gn
+++ b/remoting/host/win/BUILD.gn
@@ -99,6 +99,15 @@
   deps = [ "//base" ]
 }
 
+source_set("trust_util") {
+  sources = [
+    "trust_util.cc",
+    "trust_util.h",
+  ]
+  deps = [ "//base" ]
+  libs = [ "Wintrust.lib" ]
+}
+
 source_set("win") {
   sources = [
     "audio_volume_filter_win.cc",
diff --git a/remoting/host/win/rdp_client_window.cc b/remoting/host/win/rdp_client_window.cc
index b7ee94e..2e4de04 100644
--- a/remoting/host/win/rdp_client_window.cc
+++ b/remoting/host/win/rdp_client_window.cc
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/lazy_instance.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -75,7 +74,7 @@
     while (child != nullptr) {
       // See if the window class name matches |class_name|.
       WCHAR name[kMaxWindowClassLength];
-      int length = GetClassName(child, name, base::size(name));
+      int length = GetClassName(child, name, std::size(name));
       if (std::wstring(name, length) == class_name)
         return child;
 
diff --git a/remoting/host/win/trust_util.cc b/remoting/host/win/trust_util.cc
new file mode 100644
index 0000000..9b9cc6c
--- /dev/null
+++ b/remoting/host/win/trust_util.cc
@@ -0,0 +1,122 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/win/trust_util.h"
+
+#include <windows.h>
+
+#include <softpub.h>
+#include <wintrust.h>
+
+#include "base/logging.h"
+
+namespace remoting {
+
+bool IsBinaryTrusted(const base::FilePath& binary_path) {
+#if defined(OFFICIAL_BUILD)
+  // This function uses the WinVerifyTrust function to validate the signature
+  // for the provided |binary_path|. More information on the structures and
+  // function used here can be found at:
+  // https://docs.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-winverifytrust
+
+  WINTRUST_FILE_INFO file_info = {0};
+  file_info.cbStruct = sizeof(file_info);
+  file_info.pcwszFilePath = binary_path.value().c_str();
+  file_info.hFile = NULL;
+  file_info.pgKnownSubject = NULL;
+
+  WINTRUST_DATA wintrust_data = {0};
+  wintrust_data.cbStruct = sizeof(wintrust_data);
+  wintrust_data.pPolicyCallbackData = NULL;
+  wintrust_data.pSIPClientData = NULL;
+  wintrust_data.dwUIChoice = WTD_UI_NONE;
+  wintrust_data.fdwRevocationChecks = WTD_REVOKE_NONE;
+  wintrust_data.dwUnionChoice = WTD_CHOICE_FILE;
+  wintrust_data.dwStateAction = WTD_STATEACTION_VERIFY;
+  wintrust_data.hWVTStateData = NULL;
+  wintrust_data.pwszURLReference = NULL;
+  wintrust_data.dwUIContext = WTD_UICONTEXT_EXECUTE;
+  wintrust_data.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL;
+  wintrust_data.pFile = &file_info;
+
+  GUID policy_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+
+  LONG trust_status = WinVerifyTrust(static_cast<HWND>(INVALID_HANDLE_VALUE),
+                                     &policy_guid, &wintrust_data);
+
+  DWORD dwLastError;
+  switch (trust_status) {
+    case ERROR_SUCCESS:
+      // Indicates that the binary is trusted:
+      //   - The hash that represents the subject is trusted
+      //   - The publisher is trusted
+      //   - No verification or time stamp chain errors
+      LOG(INFO) << "Signature verified for " << binary_path.value();
+      return true;
+
+    case TRUST_E_NOSIGNATURE:
+      // The file was not signed or had a signature that was not valid.
+      // The reason for this status is retrieved via GetLastError(). Note that
+      // the last error is a DWORD but the expected values set by this function
+      // are HRESULTS so we need to cast.
+      dwLastError = GetLastError();
+      switch (static_cast<HRESULT>(dwLastError)) {
+        case TRUST_E_NOSIGNATURE:
+          LOG(ERROR) << "No signature found for " << binary_path.value()
+                     << ". ErrorReason: 0x" << std::hex << dwLastError;
+          break;
+        case TRUST_E_SUBJECT_FORM_UNKNOWN:
+          LOG(ERROR) << "The trust provider does not support the form "
+                     << "specified for the subject for " << binary_path.value()
+                     << ". ErrorReason: 0x" << std::hex << dwLastError;
+          break;
+        case TRUST_E_PROVIDER_UNKNOWN:
+          LOG(ERROR) << "The trust provider is not recognized on this system "
+                     << "for " << binary_path.value() << ". ErrorReason: 0x"
+                     << std::hex << dwLastError;
+          break;
+        default:
+          // The signature was not valid or there was an error opening the file.
+          LOG(ERROR) << "Could not verify signature for " << binary_path.value()
+                     << ". ErrorReason: " << dwLastError << ", 0x" << std::hex
+                     << dwLastError;
+          break;
+      }
+      return false;
+
+    case TRUST_E_EXPLICIT_DISTRUST:
+      // The hash that represents the subject or the publisher is not allowed by
+      // the admin or user.
+      LOG(ERROR) << "Signature for " << binary_path.value() << " is present, "
+                 << "but is explicitly distrusted.";
+      return false;
+
+    case TRUST_E_SUBJECT_NOT_TRUSTED:
+      LOG(ERROR) << "Signature for " << binary_path.value() << " is present, "
+                 << "but not trusted.";
+      return false;
+
+    case CRYPT_E_SECURITY_SETTINGS:
+      LOG(ERROR) << "Verification failed for " << binary_path.value() << ". "
+                 << "The hash representing the subject or the publisher wasn't "
+                 << "explicitly trusted by the admin and admin policy has "
+                 << "disabled user trust. No signature, publisher or timestamp "
+                 << "errors.";
+      return false;
+
+    default:
+      LOG(ERROR) << "Signature verification error for " << binary_path.value()
+                 << ": 0x" << std::hex << trust_status;
+      return false;
+  }
+#else
+  // Binaries are only signed in official builds so running the code above for
+  // local builds won't work w/o setting up a test certificate and signing the
+  // binaries using it. To simplify local development, bypass the signature
+  // checks.
+  return true;
+#endif
+}
+
+}  // namespace remoting
diff --git a/remoting/host/win/trust_util.h b/remoting/host/win/trust_util.h
new file mode 100644
index 0000000..9533a7d
--- /dev/null
+++ b/remoting/host/win/trust_util.h
@@ -0,0 +1,19 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_WIN_TRUST_UTIL_H_
+#define REMOTING_HOST_WIN_TRUST_UTIL_H_
+
+#include "base/files/file_path.h"
+
+namespace remoting {
+
+// Validates the signature for the provided |binary_path| and returns true if
+// the binary is trusted. Note that this always returns true on non-official
+// builds.
+bool IsBinaryTrusted(const base::FilePath& binary_path);
+
+}  // namespace remoting
+
+#endif  // REMOTING_HOST_WIN_TRUST_UTIL_H_
diff --git a/remoting/ios/app/app_delegate.mm b/remoting/ios/app/app_delegate.mm
index 5ced2cd5..411cce2 100644
--- a/remoting/ios/app/app_delegate.mm
+++ b/remoting/ios/app/app_delegate.mm
@@ -32,10 +32,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
-static NSString* const kTosUrl = @"https://policies.google.com/terms";
-static NSString* const kPrivacyPolicyUrl =
-    @"https://policies.google.com/privacy";
-
 @interface AppDelegate ()<FirstLaunchViewControllerDelegate> {
   FirstLaunchViewPresenter* _firstLaunchViewPresenter;
 }
diff --git a/remoting/ios/app/help_view_controller.h b/remoting/ios/app/help_view_controller.h
index bd081fd..9165cae 100644
--- a/remoting/ios/app/help_view_controller.h
+++ b/remoting/ios/app/help_view_controller.h
@@ -5,12 +5,11 @@
 #ifndef REMOTING_IOS_APP_HELP_VIEW_CONTROLLER_H_
 #define REMOTING_IOS_APP_HELP_VIEW_CONTROLLER_H_
 
+#import <SafariServices/SafariServices.h>
 #import <UIKit/UIKit.h>
 
-#import "remoting/ios/app/web_view_controller.h"
-
 // A VC that shows the help center.
-@interface HelpViewController : WebViewController
+@interface HelpViewController : SFSafariViewController
 
 - (instancetype)init;
 
diff --git a/remoting/ios/app/help_view_controller.mm b/remoting/ios/app/help_view_controller.mm
index 27aec65..aa9215f 100644
--- a/remoting/ios/app/help_view_controller.mm
+++ b/remoting/ios/app/help_view_controller.mm
@@ -9,6 +9,7 @@
 #import "remoting/ios/app/help_view_controller.h"
 
 #include "remoting/base/string_resources.h"
+#import "remoting/ios/app/web_view_controller.h"
 #include "ui/base/l10n/l10n_util.h"
 
 // TODO(nicholss): These urls should come from a global config.
@@ -22,9 +23,9 @@
 @implementation HelpViewController
 
 - (instancetype)init {
-  if (self = [super
-          initWithUrl:kHelpCenterUrl
-                title:l10n_util::GetNSString(IDS_ACTIONBAR_HELP_TITLE)]) {
+  if (self = [super initWithURL:[NSURL URLWithString:kHelpCenterUrl]]) {
+    self.navigationItem.title =
+        l10n_util::GetNSString(IDS_ACTIONBAR_HELP_TITLE);
     self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
         initWithTitle:l10n_util::GetNSString(IDS_CREDITS)
                 style:UIBarButtonItemStylePlain
diff --git a/remoting/protocol/audio_pump_unittest.cc b/remoting/protocol/audio_pump_unittest.cc
index 5a5d428f..b432cba4 100644
--- a/remoting/protocol/audio_pump_unittest.cc
+++ b/remoting/protocol/audio_pump_unittest.cc
@@ -10,7 +10,6 @@
 #include <utility>
 #include <vector>
 
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -172,7 +171,7 @@
     AudioPacket::CHANNELS_MONO,
   };
 
-  for (size_t i = 0; i < base::size(kChannels); i++) {
+  for (size_t i = 0; i < std::size(kChannels); i++) {
     source_->callback().Run(MakeAudioPacket(kChannels[i]));
     // Run message loop to let the pump processes the audio packet and send it
     // to the encoder.
@@ -184,7 +183,7 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  ASSERT_EQ(sent_packets_.size(), base::size(kChannels));
+  ASSERT_EQ(sent_packets_.size(), std::size(kChannels));
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/capture_scheduler_unittest.cc b/remoting/protocol/capture_scheduler_unittest.cc
index 7f236b64..d9a8930 100644
--- a/remoting/protocol/capture_scheduler_unittest.cc
+++ b/remoting/protocol/capture_scheduler_unittest.cc
@@ -10,7 +10,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/simple_test_tick_clock.h"
@@ -88,15 +87,15 @@
 };
 
 TEST_F(CaptureSchedulerTest, SingleSampleSameTimes) {
-  const int kTestResults[][base::size(kTestInputs)] = {
+  const int kTestResults[][std::size(kTestInputs)] = {
       {400, 200, 120, 80, 50, 120, 240, 320},  // One core.
       {200, 100, 60, 50, 50, 60, 120, 160},    // Two cores.
       {100, 50, 50, 50, 50, 50, 60, 80},       // Four cores.
       {50, 50, 50, 50, 50, 50, 50, 50}         // Eight cores.
   };
 
-  for (size_t i = 0; i < base::size(kTestResults); ++i) {
-    for (size_t j = 0; j < base::size(kTestInputs); ++j) {
+  for (size_t i = 0; i < std::size(kTestResults); ++i) {
+    for (size_t j = 0; j < std::size(kTestInputs); ++j) {
       InitScheduler();
       scheduler_->SetNumOfProcessorsForTest(1 << i);
 
@@ -108,41 +107,41 @@
 }
 
 TEST_F(CaptureSchedulerTest, SingleSampleDifferentTimes) {
-  const int kTestResults[][base::size(kTestInputs)] = {
+  const int kTestResults[][std::size(kTestInputs)] = {
       {360, 220, 120, 60, 60, 120, 220, 360},  // One core.
       {180, 110, 60, 50, 50, 60, 110, 180},    // Two cores.
       {90, 55, 50, 50, 50, 50, 55, 90},        // Four cores.
       {50, 50, 50, 50, 50, 50, 50, 50}         // Eight cores.
   };
 
-  for (size_t i = 0; i < base::size(kTestResults); ++i) {
-    for (size_t j = 0; j < base::size(kTestInputs); ++j) {
+  for (size_t i = 0; i < std::size(kTestResults); ++i) {
+    for (size_t j = 0; j < std::size(kTestInputs); ++j) {
       InitScheduler();
       scheduler_->SetNumOfProcessorsForTest(1 << i);
 
       SimulateSingleFrameCapture(
           base::Milliseconds(kTestInputs[j]),
-          base::Milliseconds(kTestInputs[base::size(kTestInputs) - 1 - j]),
+          base::Milliseconds(kTestInputs[std::size(kTestInputs) - 1 - j]),
           base::Milliseconds(kTestResults[i][j]));
     }
   }
 }
 
 TEST_F(CaptureSchedulerTest, RollingAverageDifferentTimes) {
-  const double kTestResults[][base::size(kTestInputs)] = {
+  const double kTestResults[][std::size(kTestInputs)] = {
       {360, 290, 233.333, 133.333, 80, 80, 133.333, 233.333},  // One core.
       {180, 145, 116.666, 66.666, 50, 50, 66.666, 116.666},    // Two cores.
       {90, 72.5, 58.333, 50, 50, 50, 50, 58.333},              // Four cores.
       {50, 50, 50, 50, 50, 50, 50, 50}                         // Eight cores.
   };
 
-  for (size_t i = 0; i < base::size(kTestResults); ++i) {
+  for (size_t i = 0; i < std::size(kTestResults); ++i) {
     InitScheduler();
     scheduler_->SetNumOfProcessorsForTest(1 << i);
-    for (size_t j = 0; j < base::size(kTestInputs); ++j) {
+    for (size_t j = 0; j < std::size(kTestInputs); ++j) {
       SimulateSingleFrameCapture(
           base::Milliseconds(kTestInputs[j]),
-          base::Milliseconds(kTestInputs[base::size(kTestInputs) - 1 - j]),
+          base::Milliseconds(kTestInputs[std::size(kTestInputs) - 1 - j]),
           base::Milliseconds(kTestResults[i][j]));
     }
   }
diff --git a/remoting/protocol/jingle_messages_unittest.cc b/remoting/protocol/jingle_messages_unittest.cc
index 0251b59..d7513798 100644
--- a/remoting/protocol/jingle_messages_unittest.cc
+++ b/remoting/protocol/jingle_messages_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_util.h"
 #include "remoting/protocol/content_description.h"
 #include "remoting/signaling/xmpp_constants.h"
@@ -480,7 +479,7 @@
        kTestIncomingMessage2},
   };
 
-  for (size_t i = 0; i < base::size(tests); ++i) {
+  for (size_t i = 0; i < std::size(tests); ++i) {
     std::unique_ptr<XmlElement> incoming_message(
         XmlElement::ForStr(tests[i].incoming_message));
     ASSERT_TRUE(incoming_message.get());
diff --git a/remoting/protocol/message_decoder_unittest.cc b/remoting/protocol/message_decoder_unittest.cc
index c9049b0..7eb73f8 100644
--- a/remoting/protocol/message_decoder_unittest.cc
+++ b/remoting/protocol/message_decoder_unittest.cc
@@ -10,7 +10,6 @@
 #include <memory>
 #include <string>
 
-#include "base/cxx17_backports.h"
 #include "base/strings/string_number_conversions.h"
 #include "remoting/proto/event.pb.h"
 #include "remoting/proto/internal.pb.h"
@@ -109,17 +108,17 @@
 
 TEST(MessageDecoderTest, SmallReads) {
   const int kReads[] = {1, 2, 3, 1};
-  SimulateReadSequence(kReads, base::size(kReads));
+  SimulateReadSequence(kReads, std::size(kReads));
 }
 
 TEST(MessageDecoderTest, LargeReads) {
   const int kReads[] = {50, 50, 5};
-  SimulateReadSequence(kReads, base::size(kReads));
+  SimulateReadSequence(kReads, std::size(kReads));
 }
 
 TEST(MessageDecoderTest, EmptyReads) {
   const int kReads[] = {4, 0, 50, 0};
-  SimulateReadSequence(kReads, base::size(kReads));
+  SimulateReadSequence(kReads, std::size(kReads));
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/mouse_input_filter_unittest.cc b/remoting/protocol/mouse_input_filter_unittest.cc
index 4a81dab..0760373 100644
--- a/remoting/protocol/mouse_input_filter_unittest.cc
+++ b/remoting/protocol/mouse_input_filter_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "remoting/protocol/mouse_input_filter.h"
 
-#include "base/cxx17_backports.h"
 #include "remoting/proto/event.pb.h"
 #include "remoting/protocol/protocol_mock_objects.h"
 #include "remoting/protocol/test_event_matchers.h"
@@ -143,7 +142,7 @@
 
   const Point injected[] = {{1, 1}};
   const Point expected[] = {{1, 1}};
-  RunMouseTests(base::size(expected), injected, expected, true);
+  RunMouseTests(std::size(expected), injected, expected, true);
 }
 
 // Verify that no events get through if negative dimensions are provided.
@@ -165,7 +164,7 @@
   const Point expected[] = {{0, 10},  {0, 10},  {0, 10}, {15, 39},
                             {15, 39}, {15, 39}, {15, 25}};
 
-  RunMouseTests(base::size(expected), injected, expected, true);
+  RunMouseTests(std::size(expected), injected, expected, true);
 }
 
 // Verify that we can up-scale with clamping.
@@ -178,7 +177,7 @@
   const Point expected[] = {{0, 20},  {0, 20},  {0, 20}, {30, 79},
                             {30, 79}, {30, 79}, {30, 51}};
 
-  RunMouseTests(base::size(expected), injected, expected, true);
+  RunMouseTests(std::size(expected), injected, expected, true);
 }
 
 // Verify that we can down-scale with clamping.
@@ -191,7 +190,7 @@
   const Point expected[] = {{0, 7},   {0, 7},   {0, 7},  {11, 29},
                             {11, 29}, {11, 29}, {11, 19}};
 
-  RunMouseTests(base::size(expected), injected, expected, true);
+  RunMouseTests(std::size(expected), injected, expected, true);
 }
 
 // Multimon tests
@@ -214,7 +213,7 @@
   const Point expected[] = {
       {11, 13}, {1949, 465}, {3816, 2078}, {5209, 124}, {6366, 1111}};
 
-  RunMouseTests(base::size(expected), injected, expected);
+  RunMouseTests(std::size(expected), injected, expected);
 }
 
 TEST_F(MouseInputFilterTest, MultimonLeftDefault_ShowLeftDisplay) {
@@ -224,7 +223,7 @@
   const Point injected[] = {{12, 25}, {2011, 1099}};
   const Point expected[] = {{15, 31}, {2514, 1374}};
 
-  RunMouseTests(base::size(expected), injected, expected);
+  RunMouseTests(std::size(expected), injected, expected);
 }
 
 TEST_F(MouseInputFilterTest, MultimonLeftDefault_ShowRightDisplay) {
@@ -234,7 +233,7 @@
   const Point injected[] = {{175, 165}, {2948, 1532}};
   const Point expected[] = {{2779, 206}, {6245, 1915}};
 
-  RunMouseTests(base::size(expected), injected, expected);
+  RunMouseTests(std::size(expected), injected, expected);
 }
 
 // Default display = Right (A)
@@ -253,7 +252,7 @@
   const Point injected[] = {{64, 61}, {3029, 1649}};
   const Point expected[] = {{80, 76}, {3786, 2061}};
 
-  RunMouseTests(base::size(expected), injected, expected);
+  RunMouseTests(std::size(expected), injected, expected);
 }
 
 TEST_F(MouseInputFilterTest, MultimonRightDefault_ShowRightDisplay) {
@@ -263,7 +262,7 @@
   const Point injected[] = {{19, 20}, {2014, 1095}};
   const Point expected[] = {{3864, 25}, {6358, 1369}};
 
-  RunMouseTests(base::size(expected), injected, expected);
+  RunMouseTests(std::size(expected), injected, expected);
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/pairing_registry.cc b/remoting/protocol/pairing_registry.cc
index 3cc4361d..905d698 100644
--- a/remoting/protocol/pairing_registry.cc
+++ b/remoting/protocol/pairing_registry.cc
@@ -10,7 +10,6 @@
 
 #include "base/base64.h"
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/guid.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/location.h"
@@ -54,8 +53,8 @@
   std::string client_id = base::GenerateGUID();
   std::string shared_secret;
   char buffer[kKeySize];
-  crypto::RandBytes(buffer, base::size(buffer));
-  base::Base64Encode(base::StringPiece(buffer, base::size(buffer)),
+  crypto::RandBytes(buffer, std::size(buffer));
+  base::Base64Encode(base::StringPiece(buffer, std::size(buffer)),
                      &shared_secret);
   return Pairing(created_time, client_name, client_id, shared_secret);
 }
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper.cc b/remoting/protocol/webrtc_video_encoder_wrapper.cc
index 634d397..91f84a3 100644
--- a/remoting/protocol/webrtc_video_encoder_wrapper.cc
+++ b/remoting/protocol/webrtc_video_encoder_wrapper.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/cxx17_backports.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/bind_post_task.h"
@@ -335,7 +334,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   const uint8_t* buffer =
-      reinterpret_cast<const uint8_t*>(base::data(frame.data));
+      reinterpret_cast<const uint8_t*>(std::data(frame.data));
   size_t buffer_size = frame.data.size();
 
   // TODO(crbug.com/1208215): Avoid copying/allocating frame data here, by
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 219ea3f..6f30b0e 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1505,6 +1505,15 @@
       update_time, std::move(disqualified_logs),
       std::move(operated_by_google_logs), std::move(log_operator_history));
 }
+
+void NetworkContext::CanSendSCTAuditingReport(
+    base::OnceCallback<void(bool)> callback) {
+  client_->OnCanSendSCTAuditingReport(std::move(callback));
+}
+
+void NetworkContext::OnNewSCTAuditingReportSent() {
+  client_->OnNewSCTAuditingReportSent();
+}
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
 
 void NetworkContext::CreateUDPSocket(
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 6de8167..01befea8 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -310,6 +310,8 @@
   SCTAuditingHandler* sct_auditing_handler() {
     return sct_auditing_handler_.get();
   }
+  void CanSendSCTAuditingReport(base::OnceCallback<void(bool)> callback);
+  void OnNewSCTAuditingReportSent();
 #endif  // BUILDFLAG(IS_CT_SUPPORTED)
   void CreateUDPSocket(
       mojo::PendingReceiver<mojom::UDPSocket> receiver,
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 3d5779c9..0b1afd4 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -795,6 +795,20 @@
   // response structs' comments for more information).
   OnTrustTokenIssuanceDivertedToSystem(FulfillTrustTokenIssuanceRequest request)
     => (FulfillTrustTokenIssuanceAnswer response);
+
+  // Checks if a new SCT Auditing report can be sent. The browser maintains a
+  // maximum report count cap for Hashdance clients -- this returns whether the
+  // cap has been exceeded or not (i.e., whether another report can be sent from
+  // this client). Only used for SCT auditing "hashdance" clients; no report cap
+  // is applied for SBER clients.
+  [EnableIf=is_ct_supported]
+  OnCanSendSCTAuditingReport() => (bool allowed);
+
+  // Signal that a new SCT auditing report has been sent, so that the browser
+  // can update its report count. Only used for SCT auditing "hashdance"
+  // clients.
+  [EnableIf=is_ct_supported]
+  OnNewSCTAuditingReportSent();
 };
 
 // Represents a distinct context for making network requests, with its own
diff --git a/services/network/sct_auditing/sct_auditing_handler.cc b/services/network/sct_auditing/sct_auditing_handler.cc
index 5258f8c..40425e8 100644
--- a/services/network/sct_auditing/sct_auditing_handler.cc
+++ b/services/network/sct_auditing/sct_auditing_handler.cc
@@ -316,7 +316,7 @@
       sct_auditing_cache->hashdance_traffic_annotation();
 
   auto reporter = std::make_unique<SCTAuditingReporter>(
-      reporter_key, std::move(report),
+      owner_network_context_, reporter_key, std::move(report),
       mode_ == mojom::SCTAuditingMode::kHashdance, std::move(sct_metadata),
       GetURLLoaderFactory(), log_expected_ingestion_delay,
       log_max_ingestion_random_delay, report_uri, hashdance_lookup_uri,
diff --git a/services/network/sct_auditing/sct_auditing_handler_unittest.cc b/services/network/sct_auditing/sct_auditing_handler_unittest.cc
index 530806e..4cc81b3 100644
--- a/services/network/sct_auditing/sct_auditing_handler_unittest.cc
+++ b/services/network/sct_auditing/sct_auditing_handler_unittest.cc
@@ -31,6 +31,7 @@
 #include "services/network/sct_auditing/sct_auditing_cache.h"
 #include "services/network/sct_auditing/sct_auditing_reporter.h"
 #include "services/network/test/fake_test_cert_verifier_params_factory.h"
+#include "services/network/test/test_network_context_client.h"
 #include "services/network/test/test_url_loader_factory.h"
 #include "services/network/test/test_utils.h"
 #include "services/network/url_loader_factory.h"
@@ -84,6 +85,14 @@
     log_list.emplace_back(std::move(log));
     network_service_->UpdateCtLogList(std::move(log_list), base::Time::Now());
 
+    // A NetworkContextClient is needed for querying/updating the report count.
+    mojo::PendingRemote<network::mojom::NetworkContextClient>
+        network_context_client_remote;
+    network_context_client_ =
+        std::make_unique<network::TestNetworkContextClient>(
+            network_context_client_remote.InitWithNewPipeAndPassReceiver());
+    network_context_->SetClient(std::move(network_context_client_remote));
+
     // Set up SCT auditing configuration.
     auto* cache = network_service_->sct_auditing_cache();
     cache->set_sampling_rate(1.0);
@@ -159,6 +168,7 @@
   base::FilePath persistence_path_;
   std::unique_ptr<NetworkService> network_service_;
   std::unique_ptr<NetworkContext> network_context_;
+  std::unique_ptr<TestNetworkContextClient> network_context_client_;
   scoped_refptr<net::X509Certificate> chain_;
   std::unique_ptr<SCTAuditingHandler> handler_;
   base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/services/network/sct_auditing/sct_auditing_reporter.cc b/services/network/sct_auditing/sct_auditing_reporter.cc
index a057e8e..900a05d 100644
--- a/services/network/sct_auditing/sct_auditing_reporter.cc
+++ b/services/network/sct_auditing/sct_auditing_reporter.cc
@@ -21,6 +21,7 @@
 #include "net/base/request_priority.h"
 #include "net/http/http_status_code.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/network_context.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/simple_url_loader.h"
@@ -59,6 +60,11 @@
 // not nullopt.
 absl::optional<base::TimeDelta> g_retry_delay_for_testing = absl::nullopt;
 
+void RecordLookupQueryResult(SCTAuditingReporter::LookupQueryResult result) {
+  base::UmaHistogramEnumeration("Security.SCTAuditing.OptOut.LookupQueryResult",
+                                result);
+}
+
 // Records whether sending the report to the reporting server succeeded for each
 // report sent.
 void RecordSCTAuditingReportSucceededMetrics(bool success) {
@@ -198,6 +204,7 @@
 }
 
 SCTAuditingReporter::SCTAuditingReporter(
+    NetworkContext* owner_network_context,
     net::HashValue reporter_key,
     std::unique_ptr<sct_auditing::SCTClientReport> report,
     bool is_hashdance,
@@ -212,7 +219,8 @@
     ReporterUpdatedCallback update_callback,
     ReporterDoneCallback done_callback,
     std::unique_ptr<net::BackoffEntry> persisted_backoff_entry)
-    : reporter_key_(reporter_key),
+    : owner_network_context_(owner_network_context),
+      reporter_key_(reporter_key),
       report_(std::move(report)),
       is_hashdance_(is_hashdance),
       sct_hashdance_metadata_(std::move(sct_hashdance_metadata)),
@@ -266,7 +274,28 @@
     return;
   }
 
-  // TODO(nsatragno): Query total number of client reports.
+  // Entrypoint for checking whether the max-reports limit has been reached.
+  // This should only get called once for the lifetime of the Reporter.
+  // TODO(crbug.com/1144205): Once reports are persisted to disk, the Reporter
+  // state should include whether it has been "counted" yet, otherwise if a
+  // Reporter gets persisted and restored many times it would cause the report
+  // cap to trigger. This can likely just be a boolean flag on the Reporter and
+  // the persisted state -- if `true`, this check (and incrementing the report
+  // count) can be skipped.
+  owner_network_context_->CanSendSCTAuditingReport(
+      base::BindOnce(&SCTAuditingReporter::OnCheckReportAllowedStatusComplete,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void SCTAuditingReporter::OnCheckReportAllowedStatusComplete(bool allowed) {
+  if (!allowed) {
+    // The maximum report cap has already been reached. Notify the handler that
+    // this Reporter is done. This will delete `this`, so do not add code after
+    // this point.
+    std::move(done_callback_).Run(reporter_key_);
+    return;
+  }
+
   // Calculate an estimated minimum delay after which the log is expected to
   // have been ingested by the server.
   base::TimeDelta random_delay = base::Seconds(
@@ -340,18 +369,26 @@
   bool success = url_loader_->NetError() == net::OK &&
                  response_code == net::HTTP_OK && response_body;
   if (!success) {
+    RecordLookupQueryResult(LookupQueryResult::kHTTPError);
     MaybeRetryRequest();
     return;
   }
 
   absl::optional<base::Value> result = base::JSONReader::Read(*response_body);
   if (!result) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
 
   const std::string* status = result->FindStringKey(kLookupStatusKey);
-  if (!status || *status != kStatusOK) {
+  if (!status) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
+    MaybeRetryRequest();
+    return;
+  }
+  if (*status != kStatusOK) {
+    RecordLookupQueryResult(LookupQueryResult::kStatusNotOk);
     MaybeRetryRequest();
     return;
   }
@@ -359,6 +396,7 @@
   const std::string* server_timestamp_string =
       result->FindStringKey(kLookupTimestampKey);
   if (!server_timestamp_string) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
@@ -366,12 +404,14 @@
   base::Time server_timestamp;
   if (!base::Time::FromUTCString(server_timestamp_string->c_str(),
                                  &server_timestamp)) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
 
   if (sct_hashdance_metadata_->certificate_expiry < server_timestamp) {
     // The certificate has expired. Do not report.
+    RecordLookupQueryResult(LookupQueryResult::kCertificateExpired);
     std::move(done_callback_).Run(reporter_key_);
     return;
   }
@@ -379,6 +419,7 @@
   // Find the corresponding log entry.
   const base::Value* logs = result->FindListKey(kLookupLogStatusKey);
   if (!logs) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
@@ -388,6 +429,7 @@
     const std::string* encoded_log_id = log.FindStringKey(kLookupLogIdKey);
     std::string log_id;
     if (!encoded_log_id || !base::Base64Decode(*encoded_log_id, &log_id)) {
+      RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
       MaybeRetryRequest();
       return;
     }
@@ -399,6 +441,7 @@
   if (!found_log) {
     // We could not find the SCT's log. Maybe it's a new log that the server
     // doesn't know about yet, schedule a retry.
+    RecordLookupQueryResult(LookupQueryResult::kLogNotFound);
     MaybeRetryRequest();
     return;
   }
@@ -406,6 +449,7 @@
   const std::string* ingested_until_string =
       found_log->FindStringKey(kLookupIngestedUntilKey);
   if (!ingested_until_string) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
@@ -413,18 +457,21 @@
   base::Time ingested_until;
   if (!base::Time::FromString(ingested_until_string->c_str(),
                               &ingested_until)) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
 
   if (sct_hashdance_metadata_->issued > ingested_until) {
     // The log has not yet ingested this SCT. Schedule a retry.
+    RecordLookupQueryResult(LookupQueryResult::kLogNotYetIngested);
     MaybeRetryRequest();
     return;
   }
 
   const base::Value* suffix_value = result->FindListKey(kLookupHashSuffixKey);
   if (!suffix_value) {
+    RecordLookupQueryResult(LookupQueryResult::kInvalidJson);
     MaybeRetryRequest();
     return;
   }
@@ -442,11 +489,15 @@
   if (std::find(suffixes.begin(), suffixes.end(), hash_suffix_value) !=
       suffixes.end()) {
     // Found the SCT in the suffix list, all done.
+    RecordLookupQueryResult(LookupQueryResult::kSCTSuffixFound);
     std::move(done_callback_).Run(reporter_key_);
     return;
   }
 
-  // The server does not know about this SCT, and it should. Notify the server.
+  // The server does not know about this SCT, and it should. Notify the
+  // embedder and start sending the full report.
+  owner_network_context_->OnNewSCTAuditingReportSent();
+  RecordLookupQueryResult(LookupQueryResult::kSCTSuffixNotFound);
   SendReport();
 }
 
diff --git a/services/network/sct_auditing/sct_auditing_reporter.h b/services/network/sct_auditing/sct_auditing_reporter.h
index 9ec8787..36dec761 100644
--- a/services/network/sct_auditing/sct_auditing_reporter.h
+++ b/services/network/sct_auditing/sct_auditing_reporter.h
@@ -28,6 +28,7 @@
 
 namespace network {
 
+class NetworkContext;
 class SimpleURLLoader;
 
 // Owns an SCT auditing report and handles sending it and retrying on failures.
@@ -88,7 +89,50 @@
     base::Time certificate_expiry;
   };
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class LookupQueryResult {
+    // Indicates a network status other than 200 OK.
+    kHTTPError = 0,
+
+    // The content returned by the server either did not parse as valid JSON or
+    // was missing required fields.
+    kInvalidJson = 1,
+
+    // The server returned a `responseStatus` field other than "OK".
+    kStatusNotOk = 2,
+
+    // The certificate has expired according to the timestamp returned by the
+    // server.
+    kCertificateExpired = 3,
+
+    // The server does not know about the log corresponding to the SCT.
+    kLogNotFound = 4,
+
+    // The log has not yet ingested the SCT.
+    kLogNotYetIngested = 5,
+
+    // The SCT suffix was found in the suffix list, so it should not be
+    // reported.
+    kSCTSuffixFound = 6,
+
+    // The SCT suffix was NOT found in the suffix list, so it should be
+    // reported.
+    kSCTSuffixNotFound = 7,
+    kMaxValue = kSCTSuffixNotFound,
+  };
+
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class CompletionStatus {
+    kSuccessFirstTry = 0,
+    kSuccessAfterRetries = 1,
+    kRetriesExhausted = 2,
+    kMaxValue = kRetriesExhausted,
+  };
+
   SCTAuditingReporter(
+      NetworkContext* owner_network_context_,
       net::HashValue reporter_key,
       std::unique_ptr<sct_auditing::SCTClientReport> report,
       bool is_hashdance,
@@ -120,18 +164,10 @@
     return sct_hashdance_metadata_;
   }
 
-  // These values are persisted to logs. Entries should not be renumbered and
-  // numeric values should never be reused.
-  enum class CompletionStatus {
-    kSuccessFirstTry = 0,
-    kSuccessAfterRetries = 1,
-    kRetriesExhausted = 2,
-    kMaxValue = kRetriesExhausted,
-  };
-
   static void SetRetryDelayForTesting(absl::optional<base::TimeDelta> delay);
 
  private:
+  void OnCheckReportAllowedStatusComplete(bool allowed);
   // Schedules a |request| using the backoff delay or |minimum_delay|, whichever
   // is greatest.
   void ScheduleRequestWithBackoff(base::OnceClosure request,
@@ -142,6 +178,10 @@
   void OnSendReportComplete(scoped_refptr<net::HttpResponseHeaders> headers);
   void MaybeRetryRequest();
 
+  // The NetworkContext which owns the SCTAuditingHandler that created this
+  // Reporter.
+  NetworkContext* owner_network_context_;
+
   net::HashValue reporter_key_;
   std::unique_ptr<sct_auditing::SCTClientReport> report_;
   bool is_hashdance_;
diff --git a/services/network/sct_auditing/sct_auditing_reporter_unittest.cc b/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
index 7e79eb5..4090165 100644
--- a/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
+++ b/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/callback_helpers.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/bind.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/time/clock.h"
@@ -15,9 +16,14 @@
 #include "base/time/time_to_iso8601.h"
 #include "net/base/hash_value.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/network_context.h"
+#include "services/network/network_service.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/proto/sct_audit_report.pb.h"
+#include "services/network/test/fake_test_cert_verifier_params_factory.h"
+#include "services/network/test/test_network_context_client.h"
 #include "services/network/test/test_url_loader_factory.h"
+#include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace network {
@@ -58,7 +64,8 @@
     base::Time now;
   };
 
-  SCTAuditingReporterTest() {
+  SCTAuditingReporterTest()
+      : network_service_(NetworkService::CreateForTesting()) {
     SCTAuditingReporter::SetRetryDelayForTesting(base::TimeDelta());
 
     reporter_metadata_.issued = base::Time::Now() - base::Days(30);
@@ -70,6 +77,25 @@
 
     response_.ingested_until = base::Time::Now();
     response_.now = base::Time::Now();
+
+    // Set up a NetworkContext.
+    mojom::NetworkContextParamsPtr context_params =
+        CreateNetworkContextParamsForTesting();
+    context_params->cert_verifier_params =
+        FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
+    context_params->sct_auditing_mode =
+        mojom::SCTAuditingMode::kEnhancedSafeBrowsingReporting;
+    network_context_ = std::make_unique<NetworkContext>(
+        network_service_.get(),
+        network_context_remote_.BindNewPipeAndPassReceiver(),
+        std::move(context_params));
+
+    // A NetworkContextClient is needed for querying/updating the report count.
+    mojo::PendingRemote<network::mojom::NetworkContextClient>
+        network_context_client_remote;
+    network_context_client_ = std::make_unique<TestNetworkContextClient>(
+        network_context_client_remote.InitWithNewPipeAndPassReceiver());
+    network_context_->SetClient(std::move(network_context_client_remote));
   }
 
   // Creates a reporter.
@@ -88,7 +114,7 @@
         *SCTAuditingReporter::SCTHashdanceMetadata::FromValue(
             reporter_metadata_.ToValue());
     return SCTAuditingReporter(
-        net::HashValue(), std::move(report),
+        network_context_.get(), net::HashValue(), std::move(report),
         /*is_hashdance=*/true, std::move(metadata), &url_loader_factory_,
         kExpectedIngestionDelay, kMaxIngestionRandomDelay, GURL(kTestReportURL),
         GURL(kTestLookupURL),
@@ -130,17 +156,26 @@
             nullptr));
   }
 
-  base::test::SingleThreadTaskEnvironment task_environment_{
-      base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME,
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::IO,
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME,
   };
 
+  std::unique_ptr<NetworkService> network_service_;
+  std::unique_ptr<NetworkContext> network_context_;
+  std::unique_ptr<TestNetworkContextClient> network_context_client_;
   TestURLLoaderFactory url_loader_factory_;
+  base::HistogramTester histograms;
 
   // Metadata used when creating a repoter.
   SCTAuditingReporter::SCTHashdanceMetadata reporter_metadata_;
 
   Response response_;
 
+  // Stores the mojo::Remote<mojom::NetworkContext> of the most recently created
+  // NetworkContext.
+  mojo::Remote<mojom::NetworkContext> network_context_remote_;
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_{
       features::kSCTAuditingRetryReports,
@@ -251,6 +286,9 @@
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
   pending_request = url_loader_factory_.GetPendingRequest(0);
   EXPECT_EQ(pending_request->request.url.spec(), kTestReportURL);
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kSCTSuffixNotFound, 1);
 }
 
 // Tests that a hashdance lookup that finds the SCT does not report it.
@@ -271,6 +309,9 @@
 
   // SCT should not be reported.
   EXPECT_EQ(url_loader_factory_.NumPending(), 0);
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kSCTSuffixFound, 1);
 }
 
 // Tests that a hashdance lookup with a server error retries.
@@ -286,6 +327,9 @@
   // Respond to the lookup request with an error.
   response_.status = "ERROR";
   SimulateResponse();
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kStatusNotOk, 1);
 
   // A retry should be rescheduled.
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
@@ -316,6 +360,9 @@
   url_loader_factory_.SimulateResponseForPendingRequest(
       pending_request->request.url.spec(), /*content=*/"",
       net::HTTP_TOO_MANY_REQUESTS);
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kHTTPError, 1);
 
   // A retry should be rescheduled.
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
@@ -348,6 +395,9 @@
 
   // SCT should not be reported.
   EXPECT_EQ(url_loader_factory_.NumPending(), 0);
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kCertificateExpired, 1);
 }
 
 // Tests that a hashdance lookup that does not return the SCT Log ID gets
@@ -364,6 +414,9 @@
   // Respond to the lookup request with a different log id.
   response_.log_id = "some_other_log";
   SimulateResponse();
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kLogNotFound, 1);
 
   // A retry should be rescheduled.
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
@@ -394,6 +447,9 @@
   // Respond to the lookup request with a too early `ingested_until`.
   response_.ingested_until = reporter_metadata_.issued - base::Seconds(1);
   SimulateResponse();
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kLogNotYetIngested, 1);
 
   // A retry should be rescheduled.
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
@@ -437,6 +493,9 @@
   EXPECT_EQ(url_loader_factory_.NumPending(), 1);
   pending_request = url_loader_factory_.GetPendingRequest(0);
   EXPECT_EQ(pending_request->request.url.spec(), kTestReportURL);
+  histograms.ExpectUniqueSample(
+      "Security.SCTAuditing.OptOut.LookupQueryResult",
+      SCTAuditingReporter::LookupQueryResult::kSCTSuffixNotFound, 1);
 }
 
 }  // namespace network
diff --git a/services/network/test/test_network_context_client.cc b/services/network/test/test_network_context_client.cc
index 5c6036b..87abe13 100644
--- a/services/network/test/test_network_context_client.cc
+++ b/services/network/test/test_network_context_client.cc
@@ -52,4 +52,11 @@
   std::move(callback).Run(net::OK, std::move(files));
 }
 
+#if BUILDFLAG(IS_CT_SUPPORTED)
+void TestNetworkContextClient::OnCanSendSCTAuditingReport(
+    OnCanSendSCTAuditingReportCallback callback) {
+  std::move(callback).Run(true);
+}
+#endif
+
 }  // namespace network
diff --git a/services/network/test/test_network_context_client.h b/services/network/test/test_network_context_client.h
index 5a5aa08..d72b968 100644
--- a/services/network/test/test_network_context_client.h
+++ b/services/network/test/test_network_context_client.h
@@ -53,6 +53,9 @@
   void OnTrustAnchorUsed() override {}
 #endif
 #if BUILDFLAG(IS_CT_SUPPORTED)
+  void OnCanSendSCTAuditingReport(
+      OnCanSendSCTAuditingReportCallback callback) override;
+  void OnNewSCTAuditingReportSent() override {}
 #endif
   void OnTrustTokenIssuanceDivertedToSystem(
       mojom::FulfillTrustTokenIssuanceRequestPtr request,
diff --git a/services/tracing/public/cpp/stack_sampling/stack_sampler_android.cc b/services/tracing/public/cpp/stack_sampling/stack_sampler_android.cc
index 2d4de082..a16f0fe 100644
--- a/services/tracing/public/cpp/stack_sampling/stack_sampler_android.cc
+++ b/services/tracing/public/cpp/stack_sampling/stack_sampler_android.cc
@@ -27,7 +27,8 @@
 
 void StackSamplerAndroid::RecordStackFrames(
     base::StackBuffer* stack_buffer,
-    base::ProfileBuilder* profile_builder) {
+    base::ProfileBuilder* profile_builder,
+    base::PlatformThreadId thread_id) {
   if (!unwinder_.is_initialized()) {
     // May block on disk access. This function is executed on the profiler
     // thread, so this will only block profiling execution.
diff --git a/services/tracing/public/cpp/stack_sampling/stack_sampler_android.h b/services/tracing/public/cpp/stack_sampling/stack_sampler_android.h
index 02b10262..f33e00e 100644
--- a/services/tracing/public/cpp/stack_sampling/stack_sampler_android.h
+++ b/services/tracing/public/cpp/stack_sampling/stack_sampler_android.h
@@ -31,7 +31,8 @@
   // StackSampler:
   void AddAuxUnwinder(std::unique_ptr<base::Unwinder> unwinder) override;
   void RecordStackFrames(base::StackBuffer* stack_buffer,
-                         base::ProfileBuilder* profile_builder) override;
+                         base::ProfileBuilder* profile_builder,
+                         base::PlatformThreadId thread_id) override;
 
  private:
   base::SamplingProfilerThreadToken thread_token_;
diff --git a/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc b/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
index cc58f4f5..ca843b55 100644
--- a/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
+++ b/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc
@@ -768,7 +768,7 @@
 #elif ANDROID_CFI_UNWINDING_SUPPORTED
   auto* module_cache = profile_builder->GetModuleCache();
   profiler_ = std::make_unique<base::StackSamplingProfiler>(
-      params, std::move(profile_builder),
+      sampled_thread_token_, params, std::move(profile_builder),
       std::make_unique<StackSamplerAndroid>(sampled_thread_token_,
                                             module_cache));
   profiler_->Start();
diff --git a/sql/database.cc b/sql/database.cc
index 7df95da..3f9e935 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -1608,14 +1608,6 @@
                           options_.enable_views_discouraged ? 1 : 0, nullptr);
   DCHECK_EQ(err, SQLITE_OK) << "sqlite3_db_config() should not fail";
 
-  // Enable extended result codes to provide more color on I/O errors.
-  // Not having extended result codes is not a fatal problem, as
-  // Chromium code does not attempt to handle I/O errors anyhow.  The
-  // current implementation always returns SQLITE_OK, the DCHECK is to
-  // quickly notify someone if SQLite changes.
-  err = sqlite3_extended_result_codes(db_, 1);
-  DCHECK_EQ(err, SQLITE_OK) << "Could not enable extended result codes";
-
   // sqlite3_open() does not actually read the database file (unless a hot
   // journal is found).  Successfully executing this pragma on an existing
   // database requires a valid header on page 1.  ExecuteAndReturnErrorCode() to
@@ -1834,37 +1826,65 @@
 bool Database::FullIntegrityCheck(std::vector<std::string>* messages) {
   messages->clear();
 
-  // This has the side effect of setting SQLITE_RecoveryMode, which
+  // The PRAGMA below has the side effect of setting SQLITE_RecoveryMode, which
   // allows SQLite to process through certain cases of corruption.
-  // Failing to set this pragma probably means that the database is
-  // beyond recovery.
-  if (!Execute("PRAGMA writable_schema=ON"))
-    return false;
-
-  bool success;
-  {
-    sql::Statement statement(GetUniqueStatement("PRAGMA integrity_check"));
-
-    // "PRAGMA integrity_check" currently returns multiple lines as a single
-    // row.
-    //
-    // However, since https://www.sqlite.org/pragma.html#pragma_integrity_check
-    // states that multiple records may be returned, the code below can handle
-    // multiple records, each of which has multiple lines.
-    std::vector<std::string> result_lines;
-    while (statement.Step()) {
-      std::string row = statement.ColumnString(0);
-      std::vector<base::StringPiece> row_lines = base::SplitStringPiece(
-          row, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-      for (base::StringPiece row_line : row_lines)
-        result_lines.emplace_back(row_line);
-    }
-
-    success = statement.Succeeded();
-    *messages = std::move(result_lines);
+  if (!Execute("PRAGMA writable_schema=ON")) {
+    // The "PRAGMA integrity_check" statement executed below may return less
+    // useful information. However, incomplete information is still better than
+    // nothing, so we press on.
+    messages->push_back("PRAGMA writable_schema=ON failed");
   }
 
-  // Best effort to put things back as they were before.
+  // We need to bypass sql::Statement and use raw SQLite C API calls here.
+  //
+  // "PRAGMA integrity_check" reports SQLITE_CORRUPT when the database is
+  // corrupt. Reporting SQLITE_CORRUPT is undesirable in this case, because it
+  // causes our sql::Statement infrastructure to call the database error
+  // handler, which triggers feature-level error handling. However,
+  // FullIntegrityCheck() callers presumably already know that the database is
+  // corrupted, and are trying to collect diagnostic information for reporting.
+  sqlite3_stmt* statement = nullptr;
+
+  // https://www.sqlite.org/c3ref/prepare.html states that SQLite will perform
+  // slightly better if sqlite_prepare_v3() receives a zero-terminated statement
+  // string, and a statement size that includes the zero byte. Fortunately,
+  // C++'s string literal and sizeof() operator do exactly that.
+  constexpr char kIntegrityCheckSql[] = "PRAGMA integrity_check";
+  const int prepare_result =
+      sqlite3_prepare_v3(db_, kIntegrityCheckSql, sizeof(kIntegrityCheckSql),
+                         SqlitePrepareFlags(), &statement, /*pzTail=*/nullptr);
+  if (prepare_result != SQLITE_OK)
+    return false;
+
+  // "PRAGMA integrity_check" currently returns multiple lines as a single row.
+  //
+  // However, since https://www.sqlite.org/pragma.html#pragma_integrity_check
+  // states that multiple records may be returned, the code below can handle
+  // multiple records, each of which has multiple lines.
+  std::vector<std::string> result_lines;
+
+  while (sqlite3_step(statement) == SQLITE_ROW) {
+    const uint8_t* row = chrome_sqlite3_column_text(statement, /*iCol=*/0);
+    DCHECK(row) << "PRAGMA integrity_check should never return NULL rows";
+
+    const int row_size = sqlite3_column_bytes(statement, /*iCol=*/0);
+    base::StringPiece row_string(reinterpret_cast<const char*>(row), row_size);
+
+    const std::vector<base::StringPiece> row_lines = base::SplitStringPiece(
+        row_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+    for (base::StringPiece row_line : row_lines)
+      result_lines.emplace_back(row_line);
+  }
+
+  const int finalize_result = sqlite3_finalize(statement);
+  // sqlite3_finalize() may return SQLITE_CORRUPT when the integrity check
+  // discovers any problems. We still consider this case a success, as long as
+  // the statement produced at least one diagnostic message.
+  const bool success =
+      (result_lines.size() > 0) || (finalize_result == SQLITE_OK);
+  *messages = std::move(result_lines);
+
+  // Best-effort attempt to undo the "PRAGMA writable_schema=ON" executed above.
   std::ignore = Execute("PRAGMA writable_schema=OFF");
 
   return success;
diff --git a/sql/database.h b/sql/database.h
index 1bd361c4..6824e27 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -237,10 +237,17 @@
   // Developer-friendly database ID used in logging output and memory dumps.
   void set_histogram_tag(const std::string& tag);
 
-  // Run "PRAGMA integrity_check" and post each line of
-  // results into |messages|.  Returns the success of running the
-  // statement - per the SQLite documentation, if no errors are found the
-  // call should succeed, and a single value "ok" should be in messages.
+  // Asks SQLite to perform a full integrity check on the database.
+  //
+  // Returns true if the integrity check was completed successfully. Success
+  // does not necessarily entail that the database is healthy. Finding
+  // corruption and reporting it in `messages` counts as success.
+  //
+  // If the method returns true, `messages` is populated with a list of
+  // diagnostic messages. If the integrity check finds no errors, `messages`
+  // will contain exactly one "ok" string. This unusual API design is explained
+  // by the fact that SQLite exposes integrity check functionality as a PRAGMA,
+  // and the PRAGMA returns "ok" in case of success.
   bool FullIntegrityCheck(std::vector<std::string>* messages);
 
   // Meant to be called from a client error callback so that it's able to
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc
index a8c4f86..9cc486f 100644
--- a/sql/database_unittest.cc
+++ b/sql/database_unittest.cc
@@ -1298,6 +1298,8 @@
   static constexpr char kTableSql[] =
       "CREATE TABLE rows(id INTEGER PRIMARY KEY NOT NULL, value TEXT NOT NULL)";
   ASSERT_TRUE(db_->Execute(kTableSql));
+  ASSERT_TRUE(db_->Execute("CREATE INDEX rows_by_value ON rows(value)"));
+
   {
     std::vector<std::string> messages;
     EXPECT_TRUE(db_->FullIntegrityCheck(&messages))
@@ -1305,16 +1307,11 @@
     EXPECT_THAT(messages, testing::ElementsAre("ok"))
         << "FullIntegrityCheck() should report ok before database is corrupted";
   }
-  db_->Close();
 
-  ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
-  {
-    sql::test::ScopedErrorExpecter expecter;
-    expecter.ExpectError(SQLITE_CORRUPT);
-    ASSERT_TRUE(db_->Open(db_path_));
-    EXPECT_TRUE(expecter.SawExpectedErrors())
-        << "Open() did not encounter SQLITE_CORRUPT";
-  }
+  db_->Close();
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_by_value"));
+  ASSERT_TRUE(db_->Open(db_path_));
+
   {
     std::vector<std::string> messages;
     EXPECT_TRUE(db_->FullIntegrityCheck(&messages))
@@ -1322,9 +1319,6 @@
     EXPECT_THAT(messages, testing::Not(testing::ElementsAre("ok")))
         << "FullIntegrityCheck() should not report ok for a corrupted database";
   }
-
-  // TODO(shess): CorruptTableOrIndex could be used to produce a
-  // file that would pass the quick check and fail the full check.
 }
 
 TEST_P(SQLDatabaseTest, OnMemoryDump) {
diff --git a/sql/recovery_unittest.cc b/sql/recovery_unittest.cc
index 123834c..5ed6039 100644
--- a/sql/recovery_unittest.cc
+++ b/sql/recovery_unittest.cc
@@ -15,7 +15,9 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
+#include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/bind.h"
 #include "sql/database.h"
 #include "sql/meta_table.h"
 #include "sql/statement.h"
@@ -216,169 +218,207 @@
             ExecuteWithResults(&db_, kXSql, "|", "\n"));
 }
 
-void RecoveryCallback(Database* db,
-                      const base::FilePath& db_path,
-                      const char* create_table,
-                      const char* create_index,
-                      int* record_error,
-                      int error,
-                      Statement* stmt) {
-  *record_error = error;
+// Our corruption handling assumes that a corrupt index doesn't impact
+// SQL statements that only operate on the associated table. This test verifies
+// the assumption.
+TEST_F(SQLRecoveryTest, TableIndependentFromCorruptIndex) {
+  static const char kCreateTable[] =
+      "CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL)";
+  ASSERT_TRUE(db_.Execute(kCreateTable));
+  ASSERT_TRUE(db_.Execute("CREATE UNIQUE INDEX rows_index ON rows(indexed)"));
 
-  // Clear the error callback to prevent reentrancy.
-  db->reset_error_callback();
+  // Populate the table with powers of two. These numbers make it easy to see if
+  // SUM() missed a row.
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(1, 1)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(2, 2)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(4, 4)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(8, 8)"));
 
-  std::unique_ptr<Recovery> recovery = Recovery::Begin(db, db_path);
-  ASSERT_TRUE(recovery.get());
+  // SQL statement that performs a table scan. SUM(unindexed) heavily nudges
+  // SQLite to use the table instead of the index.
+  static const char kUnindexedCountSql[] = "SELECT SUM(unindexed) FROM rows";
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "No SQL statement should fail before corruption";
 
-  ASSERT_TRUE(recovery->db()->Execute(create_table));
-  ASSERT_TRUE(recovery->db()->Execute(create_index));
+  // SQL statement that performs an index scan.
+  static const char kIndexedCountSql[] =
+      "SELECT SUM(indexed) FROM rows INDEXED BY rows_index";
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kIndexedCountSql))
+      << "Table scan should not fail due to corrupt index";
 
-  size_t rows = 0;
-  ASSERT_TRUE(recovery->AutoRecoverTable("x", &rows));
+  db_.Close();
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_index"));
+  ASSERT_TRUE(Reopen());
 
-  ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
+  {
+    sql::test::ScopedErrorExpecter expecter;
+    expecter.ExpectError(SQLITE_CORRUPT);
+    EXPECT_FALSE(db_.Execute(kIndexedCountSql))
+        << "Index scan on corrupt index should fail";
+    EXPECT_TRUE(expecter.SawExpectedErrors())
+        << "Index scan on corrupt index should fail";
+  }
+
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "Table scan should not fail due to corrupt index";
 }
 
-// Build a database, corrupt it by making an index reference to
-// deleted row, then recover when a query selects that row.
 TEST_F(SQLRecoveryTest, RecoverCorruptIndex) {
-  static const char kCreateTable[] = "CREATE TABLE x (id INTEGER, v INTEGER)";
-  static const char kCreateIndex[] = "CREATE UNIQUE INDEX x_id ON x (id)";
+  static const char kCreateTable[] =
+      "CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL)";
   ASSERT_TRUE(db_.Execute(kCreateTable));
+
+  static const char kCreateIndex[] =
+      "CREATE UNIQUE INDEX rows_index ON rows(indexed)";
   ASSERT_TRUE(db_.Execute(kCreateIndex));
 
-  // Insert a bit of data.
-  {
-    ASSERT_TRUE(db_.BeginTransaction());
+  // Populate the table with powers of two. These numbers make it easy to see if
+  // SUM() missed a row.
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(1, 1)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(2, 2)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(4, 4)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(8, 8)"));
 
-    static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (?, ?)";
-    Statement s(db_.GetUniqueStatement(kInsertSql));
-    for (int i = 0; i < 10; ++i) {
-      s.Reset(true);
-      s.BindInt(0, i);
-      s.BindInt(1, i);
-      EXPECT_FALSE(s.Step());
-      EXPECT_TRUE(s.Succeeded());
-    }
-
-    ASSERT_TRUE(db_.CommitTransaction());
-  }
   db_.Close();
-
-  // Delete a row from the table, while leaving the index entry which
-  // references it.
-  static const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
-  ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "x_id", kDeleteSql));
-
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_index"));
   ASSERT_TRUE(Reopen());
 
   int error = SQLITE_OK;
-  db_.set_error_callback(base::BindRepeating(
-      &RecoveryCallback, &db_, db_path_, kCreateTable, kCreateIndex, &error));
+  db_.set_error_callback(
+      base::BindLambdaForTesting([&](int sqlite_error, Statement* statement) {
+        error = sqlite_error;
 
-  // This works before the callback is called.
-  static const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_schema";
-  EXPECT_TRUE(db_.IsSQLValid(kTrivialSql));
+        // Recovery::Begin() does not support a pre-existing error callback.
+        db_.reset_error_callback();
+        std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
+        ASSERT_TRUE(recovery.get());
 
-  // TODO(shess): Could this be delete?  Anything which fails should work.
-  static const char kSelectSql[] = "SELECT v FROM x WHERE id = 0";
-  ASSERT_FALSE(db_.Execute(kSelectSql));
-  EXPECT_EQ(SQLITE_CORRUPT, error);
+        ASSERT_TRUE(recovery->db()->Execute(kCreateTable));
+        ASSERT_TRUE(recovery->db()->Execute(kCreateIndex));
 
-  // Database handle has been poisoned.
-  EXPECT_FALSE(db_.IsSQLValid(kTrivialSql));
+        size_t rows = 0;
+        ASSERT_TRUE(recovery->AutoRecoverTable("rows", &rows));
+        ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
+      }));
 
-  ASSERT_TRUE(Reopen());
+  // SUM(unindexed) heavily nudges SQLite to use the table instead of the index.
+  static const char kUnindexedCountSql[] = "SELECT SUM(unindexed) FROM rows";
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "Table scan should not fail due to corrupt index";
+  EXPECT_EQ(SQLITE_OK, error)
+      << "Successful statement execution should not invoke the error callback";
 
-  // The recovered table should reflect the deletion.
-  static const char kSelectAllSql[] = "SELECT v FROM x ORDER BY id";
-  EXPECT_EQ("1,2,3,4,5,6,7,8,9",
-            ExecuteWithResults(&db_, kSelectAllSql, "|", ","));
+  static const char kIndexedCountSql[] =
+      "SELECT SUM(indexed) FROM rows INDEXED BY rows_index";
+  EXPECT_EQ("", ExecuteWithResult(&db_, kIndexedCountSql))
+      << "Index scan on corrupt index should fail";
+  EXPECT_EQ(SQLITE_CORRUPT, error)
+      << "Error callback should be called during scan on corrupt index";
 
-  // The failing statement should now succeed, with no results.
-  EXPECT_EQ("", ExecuteWithResults(&db_, kSelectSql, "|", ","));
-}
-
-// Build a database, corrupt it by making a table contain a row not
-// referenced by the index, then recover the database.
-TEST_F(SQLRecoveryTest, RecoverCorruptTable) {
-  static const char kCreateTable[] = "CREATE TABLE x (id INTEGER, v INTEGER)";
-  static const char kCreateIndex[] = "CREATE UNIQUE INDEX x_id ON x (id)";
-  ASSERT_TRUE(db_.Execute(kCreateTable));
-  ASSERT_TRUE(db_.Execute(kCreateIndex));
-
-  // Insert a bit of data.
-  {
-    ASSERT_TRUE(db_.BeginTransaction());
-
-    static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (?, ?)";
-    Statement s(db_.GetUniqueStatement(kInsertSql));
-    for (int i = 0; i < 10; ++i) {
-      s.Reset(true);
-      s.BindInt(0, i);
-      s.BindInt(1, i);
-      EXPECT_FALSE(s.Step());
-      EXPECT_TRUE(s.Succeeded());
-    }
-
-    ASSERT_TRUE(db_.CommitTransaction());
-  }
-  db_.Close();
-
-  // Delete a row from the index while leaving a table entry.
-  static const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
-  ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "x", kDeleteSql));
-
-  ASSERT_TRUE(Reopen());
-
-  int error = SQLITE_OK;
-  db_.set_error_callback(base::BindRepeating(
-      &RecoveryCallback, &db_, db_path_, kCreateTable, kCreateIndex, &error));
-
-  // Index shows one less than originally inserted.
-  static const char kCountSql[] = "SELECT COUNT (*) FROM x";
-  EXPECT_EQ("9", ExecuteWithResult(&db_, kCountSql));
-
-  // A full table scan shows all of the original data.  Using column [v] to
-  // force use of the table rather than the index.
-  static const char kDistinctSql[] = "SELECT DISTINCT COUNT (v) FROM x";
-  EXPECT_EQ("10", ExecuteWithResult(&db_, kDistinctSql));
-
-  // Insert id 0 again.  Since it is not in the index, the insert
-  // succeeds, but results in a duplicate value in the table.
-  static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (0, 100)";
-  ASSERT_TRUE(db_.Execute(kInsertSql));
-
-  // Duplication is visible.
-  EXPECT_EQ("10", ExecuteWithResult(&db_, kCountSql));
-  EXPECT_EQ("11", ExecuteWithResult(&db_, kDistinctSql));
-
-  // This works before the callback is called.
-  static const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_schema";
-  EXPECT_TRUE(db_.IsSQLValid(kTrivialSql));
-
-  // TODO(shess): Figure out a statement which causes SQLite to notice the
-  // corruption.  SELECT doesn't see errors because missing index values aren't
-  // visible.  UPDATE or DELETE against v=0 don't see errors, even though the
-  // index item is missing.  I suspect SQLite only deletes the key in these
-  // cases, but doesn't verify that one or more keys were deleted.
-  ASSERT_FALSE(db_.Execute("INSERT INTO x (id, v) VALUES (0, 101)"));
-  EXPECT_EQ(SQLITE_CONSTRAINT_UNIQUE, error);
-
-  // Database handle has been poisoned.
-  EXPECT_FALSE(db_.IsSQLValid(kTrivialSql));
+  EXPECT_EQ("", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "Table scan should not succeed anymore on a poisoned database";
 
   ASSERT_TRUE(Reopen());
 
   // The recovered table has consistency between the index and the table.
-  EXPECT_EQ("10", ExecuteWithResult(&db_, kCountSql));
-  EXPECT_EQ("10", ExecuteWithResult(&db_, kDistinctSql));
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "Table should survive database recovery";
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kIndexedCountSql))
+      << "Index should be reconstructed during database recovery";
+}
 
-  // Only one of the values is retained.
-  static const char kSelectSql[] = "SELECT v FROM x WHERE id = 0";
-  const std::string results = ExecuteWithResult(&db_, kSelectSql);
-  EXPECT_TRUE(results=="100" || results=="0") << "Actual results: " << results;
+TEST_F(SQLRecoveryTest, RecoverCorruptTable) {
+  // The `filler` column is used to cause a record to overflow multiple pages.
+  static const char kCreateTable[] =
+      // clang-format off
+      "CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL,"
+      "filler BLOB NOT NULL)";
+  // clang-format on
+  ASSERT_TRUE(db_.Execute(kCreateTable));
+
+  static const char kCreateIndex[] =
+      "CREATE UNIQUE INDEX rows_index ON rows(indexed)";
+  ASSERT_TRUE(db_.Execute(kCreateIndex));
+
+  // Populate the table with powers of two. These numbers make it easy to see if
+  // SUM() missed a row.
+  ASSERT_TRUE(db_.Execute(
+      "INSERT INTO rows(indexed, unindexed, filler) VALUES(1, 1, x'31')"));
+  ASSERT_TRUE(db_.Execute(
+      "INSERT INTO rows(indexed, unindexed, filler) VALUES(2, 2, x'32')"));
+  ASSERT_TRUE(db_.Execute(
+      "INSERT INTO rows(indexed, unindexed, filler) VALUES(4, 4, x'34')"));
+
+  constexpr int kDbPageSize = 4096;
+  {
+    // Insert a record that will overflow the page.
+    std::vector<uint8_t> large_buffer;
+    ASSERT_EQ(db_.page_size(), kDbPageSize)
+        << "Page overflow relies on specific size";
+    large_buffer.resize(kDbPageSize * 2);
+    base::ranges::fill(large_buffer, '8');
+    sql::Statement insert(db_.GetUniqueStatement(
+        "INSERT INTO rows(indexed,unindexed,filler) VALUES(8,8,?)"));
+    insert.BindBlob(0, large_buffer);
+    ASSERT_TRUE(insert.Run());
+  }
+
+  db_.Close();
+  {
+    // Zero out the last page of the database. This should be the overflow page
+    // allocated for the last inserted row. So, deleting it should corrupt the
+    // rows table.
+    base::File db_file(db_path_, base::File::FLAG_OPEN | base::File::FLAG_READ |
+                                     base::File::FLAG_WRITE);
+    ASSERT_TRUE(db_file.IsValid());
+    int64_t db_size = db_file.GetLength();
+    ASSERT_GT(db_size, kDbPageSize)
+        << "The database should have multiple pages";
+    ASSERT_TRUE(db_file.SetLength(db_size - kDbPageSize));
+  }
+
+  {
+    sql::test::ScopedErrorExpecter expecter;
+    expecter.ExpectError(SQLITE_CORRUPT);
+    ASSERT_TRUE(Reopen());
+    EXPECT_TRUE(expecter.SawExpectedErrors());
+    // PRAGMAs executed inside Database::Open() will error out.
+  }
+
+  int error = SQLITE_OK;
+  db_.set_error_callback(
+      base::BindLambdaForTesting([&](int sqlite_error, Statement* statement) {
+        error = sqlite_error;
+
+        // Recovery::Begin() does not support a pre-existing error callback.
+        db_.reset_error_callback();
+        std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
+        ASSERT_TRUE(recovery.get());
+
+        ASSERT_TRUE(recovery->db()->Execute(kCreateTable));
+        ASSERT_TRUE(recovery->db()->Execute(kCreateIndex));
+
+        size_t rows = 0;
+        ASSERT_TRUE(recovery->AutoRecoverTable("rows", &rows));
+        ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
+      }));
+
+  // SUM(unindexed) heavily nudges SQLite to use the table instead of the index.
+  static const char kUnindexedCountSql[] = "SELECT SUM(unindexed) FROM rows";
+  EXPECT_FALSE(db_.Execute(kUnindexedCountSql))
+      << "Table scan on corrupt table should fail";
+  EXPECT_EQ(SQLITE_CORRUPT, error)
+      << "Error callback should be called during scan on corrupt index";
+
+  ASSERT_TRUE(Reopen());
+
+  // All rows should be recovered. Only the BLOB in the last row was damaged.
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kUnindexedCountSql))
+      << "Table should survive database recovery";
+  static const char kIndexedCountSql[] =
+      "SELECT SUM(indexed) FROM rows INDEXED BY rows_index";
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kIndexedCountSql))
+      << "Index should be reconstructed during database recovery";
 }
 
 TEST_F(SQLRecoveryTest, Meta) {
@@ -886,27 +926,23 @@
 
 // Allow callers to validate the database between recovery and commit.
 TEST_F(SQLRecoveryTest, BeginRecoverDatabase) {
-  // Create a table with a broken index.
-  ASSERT_TRUE(db_.Execute("CREATE TABLE t (id INTEGER PRIMARY KEY, c TEXT)"));
-  ASSERT_TRUE(db_.Execute("CREATE UNIQUE INDEX t_id ON t (id)"));
-  ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (1, 'hello world')"));
-  ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (2, 'testing')"));
-  ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (3, 'nope')"));
+  static const char kCreateTable[] =
+      "CREATE TABLE rows(indexed INTEGER NOT NULL, unindexed INTEGER NOT NULL)";
+  ASSERT_TRUE(db_.Execute(kCreateTable));
 
-  // Inject corruption into the index.
+  ASSERT_TRUE(db_.Execute("CREATE UNIQUE INDEX rows_index ON rows(indexed)"));
+
+  // Populate the table with powers of two. These numbers make it easy to see if
+  // SUM() missed a row.
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(1, 1)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(2, 2)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(4, 4)"));
+  ASSERT_TRUE(db_.Execute("INSERT INTO rows(indexed, unindexed) VALUES(8, 8)"));
+
   db_.Close();
-  static const char kDeleteSql[] = "DELETE FROM t WHERE id = 3";
-  ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "t_id", kDeleteSql));
+  ASSERT_TRUE(sql::test::CorruptIndexRootPage(db_path_, "rows_index"));
   ASSERT_TRUE(Reopen());
 
-  // id as read from index.
-  static const char kSelectIndexIdSql[] = "SELECT id FROM t INDEXED BY t_id";
-  EXPECT_EQ("1,2,3", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
-
-  // id as read from table.
-  static const char kSelectTableIdSql[] = "SELECT id FROM t NOT INDEXED";
-  EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
-
   // Run recovery code, then rollback.  Database remains the same.
   {
     std::unique_ptr<Recovery> recovery =
@@ -916,10 +952,19 @@
   }
   db_.Close();
   ASSERT_TRUE(Reopen());
-  EXPECT_EQ("1,2,3", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
-  EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
 
-  // Run recovery code, then commit.  The failing row is dropped.
+  static const char kIndexedCountSql[] =
+      "SELECT SUM(indexed) FROM rows INDEXED BY rows_index";
+  {
+    sql::test::ScopedErrorExpecter expecter;
+    expecter.ExpectError(SQLITE_CORRUPT);
+    EXPECT_EQ("", ExecuteWithResult(&db_, kIndexedCountSql))
+        << "Index should still be corrupted after recovery rollback";
+    EXPECT_TRUE(expecter.SawExpectedErrors())
+        << "Index should still be corrupted after recovery rollback";
+  }
+
+  // Run recovery code, then commit.  The index is recovered.
   {
     std::unique_ptr<Recovery> recovery =
         Recovery::BeginRecoverDatabase(&db_, db_path_);
@@ -928,8 +973,9 @@
   }
   db_.Close();
   ASSERT_TRUE(Reopen());
-  EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
-  EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
+
+  EXPECT_EQ("15", ExecuteWithResult(&db_, kIndexedCountSql))
+      << "Index should be reconstructed after database recovery";
 }
 
 TEST_F(SQLRecoveryTest, AttachFailure) {
diff --git a/sql/test/test_helpers.cc b/sql/test/test_helpers.cc
index 0467143..b98144da 100644
--- a/sql/test/test_helpers.cc
+++ b/sql/test/test_helpers.cc
@@ -15,12 +15,15 @@
 #include "base/big_endian.h"
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
+#include "base/strings/string_piece.h"
 #include "base/threading/thread_restrictions.h"
 #include "sql/database.h"
 #include "sql/statement.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql::test {
@@ -36,25 +39,53 @@
   return s.ColumnInt(0);
 }
 
-// Get page size for the database.
-bool GetPageSize(sql::Database* db, int* page_size) {
-  sql::Statement s(db->GetUniqueStatement("PRAGMA page_size"));
-  if (!s.Step())
-    return false;
-  *page_size = s.ColumnInt(0);
-  return true;
+// Read a database's page size. Returns nullopt in case of error.
+absl::optional<int> ReadPageSize(const base::FilePath& db_path) {
+  // See https://www.sqlite.org/fileformat2.html#page_size
+  constexpr size_t kPageSizeOffset = 16;
+  uint8_t raw_page_size_bytes[2];
+  base::File file(db_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+  if (!file.IsValid())
+    return absl::nullopt;
+  if (!file.ReadAndCheck(kPageSizeOffset, raw_page_size_bytes))
+    return absl::nullopt;
+
+  uint16_t raw_page_size;
+  base::ReadBigEndian(raw_page_size_bytes, &raw_page_size);
+  // The SQLite database format initially allocated a 16 bits for storing the
+  // page size. This worked out until SQLite wanted to support 64kb pages,
+  // because 65536 (64kb) doesn't fit in a 16-bit unsigned integer.
+  //
+  // Currently, the page_size field value of 1 is a special case for 64kb pages.
+  // The documentation hints at the path for future expansion -- the page_size
+  // field may become a litte-endian number that indicates the database page
+  // size divided by 256. This happens to work out because the smallest
+  // supported page size is 512.
+  const int page_size = (raw_page_size == 1) ? 65536 : raw_page_size;
+  // Sanity-check that the page size is valid.
+  constexpr uint16_t kMinPageSize = 512;
+  if (page_size < kMinPageSize || (page_size & (page_size - 1)) != 0)
+    return absl::nullopt;
+
+  return page_size;
 }
 
-// Get |name|'s root page number in the database.
-bool GetRootPage(sql::Database* db, const char* name, int* page_number) {
-  static const char kPageSql[] =
-      "SELECT rootpage FROM sqlite_schema WHERE name = ?";
-  sql::Statement s(db->GetUniqueStatement(kPageSql));
-  s.BindString(0, name);
-  if (!s.Step())
-    return false;
-  *page_number = s.ColumnInt(0);
-  return true;
+// Read the number of the root page of a B-tree (index/table).
+//
+// Returns a 0-indexed page number, not the raw SQLite page number.
+absl::optional<int> GetRootPage(sql::Database& db,
+                                base::StringPiece tree_name) {
+  sql::Statement select(
+      db.GetUniqueStatement("SELECT rootpage FROM sqlite_schema WHERE name=?"));
+  select.BindString(0, tree_name);
+  if (!select.Step())
+    return absl::nullopt;
+
+  int sqlite_page_number = select.ColumnInt(0);
+  if (!sqlite_page_number)
+    return absl::nullopt;
+
+  return sqlite_page_number - 1;
 }
 
 [[nodiscard]] bool IsWalDatabase(const base::FilePath& db_path) {
@@ -176,68 +207,29 @@
   return CorruptSizeInHeader(db_path);
 }
 
-bool CorruptTableOrIndex(const base::FilePath& db_path,
-                         const char* tree_name,
-                         const char* update_sql) {
+bool CorruptIndexRootPage(const base::FilePath& db_path,
+                          base::StringPiece index_name) {
+  absl::optional<int> page_size = ReadPageSize(db_path);
+  if (!page_size.has_value())
+    return false;
+
   sql::Database db;
   if (!db.Open(db_path))
     return false;
 
-  int page_size = db.page_size();
-  if (!GetPageSize(&db, &page_size))
-    return false;
-
-  int page_number = 0;
-  if (!GetRootPage(&db, tree_name, &page_number))
-    return false;
-
-  // SQLite uses 1-based page numbering.
-  const long int page_ofs = (page_number - 1) * page_size;
-  std::unique_ptr<char[]> page_buf(new char[page_size]);
-
-  // Get the page into page_buf.
-  base::ScopedFILE file(base::OpenFile(db_path, "rb+"));
-  if (!file.get())
-    return false;
-  if (0 != fseek(file.get(), page_ofs, SEEK_SET))
-    return false;
-  if (1u != fread(page_buf.get(), page_size, 1, file.get()))
-    return false;
-
-  // Require the page to be a leaf node.  A multilevel tree would be
-  // very hard to restore correctly.
-  if (page_buf[0] != 0xD && page_buf[0] != 0xA)
-    return false;
-
-  // The update has to work, and make changes.
-  if (!db.Execute(update_sql))
-    return false;
-  if (db.GetLastChangeCount() == 0)
-    return false;
-
-  // Ensure that the database is fully flushed.
+  absl::optional<int> page_number = GetRootPage(db, index_name);
   db.Close();
-
-  // Check that the stored page actually changed.  This catches usage
-  // errors where |update_sql| is not related to |tree_name|.
-  std::unique_ptr<char[]> check_page_buf(new char[page_size]);
-  // The on-disk data should have changed.
-  if (0 != fflush(file.get()))
-    return false;
-  if (0 != fseek(file.get(), page_ofs, SEEK_SET))
-    return false;
-  if (1u != fread(check_page_buf.get(), page_size, 1, file.get()))
-    return false;
-  if (!memcmp(check_page_buf.get(), page_buf.get(), page_size))
+  if (!page_number.has_value())
     return false;
 
-  // Put the original page back.
-  if (0 != fseek(file.get(), page_ofs, SEEK_SET))
-    return false;
-  if (1u != fwrite(page_buf.get(), page_size, 1, file.get()))
-    return false;
+  std::vector<uint8_t> page_buffer(page_size.value());
+  const int64_t page_offset = int64_t{page_number.value()} * page_size.value();
 
-  return true;
+  base::File file(db_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
+                               base::File::FLAG_WRITE);
+  if (!file.IsValid())
+    return false;
+  return file.WriteAndCheck(page_offset, page_buffer);
 }
 
 size_t CountSQLTables(sql::Database* db) {
diff --git a/sql/test/test_helpers.h b/sql/test/test_helpers.h
index c431a9f..ba98f42e 100644
--- a/sql/test/test_helpers.h
+++ b/sql/test/test_helpers.h
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/files/file_path.h"
+#include "base/strings/string_piece_forward.h"
 
 // Collection of test-only convenience functions.
 
@@ -22,8 +22,7 @@
 class Database;
 }
 
-namespace sql {
-namespace test {
+namespace sql::test {
 
 // SQLite stores the database size in the header, and if the actual
 // OS-derived size is smaller, the database is considered corrupt.
@@ -44,25 +43,14 @@
 // already open elsewhere.  Blocks until a write lock can be acquired.
 [[nodiscard]] bool CorruptSizeInHeaderWithLock(const base::FilePath& db_path);
 
-// Frequently corruption is a result of failure to atomically update
-// pages in different structures.  For instance, if an index update
-// takes effect but the corresponding table update does not.  This
-// helper restores the prior version of a b-tree root after running an
-// update which changed that b-tree.  The named b-tree must exist and
-// must be a leaf node (either index or table).  Returns true if the
-// on-disk file is successfully modified, and the restored page
-// differs from the updated page.
+// Simulates total index corruption by zeroing the root page of an index B-tree.
 //
-// The resulting database should be possible to open, and many
-// statements should work.  SQLITE_CORRUPT will be thrown if a query
-// through the index finds the row missing in the table.
-//
-// TODO(shess): It would be very helpful to allow a parameter to the
-// sql statement.  Perhaps a version with a string parameter would be
-// sufficient, given affinity rules?
-[[nodiscard]] bool CorruptTableOrIndex(const base::FilePath& db_path,
-                                       const char* tree_name,
-                                       const char* update_sql);
+// The corrupted database will still open successfully. SELECTs on the table
+// associated with the index will work, as long as they don't access the index.
+// However, any query that accesses the index will fail with SQLITE_CORRUPT.
+// DROPping the table or the index will fail.
+[[nodiscard]] bool CorruptIndexRootPage(const base::FilePath& db_path,
+                                        base::StringPiece index_name);
 
 // Return the number of tables in sqlite_schema.
 [[nodiscard]] size_t CountSQLTables(sql::Database* db);
@@ -144,7 +132,6 @@
   bool is_auto_incremented;
 };
 
-}  // namespace test
-}  // namespace sql
+}  // namespace sql::test
 
 #endif  // SQL_TEST_TEST_HELPERS_H_
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index ce5d8d3f..17fdeb9 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1808,7 +1808,7 @@
       {
         "args": [],
         "cros_board": "atlas",
-        "cros_img": "atlas-release/R99-14469.24.0",
+        "cros_img": "atlas-release/R99-14469.33.0",
         "name": "lacros_all_tast_tests_ATLAS_BETA",
         "resultdb": {
           "enable": true,
@@ -1868,7 +1868,7 @@
       {
         "args": [],
         "cros_board": "eve",
-        "cros_img": "eve-release/R99-14469.24.0",
+        "cros_img": "eve-release/R99-14469.33.0",
         "name": "lacros_all_tast_tests_EVE_BETA",
         "resultdb": {
           "enable": true,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index b571f0b..c36f4ac 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -5230,7 +5230,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5398,7 +5398,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5482,7 +5482,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5650,7 +5650,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index be95459a..89f5688e 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -41650,7 +41650,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -41818,7 +41818,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -41902,7 +41902,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42070,7 +42070,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42158,7 +42158,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42326,7 +42326,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42410,7 +42410,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42578,7 +42578,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42733,7 +42733,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42901,7 +42901,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -42985,7 +42985,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43153,7 +43153,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43308,7 +43308,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43476,7 +43476,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43560,7 +43560,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M100",
-              "revision": "version:100.0.4896.13"
+              "revision": "version:100.0.4896.14"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -43728,7 +43728,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M99",
-              "revision": "version:99.0.4844.47"
+              "revision": "version:99.0.4844.50"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9a6255a..851c706 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -24411,6 +24411,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24437,6 +24438,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24459,6 +24461,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24494,6 +24497,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24527,6 +24531,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24560,6 +24565,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24578,9 +24584,9 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
           "--expected-vendor-id",
-          "0",
+          "1ae0",
           "--expected-device-id",
-          "0"
+          "c0de"
         ],
         "isolate_name": "telemetry_gpu_integration_test_fuchsia",
         "merge": {
@@ -24597,6 +24603,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24639,6 +24646,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24672,6 +24680,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24714,6 +24723,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24747,6 +24757,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24781,6 +24792,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24814,6 +24826,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24847,6 +24860,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24876,6 +24890,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24903,6 +24918,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24926,6 +24942,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24962,6 +24979,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -24996,6 +25014,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25030,6 +25049,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25048,9 +25068,9 @@
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
           "--expected-vendor-id",
-          "0",
+          "1ae0",
           "--expected-device-id",
-          "0",
+          "c0de",
           "--custom-image=workstation.qemu-x64-release"
         ],
         "isolate_name": "telemetry_gpu_integration_test_fuchsia",
@@ -25068,6 +25088,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25111,6 +25132,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25145,6 +25167,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25188,6 +25211,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25222,6 +25246,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25257,6 +25282,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25291,6 +25317,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
@@ -25325,6 +25352,7 @@
           "can_use_on_swarming_builders": true,
           "dimension_sets": [
             {
+              "gpu": "1ae0:c0de",
               "kvm": "1",
               "os": "Ubuntu-18.04"
             }
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index 59fedab..181bdc1 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1147,7 +1147,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R99-14469.24.0",
+        "cros_img": "octopus-release/R99-14469.33.0",
         "name": "lacros_fyi_tast_tests_OCTOPUS_BETA",
         "swarming": {},
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
@@ -1189,7 +1189,7 @@
       {
         "args": [],
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R99-14469.24.0",
+        "cros_img": "octopus-release/R99-14469.33.0",
         "name": "ozone_unittests_OCTOPUS_BETA",
         "swarming": {},
         "test": "ozone_unittests",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index b734e98..8244a40 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -387,7 +387,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M100',
-          'revision': 'version:100.0.4896.13',
+          'revision': 'version:100.0.4896.14',
         }
       ],
     },
@@ -411,7 +411,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.47',
+          'revision': 'version:99.0.4844.50',
         }
       ],
     },
@@ -459,7 +459,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M100',
-          'revision': 'version:100.0.4896.13',
+          'revision': 'version:100.0.4896.14',
         }
       ],
     },
@@ -483,7 +483,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.47',
+          'revision': 'version:99.0.4844.50',
         }
       ],
     },
@@ -531,7 +531,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M100',
-          'revision': 'version:100.0.4896.13',
+          'revision': 'version:100.0.4896.14',
         }
       ],
     },
@@ -555,7 +555,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M99',
-          'revision': 'version:99.0.4844.47',
+          'revision': 'version:99.0.4844.50',
         }
       ],
     },
@@ -605,8 +605,8 @@
   'CROS_ATLAS_BETA': {
     'skylab': {
       'cros_board': 'atlas',
-      'cros_chrome_version': '99.0.4844.33',
-      'cros_img': 'atlas-release/R99-14469.24.0',
+      'cros_chrome_version': '99.0.4844.46',
+      'cros_img': 'atlas-release/R99-14469.33.0',
     },
     'enabled': True,
     'identifier': 'ATLAS_BETA',
@@ -641,8 +641,8 @@
   'CROS_EVE_BETA': {
     'skylab': {
       'cros_board': 'eve',
-      'cros_chrome_version': '99.0.4844.33',
-      'cros_img': 'eve-release/R99-14469.24.0',
+      'cros_chrome_version': '99.0.4844.46',
+      'cros_img': 'eve-release/R99-14469.33.0',
     },
     'enabled': True,
     'identifier': 'EVE_BETA',
@@ -695,8 +695,8 @@
   'CROS_OCTOPUS_BETA': {
     'skylab': {
       'cros_board': 'octopus',
-      'cros_chrome_version': '99.0.4844.33',
-      'cros_img': 'octopus-release/R99-14469.24.0',
+      'cros_chrome_version': '99.0.4844.46',
+      'cros_img': 'octopus-release/R99-14469.33.0',
     },
     'enabled': True,
     'identifier': 'OCTOPUS_BETA',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 016034d9..70a55766 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2941,6 +2941,7 @@
         'swarming': {
           'dimension_sets': [
             {
+              'gpu': '1ae0:c0de',
               'kvm': '1',
             },
           ],
@@ -2962,6 +2963,7 @@
         'swarming': {
           'dimension_sets': [
             {
+              'gpu': '1ae0:c0de',
               'kvm': '1',
             },
           ],
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index a974e48..6fd09b9b1 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1078,28 +1078,6 @@
             ]
         }
     ],
-    "AvoidUnnecessaryBeforeUnloadCheck": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer",
-                "android_webview",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "AvoidUnnecessaryBeforeUnloadCheck"
-                    ]
-                }
-            ]
-        }
-    ],
     "BackForwardCache": [
         {
             "platforms": [
@@ -1694,41 +1672,6 @@
             ]
         }
     ],
-    "ClankStartupOptimizations": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "NoPreloadOrPri_1",
-                    "enable_features": [
-                        "ElidePrioritizationOfPreNativeBootstrapTasks",
-                        "ElideTabPreloadAtStartup",
-                        "TreatBootstrapAsDefault"
-                    ]
-                }
-            ]
-        }
-    ],
-    "ClankStartupOptimizationsWebViewAndWebLayer": [
-        {
-            "platforms": [
-                "android_weblayer",
-                "android_webview"
-            ],
-            "experiments": [
-                {
-                    "name": "NoPreloadOrPri_1",
-                    "enable_features": [
-                        "ElidePrioritizationOfPreNativeBootstrapTasks",
-                        "ElideTabPreloadAtStartup",
-                        "TreatBootstrapAsDefault"
-                    ]
-                }
-            ]
-        }
-    ],
     "CleanUndecryptablePasswordsLinuxDuringInitialSync": [
         {
             "platforms": [
@@ -1892,9 +1835,7 @@
     "CombinedNavigationOptimizations": [
         {
             "platforms": [
-                "android",
-                "android_weblayer",
-                "android_webview"
+                "android"
             ],
             "experiments": [
                 {
@@ -1903,14 +1844,19 @@
                         "CreateCompositorWorkerContext": "true"
                     },
                     "enable_features": [
+                        "AvoidUnnecessaryBeforeUnloadCheck",
                         "EarlyCodeCache",
                         "EarlyEstablishGpuChannel",
+                        "ElidePrioritizationOfPreNativeBootstrapTasks",
+                        "ElideTabPreloadAtStartup",
                         "FontManagerEarlyInit",
+                        "IncludeIpcOverheadInNavigationStart",
                         "NavigationRequestPreconnect",
                         "NavigationThreadingOptimizations",
                         "OptimizeEarlyNavigation",
                         "OptimizeLookalikeUrlNavigationThrottle",
                         "PrefetchAndroidFonts",
+                        "TreatBootstrapAsDefault",
                         "URLLoaderSyncClient"
                     ]
                 }
@@ -1933,12 +1879,51 @@
                         "CreateCompositorWorkerContext": "true"
                     },
                     "enable_features": [
+                        "AvoidUnnecessaryBeforeUnloadCheck",
                         "EarlyCodeCache",
                         "EarlyEstablishGpuChannel",
+                        "ElidePrioritizationOfPreNativeBootstrapTasks",
+                        "ElideTabPreloadAtStartup",
                         "FontManagerEarlyInit",
+                        "IncludeIpcOverheadInNavigationStart",
                         "NavigationRequestPreconnect",
                         "NavigationThreadingOptimizations",
+                        "OptimizeEarlyNavigation",
                         "OptimizeLookalikeUrlNavigationThrottle",
+                        "PrefetchAndroidFonts",
+                        "TreatBootstrapAsDefault",
+                        "URLLoaderSyncClient"
+                    ]
+                }
+            ]
+        }
+    ],
+    "CombinedNavigationOptimizationsWebView": [
+        {
+            "platforms": [
+                "android_weblayer",
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "params": {
+                        "CreateCompositorWorkerContext": "true"
+                    },
+                    "enable_features": [
+                        "AvoidUnnecessaryBeforeUnloadCheck",
+                        "EarlyCodeCache",
+                        "EarlyEstablishGpuChannel",
+                        "ElidePrioritizationOfPreNativeBootstrapTasks",
+                        "ElideTabPreloadAtStartup",
+                        "FontManagerEarlyInit",
+                        "IncludeIpcOverheadInNavigationStart",
+                        "NavigationRequestPreconnect",
+                        "NavigationThreadingOptimizations",
+                        "OptimizeEarlyNavigation",
+                        "OptimizeLookalikeUrlNavigationThrottle",
+                        "PrefetchAndroidFonts",
+                        "TreatBootstrapAsDefault",
                         "URLLoaderSyncClient"
                     ]
                 }
@@ -3694,28 +3679,6 @@
             ]
         }
     ],
-    "IncludeIpcOverheadInNavigationStart": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer",
-                "android_webview",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "IncludeIpcOverheadInNavigationStart"
-                    ]
-                }
-            ]
-        }
-    ],
     "IncognitoNtpRevamp": [
         {
             "platforms": [
@@ -5477,7 +5440,6 @@
                 {
                     "name": "Enabled_20220208",
                     "enable_features": [
-                        "NotificationScheduleService",
                         "ReadLaterReminderNotification"
                     ]
                 }
@@ -5898,6 +5860,28 @@
             ]
         }
     ],
+    "ShoppingListMenuItem": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20210125",
+                    "params": {
+                        "availability": ">=0",
+                        "event_trigger": "name:shopping_list_menu_item_iph_triggered;comparator:==0;window:7;storage:7",
+                        "event_trigger_last_year": "name:shopping_list_menu_item_iph_triggered;comparator:<3;window:360;storage:360",
+                        "event_used": "name:shopping_list_track_price_from_menu;comparator:==0;window:360;storage:360",
+                        "session_rate": "<1"
+                    },
+                    "enable_features": [
+                        "IPH_ShoppingListMenuItem"
+                    ]
+                }
+            ]
+        }
+    ],
     "SidePanelDragAndDrop": [
         {
             "platforms": [
@@ -6148,6 +6132,7 @@
     "TabAudioMuting": [
         {
             "platforms": [
+                "chromeos",
                 "chromeos_lacros",
                 "linux",
                 "mac",
@@ -6159,7 +6144,7 @@
                     "params": {
                         "availability": "any",
                         "event_trigger": "name:tab_audio_muting_iph_triggered;comparator:==0;window:120;storage:365",
-                        "event_used": "name:ab_audio_muting_toggle_viewed;comparator:==0;window:120;storage:365",
+                        "event_used": "name:tab_audio_muting_toggle_viewed;comparator:==0;window:120;storage:365",
                         "session_rate": "==0"
                     },
                     "enable_features": [
diff --git a/third_party/android_build_tools/aapt2/3pp/fetch.py b/third_party/android_build_tools/aapt2/3pp/fetch.py
index f6957b3..ff6f5d5 100755
--- a/third_party/android_build_tools/aapt2/3pp/fetch.py
+++ b/third_party/android_build_tools/aapt2/3pp/fetch.py
@@ -1,16 +1,13 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # 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.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _FILE_URL = 'https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/{0}/aapt2-{0}-linux.jar'
 _GROUP_INDEX_URL = 'https://dl.google.com/dl/android/maven2/com/android/tools/build/group-index.xml'
diff --git a/third_party/android_build_tools/bundletool/3pp/fetch.py b/third_party/android_build_tools/bundletool/3pp/fetch.py
index e98b743..bd955776 100755
--- a/third_party/android_build_tools/bundletool/3pp/fetch.py
+++ b/third_party/android_build_tools/bundletool/3pp/fetch.py
@@ -1,15 +1,12 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # 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.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
-
-from six.moves import urllib
+import urllib.request
 
 _RELEASES_URL = 'https://api.github.com/repos/google/bundletool/releases/latest'
 _RELEASE_URL = 'https://api.github.com/repos/google/bundletool/releases/tags/{}'
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/3ppFetch.template b/third_party/android_deps/buildSrc/src/main/groovy/3ppFetch.template
index 44075afd..90a7d8e 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/3ppFetch.template
+++ b/third_party/android_deps/buildSrc/src/main/groovy/3ppFetch.template
@@ -3,14 +3,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = '${dependency.repoUrl}'
 _GROUP_NAME = '${dependency.group.replace('.', '/')}'
diff --git a/third_party/android_deps/libs/android_arch_core_common/3pp/fetch.py b/third_party/android_deps/libs/android_arch_core_common/3pp/fetch.py
index 7948c6f..ce997d72 100755
--- a/third_party/android_deps/libs/android_arch_core_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_core_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/core'
diff --git a/third_party/android_deps/libs/android_arch_core_runtime/3pp/fetch.py b/third_party/android_deps/libs/android_arch_core_runtime/3pp/fetch.py
index a353c20..e834b1e 100755
--- a/third_party/android_deps/libs/android_arch_core_runtime/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_core_runtime/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/core'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_common/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_common/3pp/fetch.py
index 5b0aa577..184f174 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_common_java8/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_common_java8/3pp/fetch.py
index 19ac28b..6760c96 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_common_java8/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_common_java8/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_livedata/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_livedata/3pp/fetch.py
index 65c945df..071093f 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_livedata/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_livedata/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/3pp/fetch.py
index ab80660b..955b033b 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_runtime/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_runtime/3pp/fetch.py
index ba605b0..e03fde21 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_runtime/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_runtime/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/3pp/fetch.py b/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/3pp/fetch.py
index 49c0caef..4ccd108 100755
--- a/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/3pp/fetch.py
+++ b/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'android/arch/lifecycle'
diff --git a/third_party/android_deps/libs/com_android_support_animated_vector_drawable/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_animated_vector_drawable/3pp/fetch.py
index 237d503d..5cd8f6c96 100755
--- a/third_party/android_deps/libs/com_android_support_animated_vector_drawable/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_animated_vector_drawable/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_appcompat_v7/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_appcompat_v7/3pp/fetch.py
index a340387..8785dbe 100755
--- a/third_party/android_deps/libs/com_android_support_appcompat_v7/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_appcompat_v7/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_asynclayoutinflater/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_asynclayoutinflater/3pp/fetch.py
index 64c0c2a..52cbf5d2 100755
--- a/third_party/android_deps/libs/com_android_support_asynclayoutinflater/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_asynclayoutinflater/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_cardview_v7/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_cardview_v7/3pp/fetch.py
index 9b4093f..49b746e0 100755
--- a/third_party/android_deps/libs/com_android_support_cardview_v7/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_cardview_v7/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_collections/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_collections/3pp/fetch.py
index 5b76581..2909a6c 100755
--- a/third_party/android_deps/libs/com_android_support_collections/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_collections/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_coordinatorlayout/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_coordinatorlayout/3pp/fetch.py
index 1ee5fdf..3af3e03 100755
--- a/third_party/android_deps/libs/com_android_support_coordinatorlayout/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_coordinatorlayout/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_cursoradapter/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_cursoradapter/3pp/fetch.py
index 6eed858c..23ab31c 100755
--- a/third_party/android_deps/libs/com_android_support_cursoradapter/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_cursoradapter/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_customview/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_customview/3pp/fetch.py
index 360f9d3..23a126241 100755
--- a/third_party/android_deps/libs/com_android_support_customview/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_customview/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_design/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_design/3pp/fetch.py
index 5308744..de4838e 100755
--- a/third_party/android_deps/libs/com_android_support_design/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_design/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_documentfile/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_documentfile/3pp/fetch.py
index 3b94513..0622f6b 100755
--- a/third_party/android_deps/libs/com_android_support_documentfile/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_documentfile/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_drawerlayout/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_drawerlayout/3pp/fetch.py
index 34f575fb8..dee4716 100755
--- a/third_party/android_deps/libs/com_android_support_drawerlayout/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_drawerlayout/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_interpolator/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_interpolator/3pp/fetch.py
index 60e4334..9d8ea1ee 100755
--- a/third_party/android_deps/libs/com_android_support_interpolator/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_interpolator/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_loader/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_loader/3pp/fetch.py
index 0ec9a74..d2db0ab4 100755
--- a/third_party/android_deps/libs/com_android_support_loader/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_loader/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_localbroadcastmanager/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_localbroadcastmanager/3pp/fetch.py
index f584efb..ae78eb4 100755
--- a/third_party/android_deps/libs/com_android_support_localbroadcastmanager/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_localbroadcastmanager/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_multidex/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_multidex/3pp/fetch.py
index 12e5f962..cb8350e 100755
--- a/third_party/android_deps/libs/com_android_support_multidex/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_multidex/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_print/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_print/3pp/fetch.py
index 522579e11..87bdf7f 100755
--- a/third_party/android_deps/libs/com_android_support_print/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_print/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_recyclerview_v7/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_recyclerview_v7/3pp/fetch.py
index e71df9d..86ad33c 100755
--- a/third_party/android_deps/libs/com_android_support_recyclerview_v7/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_recyclerview_v7/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_slidingpanelayout/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_slidingpanelayout/3pp/fetch.py
index ea12568..2a9091f5 100755
--- a/third_party/android_deps/libs/com_android_support_slidingpanelayout/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_slidingpanelayout/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_annotations/3pp/fetch.py
index efd57a8..80ffbea 100755
--- a/third_party/android_deps/libs/com_android_support_support_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_compat/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_compat/3pp/fetch.py
index 0e49157..8afa473 100755
--- a/third_party/android_deps/libs/com_android_support_support_compat/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_compat/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_core_ui/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_core_ui/3pp/fetch.py
index 4a999fa..7bd9385 100755
--- a/third_party/android_deps/libs/com_android_support_support_core_ui/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_core_ui/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_core_utils/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_core_utils/3pp/fetch.py
index 7876248..b0c450c 100755
--- a/third_party/android_deps/libs/com_android_support_support_core_utils/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_core_utils/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_fragment/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_fragment/3pp/fetch.py
index dd48651..83d2ab7 100755
--- a/third_party/android_deps/libs/com_android_support_support_fragment/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_fragment/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_media_compat/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_media_compat/3pp/fetch.py
index 97af311c..ed4c9084 100755
--- a/third_party/android_deps/libs/com_android_support_support_media_compat/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_media_compat/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_v4/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_v4/3pp/fetch.py
index 9338515c..263d509 100755
--- a/third_party/android_deps/libs/com_android_support_support_v4/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_v4/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_support_vector_drawable/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_support_vector_drawable/3pp/fetch.py
index ebb647d..2463b34 100755
--- a/third_party/android_deps/libs/com_android_support_support_vector_drawable/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_support_vector_drawable/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_swiperefreshlayout/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_swiperefreshlayout/3pp/fetch.py
index 7036e51..b9ad24a 100755
--- a/third_party/android_deps/libs/com_android_support_swiperefreshlayout/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_swiperefreshlayout/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_transition/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_transition/3pp/fetch.py
index 1e67ce2..887d9a2e 100755
--- a/third_party/android_deps/libs/com_android_support_transition/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_transition/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_versionedparcelable/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_versionedparcelable/3pp/fetch.py
index caf90b3a..4252f22c 100755
--- a/third_party/android_deps/libs/com_android_support_versionedparcelable/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_versionedparcelable/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_support_viewpager/3pp/fetch.py b/third_party/android_deps/libs/com_android_support_viewpager/3pp/fetch.py
index 28437e4..7567a46 100755
--- a/third_party/android_deps/libs/com_android_support_viewpager/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_support_viewpager/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/support'
diff --git a/third_party/android_deps/libs/com_android_tools_common/3pp/fetch.py b/third_party/android_deps/libs/com_android_tools_common/3pp/fetch.py
index e0694b8..30ff476f 100755
--- a/third_party/android_deps/libs/com_android_tools_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_tools_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/tools'
diff --git a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/3pp/fetch.py b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/3pp/fetch.py
index 87e277a0..b4016e5 100755
--- a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/tools'
diff --git a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/3pp/fetch.py b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/3pp/fetch.py
index ad94af8..f8b0f9d 100755
--- a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/tools'
diff --git a/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/3pp/fetch.py b/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/3pp/fetch.py
index 8bc98a0f..bd6c1d5 100755
--- a/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/tools/layoutlib'
diff --git a/third_party/android_deps/libs/com_android_tools_sdk_common/3pp/fetch.py b/third_party/android_deps/libs/com_android_tools_sdk_common/3pp/fetch.py
index 65a1d64..ae7340b 100755
--- a/third_party/android_deps/libs/com_android_tools_sdk_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_android_tools_sdk_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/android/tools'
diff --git a/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/3pp/fetch.py b/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/3pp/fetch.py
index 1a266d86..2782012b 100755
--- a/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/github/ben-manes/caffeine'
diff --git a/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/3pp/fetch.py b/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/3pp/fetch.py
index 29432f1..6841dff 100755
--- a/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/github/kevinstern'
diff --git a/third_party/android_deps/libs/com_google_android_datatransport_transport_api/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_datatransport_transport_api/3pp/fetch.py
index 235f7ef..f70db9a 100755
--- a/third_party/android_deps/libs/com_google_android_datatransport_transport_api/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_datatransport_transport_api/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/datatransport'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_auth/3pp/fetch.py
index e3cd0976..0270bee7 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/3pp/fetch.py
index e86b02c..57fc7b2 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/3pp/fetch.py
index 5f4d8340..747d6d1 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_base/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_base/3pp/fetch.py
index 60a4bbb..a1e0aed 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_base/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_base/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_basement/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_basement/3pp/fetch.py
index a9d711d..fd846b1 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_basement/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_basement/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cast/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_cast/3pp/fetch.py
index 0f8551c..8d96ece 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cast/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cast/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/3pp/fetch.py
index d333177..645ae2a1 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/3pp/fetch.py
index 3abd7c9..d5a9364 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/3pp/fetch.py
index 002def1..9c23401591 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_fido/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_fido/3pp/fetch.py
index 88774e9..df18bb0 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_fido/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_fido/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_flags/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_flags/3pp/fetch.py
index f339bad..05b19ad3 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_flags/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_flags/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/3pp/fetch.py
index 642af7fb..b6b21bb 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_iid/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_iid/3pp/fetch.py
index c43d6a1..5467b0b 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_iid/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_iid/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/3pp/fetch.py
index 41485d3f..480c2a19 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_location/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_location/3pp/fetch.py
index 6598aad..04afd19 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_location/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_location/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/3pp/fetch.py
index 0c5f33c..0130971 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/3pp/fetch.py
index cfdd9f3..ccc11a6 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_stats/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_stats/3pp/fetch.py
index 49687958..712fbfd 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_stats/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_stats/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/3pp/fetch.py
index 55b025c6..803c619 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_vision/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_vision/3pp/fetch.py
index 2232c7a..9ab2407 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_vision/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_vision/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/3pp/fetch.py
index b8c460a3..1f7becfd 100755
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/gms'
diff --git a/third_party/android_deps/libs/com_google_android_material_material/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_material_material/3pp/fetch.py
index 6045557b..be61f2ce 100755
--- a/third_party/android_deps/libs/com_google_android_material_material/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_material_material/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/material'
diff --git a/third_party/android_deps/libs/com_google_android_play_core/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_play_core/3pp/fetch.py
index 2fb54ec9f..8b8a738d 100755
--- a/third_party/android_deps/libs/com_google_android_play_core/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_android_play_core/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/android/play'
diff --git a/third_party/android_deps/libs/com_google_auto_auto_common/3pp/fetch.py b/third_party/android_deps/libs/com_google_auto_auto_common/3pp/fetch.py
index f7fa9868..b3d0acb 100755
--- a/third_party/android_deps/libs/com_google_auto_auto_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_auto_auto_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/auto'
diff --git a/third_party/android_deps/libs/com_google_auto_service_auto_service/3pp/fetch.py b/third_party/android_deps/libs/com_google_auto_service_auto_service/3pp/fetch.py
index 27b82777..94636b3d 100755
--- a/third_party/android_deps/libs/com_google_auto_service_auto_service/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_auto_service_auto_service/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/auto/service'
diff --git a/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/3pp/fetch.py
index 9fafd1f..64db5fb 100755
--- a/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/auto/service'
diff --git a/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/3pp/fetch.py
index 25f44fe..b8276a2 100755
--- a/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/auto/value'
diff --git a/third_party/android_deps/libs/com_google_code_findbugs_jformatstring/3pp/fetch.py b/third_party/android_deps/libs/com_google_code_findbugs_jformatstring/3pp/fetch.py
index 609c92b7..2d8ae17 100755
--- a/third_party/android_deps/libs/com_google_code_findbugs_jformatstring/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_code_findbugs_jformatstring/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/code/findbugs'
diff --git a/third_party/android_deps/libs/com_google_code_findbugs_jsr305/3pp/fetch.py b/third_party/android_deps/libs/com_google_code_findbugs_jsr305/3pp/fetch.py
index 8fdc78ec..06a89bb2 100755
--- a/third_party/android_deps/libs/com_google_code_findbugs_jsr305/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_code_findbugs_jsr305/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/code/findbugs'
diff --git a/third_party/android_deps/libs/com_google_code_gson_gson/3pp/fetch.py b/third_party/android_deps/libs/com_google_code_gson_gson/3pp/fetch.py
index e1b6cc3..0e98bf94 100755
--- a/third_party/android_deps/libs/com_google_code_gson_gson/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_code_gson_gson/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/code/gson'
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger/3pp/fetch.py b/third_party/android_deps/libs/com_google_dagger_dagger/3pp/fetch.py
index 917de10..f9d38dc 100755
--- a/third_party/android_deps/libs/com_google_dagger_dagger/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_dagger_dagger/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/dagger'
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/3pp/fetch.py b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/3pp/fetch.py
index b419ab6e..2b665d9 100755
--- a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/dagger'
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_producers/3pp/fetch.py b/third_party/android_deps/libs/com_google_dagger_dagger_producers/3pp/fetch.py
index 596b67f6..fe9e40b 100755
--- a/third_party/android_deps/libs/com_google_dagger_dagger_producers/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_producers/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/dagger'
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_spi/3pp/fetch.py b/third_party/android_deps/libs/com_google_dagger_dagger_spi/3pp/fetch.py
index 98e7a18d..9ec653a 100755
--- a/third_party/android_deps/libs/com_google_dagger_dagger_spi/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_spi/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/dagger'
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/3pp/fetch.py
index e6ad4cb..da387cc 100755
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/3pp/fetch.py
index 5459439..2d7d544 100755
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/3pp/fetch.py
index e9d87c273..4bddd60 100755
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_core/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_error_prone_core/3pp/fetch.py
index df0de9c..ac12f857 100755
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_core/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_core/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/3pp/fetch.py
index bf4bcad..2d65787b 100755
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_javac/3pp/fetch.py
index 787d818f..bb40ecc8 100755
--- a/third_party/android_deps/libs/com_google_errorprone_javac/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_javac/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/3pp/fetch.py b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/3pp/fetch.py
index 4ebc98e48..d8bad61 100755
--- a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/errorprone'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_annotations/3pp/fetch.py
index a5b8367..0f67f0ed 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_common/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_common/3pp/fetch.py
index 63d58c4..23cae1a 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_components/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_components/3pp/fetch.py
index cf41564..c2aa2e1 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_components/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_components/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_encoders/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_encoders/3pp/fetch.py
index f03afec..f1639887 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_encoders/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_encoders/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/3pp/fetch.py
index 69d8cb1c..52cbffea0 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_iid/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_iid/3pp/fetch.py
index 6325c2d..73947c4 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_iid/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_iid/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/3pp/fetch.py
index 1b013ad..12d5630 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_installations/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_installations/3pp/fetch.py
index b406e56..29e1f5a 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_installations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_installations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/3pp/fetch.py
index d25d3e2..b26349b 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/3pp/fetch.py
index bd485c8..250fba57 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_messaging/3pp/fetch.py b/third_party/android_deps/libs/com_google_firebase_firebase_messaging/3pp/fetch.py
index eb055f8..2794104a 100755
--- a/third_party/android_deps/libs/com_google_firebase_firebase_messaging/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_messaging/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://dl.google.com/dl/android/maven2'
 _GROUP_NAME = 'com/google/firebase'
diff --git a/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/3pp/fetch.py b/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/3pp/fetch.py
index e509eaf..0efc5e1c 100755
--- a/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/flatbuffers'
diff --git a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/3pp/fetch.py b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/3pp/fetch.py
index b19239bc..7988dc37 100755
--- a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/googlejavaformat'
diff --git a/third_party/android_deps/libs/com_google_guava_failureaccess/3pp/fetch.py b/third_party/android_deps/libs/com_google_guava_failureaccess/3pp/fetch.py
index 0772ea5..7cfe14cc 100755
--- a/third_party/android_deps/libs/com_google_guava_failureaccess/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_guava_failureaccess/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/guava'
diff --git a/third_party/android_deps/libs/com_google_guava_guava/3pp/fetch.py b/third_party/android_deps/libs/com_google_guava_guava/3pp/fetch.py
index f3dcb0d0..a5f082d8 100755
--- a/third_party/android_deps/libs/com_google_guava_guava/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_guava_guava/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/guava'
diff --git a/third_party/android_deps/libs/com_google_guava_guava_android/3pp/fetch.py b/third_party/android_deps/libs/com_google_guava_guava_android/3pp/fetch.py
index f3dcb0d0..a5f082d8 100755
--- a/third_party/android_deps/libs/com_google_guava_guava_android/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_guava_guava_android/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/guava'
diff --git a/third_party/android_deps/libs/com_google_guava_listenablefuture/3pp/fetch.py b/third_party/android_deps/libs/com_google_guava_listenablefuture/3pp/fetch.py
index f289638..a5291270 100755
--- a/third_party/android_deps/libs/com_google_guava_listenablefuture/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_guava_listenablefuture/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/guava'
diff --git a/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/3pp/fetch.py b/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/3pp/fetch.py
index 8b9cd63..22c072b6 100755
--- a/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/j2objc'
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_java/3pp/fetch.py b/third_party/android_deps/libs/com_google_protobuf_protobuf_java/3pp/fetch.py
index d8f1b08..484c0c5c 100755
--- a/third_party/android_deps/libs/com_google_protobuf_protobuf_java/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_java/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/protobuf'
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/3pp/fetch.py b/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/3pp/fetch.py
index 0291cd6a..7324161 100755
--- a/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/google/protobuf'
diff --git a/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/3pp/fetch.py b/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/3pp/fetch.py
index dff227c..9a942e0 100755
--- a/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/googlecode/java-diff-utils'
diff --git a/third_party/android_deps/libs/com_squareup_javapoet/3pp/fetch.py b/third_party/android_deps/libs/com_squareup_javapoet/3pp/fetch.py
index 9c72dbd..bf9f10e 100755
--- a/third_party/android_deps/libs/com_squareup_javapoet/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_squareup_javapoet/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/squareup'
diff --git a/third_party/android_deps/libs/com_squareup_javawriter/3pp/fetch.py b/third_party/android_deps/libs/com_squareup_javawriter/3pp/fetch.py
index b2b273a..04a31d3 100755
--- a/third_party/android_deps/libs/com_squareup_javawriter/3pp/fetch.py
+++ b/third_party/android_deps/libs/com_squareup_javawriter/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'com/squareup'
diff --git a/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/3pp/fetch.py b/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/3pp/fetch.py
index c65e79b..5d4559a 100755
--- a/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/3pp/fetch.py
+++ b/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'io/github/java-diff-utils'
diff --git a/third_party/android_deps/libs/javax_annotation_javax_annotation_api/3pp/fetch.py b/third_party/android_deps/libs/javax_annotation_javax_annotation_api/3pp/fetch.py
index 0c568a8..193f7e1 100755
--- a/third_party/android_deps/libs/javax_annotation_javax_annotation_api/3pp/fetch.py
+++ b/third_party/android_deps/libs/javax_annotation_javax_annotation_api/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'javax/annotation'
diff --git a/third_party/android_deps/libs/javax_annotation_jsr250_api/3pp/fetch.py b/third_party/android_deps/libs/javax_annotation_jsr250_api/3pp/fetch.py
index a20aea0..90ab92a 100755
--- a/third_party/android_deps/libs/javax_annotation_jsr250_api/3pp/fetch.py
+++ b/third_party/android_deps/libs/javax_annotation_jsr250_api/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'javax/annotation'
diff --git a/third_party/android_deps/libs/javax_inject_javax_inject/3pp/fetch.py b/third_party/android_deps/libs/javax_inject_javax_inject/3pp/fetch.py
index 5271aae..c29a17c 100755
--- a/third_party/android_deps/libs/javax_inject_javax_inject/3pp/fetch.py
+++ b/third_party/android_deps/libs/javax_inject_javax_inject/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'javax/inject'
diff --git a/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/3pp/fetch.py b/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/3pp/fetch.py
index cc6c4c72..c652b45d 100755
--- a/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/3pp/fetch.py
+++ b/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'net/ltgt/gradle/incap'
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py
index e5da4877..7c7365e 100755
--- a/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py
+++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'net/sf/kxml'
diff --git a/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/3pp/fetch.py b/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/3pp/fetch.py
index b6741c61..7e8d3f2 100755
--- a/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ccil/cowan/tagsoup'
diff --git a/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/3pp/fetch.py b/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/3pp/fetch.py
index 43c89d54..6f4d948 100755
--- a/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/checkerframework'
diff --git a/third_party/android_deps/libs/org_checkerframework_checker_qual/3pp/fetch.py b/third_party/android_deps/libs/org_checkerframework_checker_qual/3pp/fetch.py
index 63083b41..5307393e 100755
--- a/third_party/android_deps/libs/org_checkerframework_checker_qual/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_checkerframework_checker_qual/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/checkerframework'
diff --git a/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/3pp/fetch.py b/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/3pp/fetch.py
index f73fd09..ca499d5 100755
--- a/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/checkerframework'
diff --git a/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/3pp/fetch.py b/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/3pp/fetch.py
index cd398dc7..c6c7622 100755
--- a/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/codehaus/mojo'
diff --git a/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/3pp/fetch.py b/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/3pp/fetch.py
index a7577299..fb584dd3 100755
--- a/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/eclipse/jgit'
diff --git a/third_party/android_deps/libs/org_jetbrains_annotations/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_annotations/3pp/fetch.py
index 824c492..aded062 100755
--- a/third_party/android_deps/libs/org_jetbrains_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/3pp/fetch.py
index b6fb5153..09799fa 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlin'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/3pp/fetch.py
index 44546d42..f3ae6ffa 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlin'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/3pp/fetch.py
index 6ed7a34..adad11c 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlin'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/3pp/fetch.py
index 8f6801537..15677e8 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlin'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/3pp/fetch.py
index fe0180d..ea9acdd 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlinx'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/3pp/fetch.py
index 7fd43a17b..a46ffaed 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlinx'
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/3pp/fetch.py
index 7dcf9b3f..d5462e0 100755
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/jetbrains/kotlinx'
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm/3pp/fetch.py b/third_party/android_deps/libs/org_ow2_asm_asm/3pp/fetch.py
index fbddbc8..7c17032d 100755
--- a/third_party/android_deps/libs/org_ow2_asm_asm/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ow2_asm_asm/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ow2/asm'
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_analysis/3pp/fetch.py b/third_party/android_deps/libs/org_ow2_asm_asm_analysis/3pp/fetch.py
index f770fb5..e7f6b50 100755
--- a/third_party/android_deps/libs/org_ow2_asm_asm_analysis/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_analysis/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ow2/asm'
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_commons/3pp/fetch.py b/third_party/android_deps/libs/org_ow2_asm_asm_commons/3pp/fetch.py
index 71cf040..2c8b858 100755
--- a/third_party/android_deps/libs/org_ow2_asm_asm_commons/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_commons/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ow2/asm'
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_tree/3pp/fetch.py b/third_party/android_deps/libs/org_ow2_asm_asm_tree/3pp/fetch.py
index e6ac25df..70913b0 100755
--- a/third_party/android_deps/libs/org_ow2_asm_asm_tree/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_tree/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ow2/asm'
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_util/3pp/fetch.py b/third_party/android_deps/libs/org_ow2_asm_asm_util/3pp/fetch.py
index f21bd48..9e1cacb 100755
--- a/third_party/android_deps/libs/org_ow2_asm_asm_util/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_util/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/ow2/asm'
diff --git a/third_party/android_deps/libs/org_pcollections_pcollections/3pp/fetch.py b/third_party/android_deps/libs/org_pcollections_pcollections/3pp/fetch.py
index f3201cef..1a52098 100755
--- a/third_party/android_deps/libs/org_pcollections_pcollections/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_pcollections_pcollections/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/pcollections'
diff --git a/third_party/android_deps/libs/org_robolectric_annotations/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_annotations/3pp/fetch.py
index 6aa9a64..6515c48 100755
--- a/third_party/android_deps/libs/org_robolectric_annotations/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_annotations/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_junit/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_junit/3pp/fetch.py
index d333cd3..400dc9fa 100755
--- a/third_party/android_deps/libs/org_robolectric_junit/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_junit/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py
index 62d39a2..63a88aaf 100755
--- a/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_pluginapi/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_pluginapi/3pp/fetch.py
index 71bc20dd..3f95f13 100755
--- a/third_party/android_deps/libs/org_robolectric_pluginapi/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_pluginapi/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/3pp/fetch.py
index ee2bedd..66040b1 100755
--- a/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_resources/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_resources/3pp/fetch.py
index 105dc0e6..85a6a87 100755
--- a/third_party/android_deps/libs/org_robolectric_resources/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_resources/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_robolectric/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_robolectric/3pp/fetch.py
index 58e31d50..5e63558 100755
--- a/third_party/android_deps/libs/org_robolectric_robolectric/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_robolectric/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_sandbox/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_sandbox/3pp/fetch.py
index 3c1b311..d6b3e8a0 100755
--- a/third_party/android_deps/libs/org_robolectric_sandbox/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_sandbox/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_shadowapi/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_shadowapi/3pp/fetch.py
index 8b67e76..d8a7312 100755
--- a/third_party/android_deps/libs/org_robolectric_shadowapi/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_shadowapi/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_framework/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_shadows_framework/3pp/fetch.py
index 7e516990..cd6b00d 100755
--- a/third_party/android_deps/libs/org_robolectric_shadows_framework/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_shadows_framework/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_multidex/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_shadows_multidex/3pp/fetch.py
index f6eec25..ed5f948 100755
--- a/third_party/android_deps/libs/org_robolectric_shadows_multidex/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_shadows_multidex/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_playservices/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_shadows_playservices/3pp/fetch.py
index 32bdee9..f5e0685 100755
--- a/third_party/android_deps/libs/org_robolectric_shadows_playservices/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_shadows_playservices/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_utils/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_utils/3pp/fetch.py
index 9a1a64c..068f245 100755
--- a/third_party/android_deps/libs/org_robolectric_utils/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_utils/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/android_deps/libs/org_robolectric_utils_reflector/3pp/fetch.py b/third_party/android_deps/libs/org_robolectric_utils_reflector/3pp/fetch.py
index c2422c3..01ff4aa 100755
--- a/third_party/android_deps/libs/org_robolectric_utils_reflector/3pp/fetch.py
+++ b/third_party/android_deps/libs/org_robolectric_utils_reflector/3pp/fetch.py
@@ -6,14 +6,11 @@
 # This is generated, do not edit. Update BuildConfigGenerator.groovy and
 # 3ppFetch.template instead.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
 import re
-
-from six.moves import urllib
+import urllib.request
 
 _REPO_URL = 'https://repo.maven.apache.org/maven2'
 _GROUP_NAME = 'org/robolectric'
diff --git a/third_party/blink/common/mediastream/media_stream_request.cc b/third_party/blink/common/mediastream/media_stream_request.cc
index 3f36bd6..619ec31 100644
--- a/third_party/blink/common/mediastream/media_stream_request.cc
+++ b/third_party/blink/common/mediastream/media_stream_request.cc
@@ -109,7 +109,7 @@
       input(other.input),
       session_id_(other.session_id_) {
   DCHECK(!session_id_.has_value() || !session_id_->is_empty());
-  if (other.display_media_info.has_value())
+  if (other.display_media_info)
     display_media_info = other.display_media_info->Clone();
 }
 
@@ -129,7 +129,7 @@
   input = other.input;
   session_id_ = other.session_id_;
   DCHECK(!session_id_.has_value() || !session_id_->is_empty());
-  if (other.display_media_info.has_value())
+  if (other.display_media_info)
     display_media_info = other.display_media_info->Clone();
   return *this;
 }
diff --git a/third_party/blink/public/common/mediastream/media_stream_mojom_traits.h b/third_party/blink/public/common/mediastream/media_stream_mojom_traits.h
index ab3ec14..e8d2aa4 100644
--- a/third_party/blink/public/common/mediastream/media_stream_mojom_traits.h
+++ b/third_party/blink/public/common/mediastream/media_stream_mojom_traits.h
@@ -54,8 +54,8 @@
     return device.serializable_session_id();
   }
 
-  static const absl::optional<media::mojom::DisplayMediaInformationPtr>&
-  display_media_info(const blink::MediaStreamDevice& device) {
+  static const media::mojom::DisplayMediaInformationPtr& display_media_info(
+      const blink::MediaStreamDevice& device) {
     return device.display_media_info;
   }
 
diff --git a/third_party/blink/public/common/mediastream/media_stream_request.h b/third_party/blink/public/common/mediastream/media_stream_request.h
index 14cf0ea..78d5cb5 100644
--- a/third_party/blink/public/common/mediastream/media_stream_request.h
+++ b/third_party/blink/public/common/mediastream/media_stream_request.h
@@ -114,8 +114,8 @@
   media::AudioParameters input =
       media::AudioParameters::UnavailableDeviceParams();
 
-  // This field is optional and available only for display media devices.
-  absl::optional<media::mojom::DisplayMediaInformationPtr> display_media_info;
+  // This field is only non-null for display media devices.
+  media::mojom::DisplayMediaInformationPtr display_media_info;
 
  private:
   // Id for this capture session. Unique for all sessions of the same type.
diff --git a/third_party/blink/public/common/navigation/navigation_params_mojom_traits.h b/third_party/blink/public/common/navigation/navigation_params_mojom_traits.h
index 5249553..9289915 100644
--- a/third_party/blink/public/common/navigation/navigation_params_mojom_traits.h
+++ b/third_party/blink/public/common/navigation/navigation_params_mojom_traits.h
@@ -13,7 +13,7 @@
 namespace mojo {
 
 template <>
-struct CloneTraits<blink::mojom::PrefetchedSignedExchangeInfoPtr, true> {
+struct CloneTraits<blink::mojom::PrefetchedSignedExchangeInfoPtr> {
   static blink::mojom::PrefetchedSignedExchangeInfoPtr Clone(
       const blink::mojom::PrefetchedSignedExchangeInfoPtr& input) {
     return blink::mojom::PrefetchedSignedExchangeInfo::New(
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 06d5fcb..5f83e89 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -471,7 +471,7 @@
     properties
       Page.FrameId frameId
 
-  type SameSiteCookieExclusionReason extends string
+  type CookieExclusionReason extends string
     enum
       ExcludeSameSiteUnspecifiedTreatedAsLax
       ExcludeSameSiteNoneInsecure
@@ -480,7 +480,7 @@
       ExcludeInvalidSameParty
       ExcludeSamePartyCrossPartyContext
 
-  type SameSiteCookieWarningReason extends string
+  type CookieWarningReason extends string
     enum
       WarnSameSiteUnspecifiedCrossSiteContext
       WarnSameSiteNoneInsecure
@@ -491,7 +491,7 @@
       WarnSameSiteLaxCrossDowngradeStrict
       WarnSameSiteLaxCrossDowngradeLax
 
-  type SameSiteCookieOperation extends string
+  type CookieOperation extends string
     enum
       SetCookie
       ReadCookie
@@ -499,7 +499,7 @@
   # This information is currently necessary, as the front-end has a difficult
   # time finding a specific cookie. With this, we can convey specific error
   # information without the cookie.
-  type SameSiteCookieIssueDetails extends object
+  type CookieIssueDetails extends object
     properties
       # If AffectedCookie is not set then rawCookieLine contains the raw
       # Set-Cookie header string. This hints at a problem where the
@@ -507,11 +507,11 @@
       # that no valid cookie could be created.
       optional AffectedCookie cookie
       optional string rawCookieLine
-      array of SameSiteCookieWarningReason cookieWarningReasons
-      array of SameSiteCookieExclusionReason cookieExclusionReasons
+      array of CookieWarningReason cookieWarningReasons
+      array of CookieExclusionReason cookieExclusionReasons
       # Optionally identifies the site-for-cookies and the cookie url, which
       # may be used by the front-end as additional context.
-      SameSiteCookieOperation operation
+      CookieOperation operation
       optional string siteForCookies
       optional string cookieUrl
       optional AffectedRequest request
@@ -814,7 +814,7 @@
   # information about the kind of issue.
   type InspectorIssueCode extends string
     enum
-      SameSiteCookieIssue
+      CookieIssue
       MixedContentIssue
       BlockedByResponseIssue
       HeavyAdIssue
@@ -836,7 +836,7 @@
   # add a new optional field to this type.
   type InspectorIssueDetails extends object
     properties
-      optional SameSiteCookieIssueDetails sameSiteCookieIssueDetails
+      optional CookieIssueDetails cookieIssueDetails
       optional MixedContentIssueDetails mixedContentIssueDetails
       optional BlockedByResponseIssueDetails blockedByResponseIssueDetails
       optional HeavyAdIssueDetails heavyAdIssueDetails
diff --git a/third_party/blink/public/mojom/devtools/inspector_issue.mojom b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
index b3b0af0..0792b72 100644
--- a/third_party/blink/public/mojom/devtools/inspector_issue.mojom
+++ b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
@@ -13,7 +13,7 @@
 // A code that uniquely identifies an issue. This type should be descriptive
 // enough for the front-end to provide a clear description of the issue.
 enum InspectorIssueCode {
-  kSameSiteCookieIssue,
+  kCookieIssue,
   kMixedContentIssue,
   kBlockedByResponseIssue,
   kContentSecurityPolicyIssue,
@@ -107,18 +107,18 @@
   int32 violating_node_id = 0;
 };
 
-enum SameSiteCookieOperation {
+enum CookieOperation {
   kSetCookie, kReadCookie
 };
 
-enum SameSiteCookieExclusionReason {
+enum CookieExclusionReason {
   kExcludeSameSiteUnspecifiedTreatedAsLax,
   kExcludeSameSiteNoneInsecure,
   kExcludeSameSiteLax,
   kExcludeSameSiteStrict,
 };
 
-enum SameSiteCookieWarningReason {
+enum CookieWarningReason {
   kWarnSameSiteUnspecifiedCrossSiteContext,
   kWarnSameSiteNoneInsecure,
   kWarnSameSiteUnspecifiedLaxAllowUnsafe,
@@ -129,12 +129,12 @@
   kWarnSameSiteLaxCrossDowngradeLax,
 };
 
-// Specific information about |kSameSiteCookieIssue| type issues.
-struct SameSiteCookieIssueDetails {
+// Specific information about |kCookieIssue| type issues.
+struct CookieIssueDetails {
   AffectedCookie cookie;
-  array<SameSiteCookieExclusionReason> exclusion_reason;
-  array<SameSiteCookieWarningReason> warning_reason;
-  SameSiteCookieOperation operation;
+  array<CookieExclusionReason> exclusion_reason;
+  array<CookieWarningReason> warning_reason;
+  CookieOperation operation;
   url.mojom.Url? site_for_cookies;
   url.mojom.Url? cookie_url;
   AffectedRequest? request;
@@ -219,7 +219,7 @@
 // A collection of optional fields that may store additional data depending
 // on the issue code.
 struct InspectorIssueDetails {
-  SameSiteCookieIssueDetails? samesite_cookie_issue_details;
+  CookieIssueDetails? cookie_issue_details;
   MixedContentIssueDetails? mixed_content_issue_details;
   BlockedByResponseIssueDetails? blocked_by_response_issue_details;
   ContentSecurityPolicyIssueDetails? csp_issue_details;
diff --git a/third_party/blink/renderer/core/app_history/app_history.cc b/third_party/blink/renderer/core/app_history/app_history.cc
index b216f89..d61f989 100644
--- a/third_party/blink/renderer/core/app_history/app_history.cc
+++ b/third_party/blink/renderer/core/app_history/app_history.cc
@@ -660,7 +660,9 @@
     WebFrameLoadType type,
     UserNavigationInvolvement involvement,
     SerializedScriptValue* state_object,
-    HistoryItem* destination_item) {
+    HistoryItem* destination_item,
+    bool is_browser_initiated,
+    bool is_synchronously_committed) {
   // TODO(japhet): The draft spec says to cancel any ongoing navigate event
   // before invoking DispatchNavigateEvent(), because not all navigations will
   // fire a navigate event, but all should abort an ongoing navigate event.
@@ -756,16 +758,11 @@
   if (!promise_list.IsEmpty()) {
     transition_ = MakeGarbageCollected<AppHistoryTransition>(
         script_state, navigation_type, current());
-    // In order to handle fragment cases (especially browser-initiated ones)
-    // correctly, we need state that only DocumentLoader holds. Defer to
-    // DocumentLoader to run the url and history update steps for the fragment
-    // case, but run it here for other cases.
-    if (event_type != NavigateEventType::kFragment) {
-      GetSupplementable()->document()->Loader()->RunURLAndHistoryUpdateSteps(
-          url,
-          mojom::blink::SameDocumentNavigationType::kAppHistoryTransitionWhile,
-          state_object, type);
-    }
+    GetSupplementable()->document()->Loader()->RunURLAndHistoryUpdateSteps(
+        url, destination_item,
+        mojom::blink::SameDocumentNavigationType::kAppHistoryTransitionWhile,
+        state_object, type, mojom::blink::ScrollRestorationType::kAuto,
+        is_browser_initiated, is_synchronously_committed);
   }
 
   if (!promise_list.IsEmpty() ||
diff --git a/third_party/blink/renderer/core/app_history/app_history.h b/third_party/blink/renderer/core/app_history/app_history.h
index 2ba8cee..24c44f9 100644
--- a/third_party/blink/renderer/core/app_history/app_history.h
+++ b/third_party/blink/renderer/core/app_history/app_history.h
@@ -102,8 +102,10 @@
                                        NavigateEventType,
                                        WebFrameLoadType,
                                        UserNavigationInvolvement,
-                                       SerializedScriptValue* = nullptr,
-                                       HistoryItem* destination_item = nullptr);
+                                       SerializedScriptValue*,
+                                       HistoryItem* destination_item,
+                                       bool is_browser_initiated = false,
+                                       bool is_synchronously_committed = true);
   void InformAboutCanceledNavigation();
 
   int GetIndexFor(AppHistoryEntry*);
diff --git a/third_party/blink/renderer/core/css/transition.css b/third_party/blink/renderer/core/css/transition.css
index ac155c94..b39d556 100644
--- a/third_party/blink/renderer/core/css/transition.css
+++ b/third_party/blink/renderer/core/css/transition.css
@@ -18,6 +18,7 @@
   position: absolute;
   top: 0;
   left: 0;
+  will-change: transform;
 }
 
 html::transition-container(root) {
@@ -38,6 +39,6 @@
   left: 0;
   width: 100%;
   height: 100%;
-  /* TODO(vmpstr): This needs to be updated to plus-lighter */
-  mix-blend-mode: normal;
+  mix-blend-mode: plus-lighter;
+  will-change: opacity;
 }
diff --git a/third_party/blink/renderer/core/fragment_directive/fragment_directive_utils.cc b/third_party/blink/renderer/core/fragment_directive/fragment_directive_utils.cc
index c478de9f..cf5b47e1 100644
--- a/third_party/blink/renderer/core/fragment_directive/fragment_directive_utils.cc
+++ b/third_party/blink/renderer/core/fragment_directive/fragment_directive_utils.cc
@@ -21,7 +21,7 @@
   // fragment shown in the URL matches the state of the highlight on the page.
   // This is equivalent to history.replaceState in javascript.
   frame->DomWindow()->document()->Loader()->RunURLAndHistoryUpdateSteps(
-      url, mojom::blink::SameDocumentNavigationType::kFragment,
+      url, nullptr, mojom::blink::SameDocumentNavigationType::kFragment,
       /*data=*/nullptr, WebFrameLoadType::kReplaceCurrentItem,
       mojom::blink::ScrollRestorationType::kAuto);
 }
diff --git a/third_party/blink/renderer/core/frame/history.cc b/third_party/blink/renderer/core/frame/history.cc
index 88c59a9..be51fc58c 100644
--- a/third_party/blink/renderer/core/frame/history.cc
+++ b/third_party/blink/renderer/core/frame/history.cc
@@ -319,14 +319,14 @@
   if (auto* app_history = AppHistory::appHistory(*DomWindow())) {
     if (app_history->DispatchNavigateEvent(
             full_url, nullptr, NavigateEventType::kHistoryApi, type,
-            UserNavigationInvolvement::kNone,
-            data.get()) != AppHistory::DispatchResult::kContinue) {
+            UserNavigationInvolvement::kNone, data.get(),
+            nullptr) != AppHistory::DispatchResult::kContinue) {
       return;
     }
   }
 
   DomWindow()->document()->Loader()->RunURLAndHistoryUpdateSteps(
-      full_url, mojom::blink::SameDocumentNavigationType::kHistoryApi,
+      full_url, nullptr, mojom::blink::SameDocumentNavigationType::kHistoryApi,
       std::move(data), type, restoration_type);
 }
 
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index 1ae74fb7..6c86609 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -13415,7 +13415,7 @@
       SerializeString("message", ToScriptStateForMainWorld(frame));
   tester.ExpectTotalCount(histogramName, 0);
   document_loader.UpdateForSameDocumentNavigation(
-      ToKURL("about:blank"),
+      ToKURL("about:blank"), nullptr,
       mojom::blink::SameDocumentNavigationType::kHistoryApi, message,
       mojom::blink::ScrollRestorationType::kAuto,
       WebFrameLoadType::kReplaceCurrentItem,
@@ -13426,7 +13426,7 @@
   tester.ExpectBucketCount(histogramName,
                            kSPANavTypeHistoryPushStateOrReplaceState, 1);
   document_loader.UpdateForSameDocumentNavigation(
-      ToKURL("about:blank"),
+      ToKURL("about:blank"), MakeGarbageCollected<HistoryItem>(),
       mojom::blink::SameDocumentNavigationType::kFragment, message,
       mojom::blink::ScrollRestorationType::kManual,
       WebFrameLoadType::kBackForward, frame->DomWindow()->GetSecurityOrigin(),
@@ -13434,7 +13434,7 @@
   tester.ExpectBucketCount(histogramName,
                            kSPANavTypeSameDocumentBackwardOrForward, 1);
   document_loader.UpdateForSameDocumentNavigation(
-      ToKURL("about:blank"),
+      ToKURL("about:blank"), nullptr,
       mojom::blink::SameDocumentNavigationType::kFragment, message,
       mojom::blink::ScrollRestorationType::kManual,
       WebFrameLoadType::kReplaceCurrentItem,
diff --git a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
index cb9364e6..319412f3 100644
--- a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
@@ -41,8 +41,8 @@
 blink::protocol::String InspectorIssueCodeValue(
     mojom::blink::InspectorIssueCode code) {
   switch (code) {
-    case mojom::blink::InspectorIssueCode::kSameSiteCookieIssue:
-      return protocol::Audits::InspectorIssueCodeEnum::SameSiteCookieIssue;
+    case mojom::blink::InspectorIssueCode::kCookieIssue:
+      return protocol::Audits::InspectorIssueCodeEnum::CookieIssue;
     case mojom::blink::InspectorIssueCode::kMixedContentIssue:
       return protocol::Audits::InspectorIssueCodeEnum::MixedContentIssue;
     case mojom::blink::InspectorIssueCode::kBlockedByResponseIssue:
@@ -70,31 +70,26 @@
 }
 
 protocol::String BuildCookieExclusionReason(
-    mojom::blink::SameSiteCookieExclusionReason exclusion_reason) {
+    mojom::blink::CookieExclusionReason exclusion_reason) {
   switch (exclusion_reason) {
-    case blink::mojom::blink::SameSiteCookieExclusionReason::
+    case blink::mojom::blink::CookieExclusionReason::
         kExcludeSameSiteUnspecifiedTreatedAsLax:
-      return protocol::Audits::SameSiteCookieExclusionReasonEnum::
+      return protocol::Audits::CookieExclusionReasonEnum::
           ExcludeSameSiteUnspecifiedTreatedAsLax;
-    case blink::mojom::blink::SameSiteCookieExclusionReason::
+    case blink::mojom::blink::CookieExclusionReason::
         kExcludeSameSiteNoneInsecure:
-      return protocol::Audits::SameSiteCookieExclusionReasonEnum::
+      return protocol::Audits::CookieExclusionReasonEnum::
           ExcludeSameSiteNoneInsecure;
-    case blink::mojom::blink::SameSiteCookieExclusionReason::
-        kExcludeSameSiteLax:
-      return protocol::Audits::SameSiteCookieExclusionReasonEnum::
-          ExcludeSameSiteLax;
-    case blink::mojom::blink::SameSiteCookieExclusionReason::
-        kExcludeSameSiteStrict:
-      return protocol::Audits::SameSiteCookieExclusionReasonEnum::
-          ExcludeSameSiteStrict;
+    case blink::mojom::blink::CookieExclusionReason::kExcludeSameSiteLax:
+      return protocol::Audits::CookieExclusionReasonEnum::ExcludeSameSiteLax;
+    case blink::mojom::blink::CookieExclusionReason::kExcludeSameSiteStrict:
+      return protocol::Audits::CookieExclusionReasonEnum::ExcludeSameSiteStrict;
   }
 }
 
 std::unique_ptr<std::vector<blink::protocol::String>>
 BuildCookieExclusionReasons(
-    const WTF::Vector<mojom::blink::SameSiteCookieExclusionReason>&
-        exclusion_reasons) {
+    const WTF::Vector<mojom::blink::CookieExclusionReason>& exclusion_reasons) {
   auto protocol_exclusion_reasons =
       std::make_unique<std::vector<blink::protocol::String>>();
   for (const auto& reason : exclusion_reasons) {
@@ -104,46 +99,44 @@
 }
 
 protocol::String BuildCookieWarningReason(
-    mojom::blink::SameSiteCookieWarningReason warning_reason) {
+    mojom::blink::CookieWarningReason warning_reason) {
   switch (warning_reason) {
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteUnspecifiedCrossSiteContext:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteUnspecifiedCrossSiteContext;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
-        kWarnSameSiteNoneInsecure:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+    case blink::mojom::blink::CookieWarningReason::kWarnSameSiteNoneInsecure:
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteNoneInsecure;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteUnspecifiedLaxAllowUnsafe:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteUnspecifiedLaxAllowUnsafe;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteStrictLaxDowngradeStrict:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteStrictLaxDowngradeStrict;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteStrictCrossDowngradeStrict:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteStrictCrossDowngradeStrict;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteStrictCrossDowngradeLax:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteStrictCrossDowngradeLax;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteLaxCrossDowngradeStrict:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteLaxCrossDowngradeStrict;
-    case blink::mojom::blink::SameSiteCookieWarningReason::
+    case blink::mojom::blink::CookieWarningReason::
         kWarnSameSiteLaxCrossDowngradeLax:
-      return protocol::Audits::SameSiteCookieWarningReasonEnum::
+      return protocol::Audits::CookieWarningReasonEnum::
           WarnSameSiteLaxCrossDowngradeLax;
   }
 }
 
 std::unique_ptr<std::vector<blink::protocol::String>> BuildCookieWarningReasons(
-    const WTF::Vector<mojom::blink::SameSiteCookieWarningReason>&
-        warning_reasons) {
+    const WTF::Vector<mojom::blink::CookieWarningReason>& warning_reasons) {
   auto protocol_warning_reasons =
       std::make_unique<std::vector<blink::protocol::String>>();
   for (const auto& reason : warning_reasons) {
@@ -151,13 +144,12 @@
   }
   return protocol_warning_reasons;
 }
-protocol::String BuildCookieOperation(
-    mojom::blink::SameSiteCookieOperation operation) {
+protocol::String BuildCookieOperation(mojom::blink::CookieOperation operation) {
   switch (operation) {
-    case blink::mojom::blink::SameSiteCookieOperation::kSetCookie:
-      return protocol::Audits::SameSiteCookieOperationEnum::SetCookie;
-    case blink::mojom::blink::SameSiteCookieOperation::kReadCookie:
-      return protocol::Audits::SameSiteCookieOperationEnum::ReadCookie;
+    case blink::mojom::blink::CookieOperation::kSetCookie:
+      return protocol::Audits::CookieOperationEnum::SetCookie;
+    case blink::mojom::blink::CookieOperation::kReadCookie:
+      return protocol::Audits::CookieOperationEnum::ReadCookie;
   }
 }
 
@@ -335,10 +327,10 @@
 ConvertInspectorIssueToProtocolFormat(InspectorIssue* issue) {
   auto issueDetails = protocol::Audits::InspectorIssueDetails::create();
 
-  if (issue->Details()->samesite_cookie_issue_details) {
-    const auto* d = issue->Details()->samesite_cookie_issue_details.get();
-    auto sameSiteCookieDetails =
-        std::move(protocol::Audits::SameSiteCookieIssueDetails::create()
+  if (issue->Details()->cookie_issue_details) {
+    const auto* d = issue->Details()->cookie_issue_details.get();
+    auto cookieDetails =
+        std::move(protocol::Audits::CookieIssueDetails::create()
                       .setCookie(BuildAffectedCookie(d->cookie))
                       .setCookieExclusionReasons(
                           BuildCookieExclusionReasons(d->exclusion_reason))
@@ -347,15 +339,15 @@
                       .setOperation(BuildCookieOperation(d->operation)));
 
     if (d->site_for_cookies) {
-      sameSiteCookieDetails.setSiteForCookies(*d->site_for_cookies);
+      cookieDetails.setSiteForCookies(*d->site_for_cookies);
     }
     if (d->cookie_url) {
-      sameSiteCookieDetails.setCookieUrl(*d->cookie_url);
+      cookieDetails.setCookieUrl(*d->cookie_url);
     }
     if (d->request) {
-      sameSiteCookieDetails.setRequest(BuildAffectedRequest(d->request));
+      cookieDetails.setRequest(BuildAffectedRequest(d->request));
     }
-    issueDetails.setSameSiteCookieIssueDetails(sameSiteCookieDetails.build());
+    issueDetails.setCookieIssueDetails(cookieDetails.build());
   }
 
   if (issue->Details()->mixed_content_issue_details) {
diff --git a/third_party/blink/renderer/core/layout/OWNERS b/third_party/blink/renderer/core/layout/OWNERS
index ae456c6..7836f30 100644
--- a/third_party/blink/renderer/core/layout/OWNERS
+++ b/third_party/blink/renderer/core/layout/OWNERS
@@ -4,7 +4,6 @@
 fs@opera.com
 pdr@chromium.org
 schenney@chromium.org
-skobes@chromium.org
 tkent@chromium.org
 wangxianzhu@chromium.org
 xiaochengh@chromium.org
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index ebf9a96..3cd41f60 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -2365,28 +2365,6 @@
   // non-empty child content yet (as that would have resolved the BFC offset).
   DCHECK(container_builder_.BfcBlockOffset());
 
-  bool pushed_to_next_fragmentainer_by_float = false;
-  if (layout_result.Status() == NGLayoutResult::kSuccess && child.IsBlock()) {
-    const auto* child_box_fragment =
-        To<NGPhysicalBoxFragment>(&layout_result.PhysicalFragment());
-
-    // If we're at a resumed fragment, don't break before it. Once we've found
-    // room for the first fragment, we cannot skip fragmentainers afterwards. We
-    // might be out of space at a subsequent fragment e.g. if all space is taken
-    // up by a float that got pushed ahead from a previous fragmentainer, but we
-    // still need to allow this fragment here. Inserting a break before on a
-    // node that has already started producing fragments would result in
-    // restarting layout from scratch once we find room for a fragment
-    // again. Preventing breaking here should have no visual effect, since the
-    // block-size of the fragment will typically be 0 anyway.
-    if (!child_box_fragment->IsFirstForNode())
-      return NGBreakStatus::kContinue;
-
-    if (ExclusionSpace().NeedsClearancePastFragmentainer(
-            child.Style().Clear(Style())))
-      pushed_to_next_fragmentainer_by_float = true;
-  }
-
   LayoutUnit fragmentainer_block_offset =
       ConstraintSpace().FragmentainerOffsetAtBfc() + bfc_block_offset -
       layout_result.AnnotationBlockOffsetAdjustment();
@@ -2407,11 +2385,9 @@
       CalculateBreakAppealBefore(ConstraintSpace(), child, layout_result,
                                  container_builder_, has_container_separation);
 
-  // Unless clearance forces the child to the next fragmentainer, attempt to
-  // move past the break point, and if we can do that, also assess the appeal of
-  // breaking there, even if we didn't.
-  if (!pushed_to_next_fragmentainer_by_float &&
-      MovePastBreakpoint(ConstraintSpace(), child, layout_result,
+  // Attempt to move past the break point, and if we can do that, also assess
+  // the appeal of breaking there, even if we didn't.
+  if (MovePastBreakpoint(ConstraintSpace(), child, layout_result,
                          fragmentainer_block_offset, appeal_before,
                          &container_builder_))
     return NGBreakStatus::kContinue;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
index fbcf74fc..3701f530 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -720,6 +720,28 @@
   const auto& physical_fragment = layout_result.PhysicalFragment();
   NGFragment fragment(space.GetWritingDirection(), physical_fragment);
 
+  if (child.IsBlock()) {
+    const auto& box_fragment = To<NGPhysicalBoxFragment>(physical_fragment);
+
+    // If we're at a resumed fragment, don't break before it. Once we've found
+    // room for the first fragment, we cannot skip fragmentainers afterwards. We
+    // might be out of space at a subsequent fragment e.g. if all space is taken
+    // up by a float that got pushed ahead from a previous fragmentainer, but we
+    // still need to allow this fragment here. Inserting a break before on a
+    // node that has already started producing fragments would result in
+    // restarting layout from scratch once we find room for a fragment
+    // again. Preventing breaking here should have no visual effect, since the
+    // block-size of the fragment will typically be 0 anyway.
+    if (!box_fragment.IsFirstForNode())
+      return true;
+
+    // If clearance forces the child to the next fragmentainer, we cannot move
+    // past the breakpoint, but rather retry in the next fragmentainer.
+    if (builder && builder->ExclusionSpace().NeedsClearancePastFragmentainer(
+                       child.Style().Clear(space.Direction())))
+      return false;
+  }
+
   if (!space.HasKnownFragmentainerBlockSize()) {
     if (space.IsInitialColumnBalancingPass() && builder) {
       if (layout_result.PhysicalFragment().IsMonolithic() ||
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 8f849e5..92a05cb 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -709,24 +709,27 @@
 
 void DocumentLoader::RunURLAndHistoryUpdateSteps(
     const KURL& new_url,
+    HistoryItem* history_item,
     mojom::blink::SameDocumentNavigationType same_document_navigation_type,
     scoped_refptr<SerializedScriptValue> data,
     WebFrameLoadType type,
-    mojom::blink::ScrollRestorationType scroll_restoration_type) {
-  DCHECK(!IsBackForwardLoadType(type));
+    mojom::blink::ScrollRestorationType scroll_restoration_type,
+    bool is_browser_initiated,
+    bool is_synchronously_committed) {
   // We use the security origin of this frame since callers of this method must
   // already have performed same origin checks.
   // is_browser_initiated is false and is_synchronously_committed is true
   // because anything invoking this algorithm is a renderer-initiated navigation
   // in this process.
   UpdateForSameDocumentNavigation(
-      new_url, same_document_navigation_type, std::move(data),
+      new_url, history_item, same_document_navigation_type, std::move(data),
       scroll_restoration_type, type, frame_->DomWindow()->GetSecurityOrigin(),
-      false /* is_browser_initiated */, true /* is_synchronously_committed */);
+      is_browser_initiated, is_synchronously_committed);
 }
 
 void DocumentLoader::UpdateForSameDocumentNavigation(
     const KURL& new_url,
+    HistoryItem* history_item,
     mojom::blink::SameDocumentNavigationType same_document_navigation_type,
     scoped_refptr<SerializedScriptValue> data,
     mojom::blink::ScrollRestorationType scroll_restoration_type,
@@ -734,6 +737,8 @@
     const SecurityOrigin* initiator_origin,
     bool is_browser_initiated,
     bool is_synchronously_committed) {
+  DCHECK_EQ(IsBackForwardLoadType(type), !!history_item);
+
   SinglePageAppNavigationType single_page_app_navigation_type =
       CategorizeSinglePageAppNavigation(same_document_navigation_type, type);
   UMA_HISTOGRAM_ENUMERATION(
@@ -743,6 +748,9 @@
   TRACE_EVENT1("blink", "FrameLoader::updateForSameDocumentNavigation", "url",
                new_url.GetString().Ascii());
 
+  if (history_item)
+    history_item_ = history_item;
+
   // Generate start and stop notifications only when loader is completed so that
   // we don't fire them for fragment redirection that happens in window.onload
   // handler. See https://bugs.webkit.org/show_bug.cgi?id=31838
@@ -1317,16 +1325,12 @@
     }
     auto dispatch_result = app_history->DispatchNavigateEvent(
         url, nullptr, NavigateEventType::kFragment, frame_load_type,
-        involvement, nullptr, history_item);
+        involvement, nullptr, history_item, is_browser_initiated,
+        is_synchronously_committed);
     if (dispatch_result == AppHistory::DispatchResult::kAbort)
       return mojom::blink::CommitResult::Aborted;
-    // In the kTransitionWhile case, fall through and let the commit proceed
-    // normally, just with the  mojom::blink::SameDocumentNavigationType
-    // modified.
-    if (dispatch_result == AppHistory::DispatchResult::kTransitionWhile) {
-      same_document_navigation_type =
-          mojom::blink::SameDocumentNavigationType::kAppHistoryTransitionWhile;
-    }
+    if (dispatch_result == AppHistory::DispatchResult::kTransitionWhile)
+      return mojom::blink::CommitResult::Ok;
   }
 
   // If the requesting document is cross-origin, perform the navigation
@@ -1417,10 +1421,8 @@
   bool same_item_sequence_number =
       history_item_ && history_item &&
       history_item_->ItemSequenceNumber() == history_item->ItemSequenceNumber();
-  if (history_item)
-    history_item_ = history_item;
   UpdateForSameDocumentNavigation(
-      url, same_document_navigation_type, nullptr,
+      url, history_item, same_document_navigation_type, nullptr,
       mojom::blink::ScrollRestorationType::kAuto, frame_load_type,
       initiator_origin, is_browser_initiated, is_synchronously_committed);
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
index 30cac0e..d67f5a4 100644
--- a/third_party/blink/renderer/core/loader/document_loader.h
+++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -167,17 +167,19 @@
   void DidObserveLoadingBehavior(LoadingBehaviorFlag);
 
   // https://html.spec.whatwg.org/multipage/history.html#url-and-history-update-steps
-  void RunURLAndHistoryUpdateSteps(
-      const KURL&,
-      mojom::blink::SameDocumentNavigationType,
-      scoped_refptr<SerializedScriptValue>,
-      WebFrameLoadType = WebFrameLoadType::kReplaceCurrentItem,
-      mojom::blink::ScrollRestorationType =
-          mojom::blink::ScrollRestorationType::kAuto);
+  void RunURLAndHistoryUpdateSteps(const KURL&,
+                                   HistoryItem*,
+                                   mojom::blink::SameDocumentNavigationType,
+                                   scoped_refptr<SerializedScriptValue>,
+                                   WebFrameLoadType,
+                                   mojom::blink::ScrollRestorationType,
+                                   bool is_browser_initiated = false,
+                                   bool is_synchronously_committed = true);
 
   // |is_synchronously_committed| is described in comment for
   // CommitSameDocumentNavigation.
   void UpdateForSameDocumentNavigation(const KURL&,
+                                       HistoryItem*,
                                        mojom::blink::SameDocumentNavigationType,
                                        scoped_refptr<SerializedScriptValue>,
                                        mojom::blink::ScrollRestorationType,
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc
index 8ab32bb9..d7b2da6 100644
--- a/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -775,8 +775,8 @@
               request.GetTriggeringEventInfo() ==
                       mojom::blink::TriggeringEventInfo::kFromTrustedEvent
                   ? UserNavigationInvolvement::kActivation
-                  : UserNavigationInvolvement::kNone) !=
-          AppHistory::DispatchResult::kContinue) {
+                  : UserNavigationInvolvement::kNone,
+              nullptr, nullptr) != AppHistory::DispatchResult::kContinue) {
         return;
       }
     }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index e195db9..45ea7ce8 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2279,7 +2279,7 @@
 void Internals::triggerTestInspectorIssue(Document* document) {
   DCHECK(document);
   auto info = mojom::blink::InspectorIssueInfo::New(
-      mojom::InspectorIssueCode::kSameSiteCookieIssue,
+      mojom::InspectorIssueCode::kCookieIssue,
       mojom::blink::InspectorIssueDetails::New());
   document->GetFrame()->AddInspectorIssue(std::move(info));
 }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
index 4eaaab13..6d0d6e39 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
@@ -14,7 +14,7 @@
     [NoAllocDirectCall, RaisesException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius);
     [NoAllocDirectCall] void rect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height);
     [RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, sequence<(unrestricted double or DOMPointInit)> radii);
-    [RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, (unrestricted double or DOMPointInit) radii);
+    [RaisesException] void roundRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h, optional (unrestricted double or DOMPointInit) radii = 0);
 
     [NoAllocDirectCall, RaisesException] void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
     [NoAllocDirectCall, RaisesException] void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
index 8305cb0..befcbde 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -705,8 +705,8 @@
   settings.resize_mode = WebString::FromASCII(std::string(
       adapter_settings().target_size() ? WebMediaStreamTrack::kResizeModeRescale
                                        : WebMediaStreamTrack::kResizeModeNone));
-  if (source_->device().display_media_info.has_value()) {
-    const auto& info = source_->device().display_media_info.value();
+  if (source_->device().display_media_info) {
+    const auto& info = source_->device().display_media_info;
     settings.display_surface = info->display_surface;
     settings.logical_surface = info->logical_surface;
     settings.cursor = info->cursor;
@@ -724,11 +724,11 @@
   }
 
   const MediaStreamDevice& device = source_->device();
-  if (!device.display_media_info.has_value()) {
+  if (!device.display_media_info) {
     return capture_handle;
   }
   const media::mojom::DisplayMediaInformationPtr& info =
-      device.display_media_info.value();
+      device.display_media_info;
 
   if (!info->capture_handle) {
     return capture_handle;
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_details.cc b/third_party/blink/renderer/modules/screen_enumeration/screen_details.cc
index e98a523..3ea9769 100644
--- a/third_party/blink/renderer/modules/screen_enumeration/screen_details.cc
+++ b/third_party/blink/renderer/modules/screen_enumeration/screen_details.cc
@@ -19,7 +19,8 @@
     : ExecutionContextLifecycleObserver(window) {
   LocalFrame* frame = window->GetFrame();
   const auto& screen_infos = frame->GetChromeClient().GetScreenInfos(*frame);
-  UpdateScreenInfos(window, screen_infos);
+  // Do not dispatch change events during class initialization.
+  UpdateScreenInfosImpl(window, screen_infos, /*dispatch_events=*/false);
 }
 
 const HeapVector<Member<ScreenDetailed>>& ScreenDetails::screens() const {
@@ -59,16 +60,22 @@
 
 void ScreenDetails::UpdateScreenInfos(LocalDOMWindow* window,
                                       const display::ScreenInfos& new_infos) {
+  UpdateScreenInfosImpl(window, new_infos, /*dispatch_events=*/true);
+}
+
+void ScreenDetails::UpdateScreenInfosImpl(LocalDOMWindow* window,
+                                          const display::ScreenInfos& new_infos,
+                                          bool dispatch_events) {
   // Expect that all updates contain a non-zero set of screens.
   DCHECK(!new_infos.screen_infos.empty());
 
-  // (1) Detect if the set of screens has changed, and update screens_.
+  // (1) Detect if screens were added or removed and update web exposed data.
   bool added_or_removed = false;
 
   // O(displays) should be small, so O(n^2) check in both directions
   // instead of keeping some more efficient cache of display ids.
 
-  // Check if any screens have been removed and remove them from screens_.
+  // Check if any screens have been removed and remove them from `screens_`.
   for (WTF::wtf_size_t i = 0; i < screens_.size();
        /*conditionally incremented*/) {
     if (base::Contains(new_infos.screen_infos, screens_[i]->DisplayId(),
@@ -82,8 +89,7 @@
     }
   }
 
-  // Check if any screens have been added, and append them to the end of
-  // screens_.
+  // Check if any screens have been added, and append them to `screens_`.
   for (const auto& info : new_infos.screen_infos) {
     if (!base::Contains(screens_, info.display_id,
                         &ScreenDetailed::DisplayId)) {
@@ -94,66 +100,65 @@
     }
   }
 
-  // screens is sorted by dimensions, x first and then y.
+  // Sort `screens_` by position; x first and then y.
   base::ranges::stable_sort(screens_, [](ScreenDetailed* a, ScreenDetailed* b) {
     if (a->left() != b->left())
       return a->left() < b->left();
     return a->top() < b->top();
   });
 
-  // Update current_display_id_ so that currentScreen() is up to date
-  // before we send out any events.
+  // Update current_display_id_ for currentScreen() before event dispatch.
   current_display_id_ = new_infos.current_display_id;
 
-  // (2) At this point, all data structures are up to date.
-  // screens_ has the current set of screens.
-  // current_screen_ has new values pushed to it.
+  // (2) At this point, all web exposed data is updated.
+  // `screens_` has the updated set of screens.
+  // `current_display_id_` has the updated value.
   // (prior to this function) individual ScreenDetailed objects have new values.
-
-  // (3) Send a change event if the current screen has changed.
-  if (prev_screen_infos_.screen_infos.empty() ||
-      prev_screen_infos_.current().display_id !=
-          new_infos.current().display_id ||
-      !ScreenDetailed::AreWebExposedScreenDetailedPropertiesEqual(
-          prev_screen_infos_.current(), new_infos.current())) {
-    DispatchEvent(*Event::Create(event_type_names::kCurrentscreenchange));
-  }
-
-  // (4) Send a change event if the set of screens has changed.
-  if (added_or_removed) {
-    // Allow fullscreen requests shortly after user-generated screens changes.
-    // TODO(enne): consider doing this only when screens have been added.
-    LocalFrame* frame = window->GetFrame();
-    frame->ActivateTransientAllowFullscreen();
-
-    DispatchEvent(*Event::Create(event_type_names::kScreenschange));
-  }
-
-  // (5) Send change events to individual screens if they have changed.
-  // It's not guaranteed that screen_infos are ordered, so for each screen
-  // find the info that corresponds to it in old_info and new_infos.
   //
-  // Note: we cannot use an iterator-based loop here, as iterators may be
-  // invalidated by DispatchEvent(), which may call ContextDestroyed().
-  for (wtf_size_t i = 0; i < screens_.size(); ++i) {
-    const auto& screen = screens_[i];
-    auto id = screen->DisplayId();
-    auto new_it = base::ranges::find(new_infos.screen_infos, id,
-                                     &display::ScreenInfo::display_id);
-    DCHECK(new_it != new_infos.screen_infos.end());
-    auto old_it = base::ranges::find(prev_screen_infos_.screen_infos, id,
-                                     &display::ScreenInfo::display_id);
-    if (old_it != prev_screen_infos_.screen_infos.end() &&
-        !ScreenDetailed::AreWebExposedScreenDetailedPropertiesEqual(*old_it,
-                                                                    *new_it)) {
-      screen->DispatchEvent(*Event::Create(event_type_names::kChange));
+  // Enqueue events for dispatch if `dispatch_events` is true.
+  // Enqueuing event dispatch avoids recursion if screen changes occur while an
+  // event handler is running a nested event loop, e.g. via window.print().
+  if (dispatch_events) {
+    // Enqueue a change event if the current screen has changed.
+    if (prev_screen_infos_.screen_infos.empty() ||
+        prev_screen_infos_.current().display_id !=
+            new_infos.current().display_id ||
+        !ScreenDetailed::AreWebExposedScreenDetailedPropertiesEqual(
+            prev_screen_infos_.current(), new_infos.current())) {
+      EnqueueEvent(*Event::Create(event_type_names::kCurrentscreenchange),
+                   TaskType::kMiscPlatformAPI);
+    }
 
-      // Note: screen may no longer be valid and screens_ may have been
-      // cleared at this point via DispatchEvent calling ContextDestroyed.
+    // Enqueue a change event if screens were added or removed.
+    if (added_or_removed) {
+      // Allow fullscreen requests shortly after user-generated screens changes.
+      // TODO(enne): consider doing this only when screens have been added.
+      window->GetFrame()->ActivateTransientAllowFullscreen();
+
+      EnqueueEvent(*Event::Create(event_type_names::kScreenschange),
+                   TaskType::kMiscPlatformAPI);
+    }
+
+    // Enqueue change events for any individual screens that changed.
+    // It's not guaranteed that screen_infos are ordered, so for each screen
+    // find the info that corresponds to it in old_info and new_infos.
+    for (Member<ScreenDetailed>& screen : screens_) {
+      auto id = screen->DisplayId();
+      auto new_it = base::ranges::find(new_infos.screen_infos, id,
+                                       &display::ScreenInfo::display_id);
+      DCHECK(new_it != new_infos.screen_infos.end());
+      auto old_it = base::ranges::find(prev_screen_infos_.screen_infos, id,
+                                       &display::ScreenInfo::display_id);
+      if (old_it != prev_screen_infos_.screen_infos.end() &&
+          !ScreenDetailed::AreWebExposedScreenDetailedPropertiesEqual(
+              *old_it, *new_it)) {
+        screen->EnqueueEvent(*Event::Create(event_type_names::kChange),
+                             TaskType::kMiscPlatformAPI);
+      }
     }
   }
 
-  // (6) Store screen infos for change comparison next time.
+  // (3) Store screen infos for change comparison next time.
   //
   // Aside: Because ScreenDetailed is a "live" thin wrapper over the ScreenInfo
   // object owned by WidgetBase, WidgetBase's copy needs to be updated
diff --git a/third_party/blink/renderer/modules/screen_enumeration/screen_details.h b/third_party/blink/renderer/modules/screen_enumeration/screen_details.h
index 2ff1688b..e9eea0e 100644
--- a/third_party/blink/renderer/modules/screen_enumeration/screen_details.h
+++ b/third_party/blink/renderer/modules/screen_enumeration/screen_details.h
@@ -43,12 +43,18 @@
 
   void Trace(Visitor*) const override;
 
-  // Called when there is a visual property update with potentially new
-  // multi-screen information.
+  // Called on visual property updates with potentially new screen information.
+  // Update web-exposed data structures and enqueues events for dispatch.
   void UpdateScreenInfos(LocalDOMWindow* window,
                          const display::ScreenInfos& new_infos);
 
  private:
+  // Update web-exposed data structures on screen information changes.
+  // Enqueues events for dispatch if `dispatch_events` is true.
+  void UpdateScreenInfosImpl(LocalDOMWindow* window,
+                             const display::ScreenInfos& new_infos,
+                             bool dispatch_events);
+
   // Returns the first unused index, starting at one.  Internal and external
   // are numbered separately.  This is used for ScreenDetailed::label strings.
   uint32_t GetNewLabelIdx(bool is_internal);
diff --git a/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc b/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
index 28a0725..4196350 100644
--- a/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/decoder_template_test.cc
@@ -149,7 +149,8 @@
 }
 
 // Ensures codecs do not apply reclamation pressure by default.
-TYPED_TEST(DecoderTemplateTest, NoPressureByDefault) {
+// Sheriff 2022/02/25; flaky test crbug/1300845
+TYPED_TEST(DecoderTemplateTest, DISABLED_NoPressureByDefault) {
   V8TestingScope v8_scope;
 
   // Create a decoder.
diff --git a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
index 467e634d..6ac92e9 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/web_platform_media_stream_source.cc
@@ -56,12 +56,11 @@
 void WebPlatformMediaStreamSource::SetCaptureHandle(
     media::mojom::CaptureHandlePtr capture_handle) {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  if (!device_.display_media_info.has_value()) {
+  if (!device_.display_media_info) {
     DVLOG(1) << "Not a display-capture device.";
     return;
   }
-  auto& info = device_.display_media_info.value();
-  info->capture_handle = std::move(capture_handle);
+  device_.display_media_info->capture_handle = std::move(capture_handle);
 }
 
 void WebPlatformMediaStreamSource::SetStopCallback(
diff --git a/third_party/blink/renderer/platform/graphics/bitmap_image.cc b/third_party/blink/renderer/platform/graphics/bitmap_image.cc
index 054ac06..016df6b4 100644
--- a/third_party/blink/renderer/platform/graphics/bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/bitmap_image.cc
@@ -311,12 +311,11 @@
 
   const cc::PaintFlags* image_flags = &flags;
   absl::optional<cc::PaintFlags> dark_mode_flags;
-  if (draw_options.apply_dark_mode) {
+  if (auto* dark_mode_filter = draw_options.dark_mode_filter) {
     dark_mode_flags = flags;
-    DarkModeFilter* dark_mode_filter = draw_options.dark_mode_filter;
-    DarkModeFilterHelper::ApplyToImageIfNeeded(
-        *dark_mode_filter, this, &dark_mode_flags.value(),
-        gfx::RectFToSkRect(src_rect), gfx::RectFToSkRect(dst_rect));
+    DarkModeFilterHelper::ApplyFilterToImage(*dark_mode_filter, this,
+                                             &dark_mode_flags.value(),
+                                             gfx::RectFToSkRect(src_rect));
     image_flags = &dark_mode_flags.value();
   }
   canvas->drawImageRect(
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index 47b466f..613d059 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -116,6 +116,7 @@
   // Here check layer_bounds because RasterInvalidator doesn't issue raster
   // invalidation when only layer_bounds changes.
   if (cc_display_item_list_ && layer_bounds == old_layer_bounds &&
+      cc_picture_layer_->draws_content() == pending_layer.DrawsContent() &&
       !raster_under_invalidation_params) {
     DCHECK_EQ(cc_picture_layer_->bounds(), layer_bounds);
     return cc_picture_layer_;
@@ -128,17 +129,7 @@
 
   cc_picture_layer_->SetBounds(layer_bounds);
   cc_picture_layer_->SetHitTestable(true);
-  // TODO(wangxianzhu): Use SetIsDrawable(pending_layer.DrawsContent()) when
-  // it's accurate. For now it only covers a subset of drawing content
-  // conditions (i.e. the following DCHECK).
-  DCHECK(!pending_layer.DrawsContent() ||
-         cc_display_item_list_->TotalOpCount());
-  cc_picture_layer_->SetIsDrawable(
-      (!layer_bounds.IsEmpty() && cc_display_item_list_->TotalOpCount()) ||
-      // Backdrop effects and filters require the layer to be drawable even if
-      // the layer draws nothing.
-      layer_state.Effect().HasBackdropEffect() ||
-      !layer_state.Effect().Filter().IsEmpty());
+  cc_picture_layer_->SetIsDrawable(pending_layer.DrawsContent());
 
   return cc_picture_layer_;
 }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 40e63d7..9993bbd 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -492,7 +492,8 @@
 void PaintArtifactCompositor::LayerizeGroup(
     const PaintChunkSubset& chunks,
     const EffectPaintPropertyNode& current_group,
-    PaintChunkIterator& chunk_cursor) {
+    PaintChunkIterator& chunk_cursor,
+    bool force_draws_content) {
   wtf_size_t first_layer_in_current_group = pending_layers_.size();
   // The worst case time complexity of the algorithm is O(pqd), where
   // p = the number of paint chunks.
@@ -521,6 +522,9 @@
     if (&chunk_effect == &current_group) {
       pending_layers_.emplace_back(chunks, chunk_cursor);
       ++chunk_cursor;
+      // force_draws_content doesn't apply to pending layers that require own
+      // layer, specifically scrollbar layers, foreign layers, scroll hit
+      // testing layers.
       if (pending_layers_.back().RequiresOwnLayer())
         continue;
     } else {
@@ -533,7 +537,8 @@
       // Case C: The following chunks belong to a subgroup. Process them by
       //         a recursion call.
       wtf_size_t first_layer_in_subgroup = pending_layers_.size();
-      LayerizeGroup(chunks, *subgroup, chunk_cursor);
+      LayerizeGroup(chunks, *subgroup, chunk_cursor,
+                    force_draws_content || subgroup->DrawsContent());
       // The above LayerizeGroup generated new layers in pending_layers_
       // [first_layer_in_subgroup .. pending_layers.size() - 1]. If it
       // generated 2 or more layer that we already know can't be merged
@@ -552,6 +557,8 @@
     PendingLayer& new_layer = pending_layers_.back();
     DCHECK(!new_layer.RequiresOwnLayer());
     DCHECK_EQ(&current_group, &new_layer.GetPropertyTreeState().Effect());
+    if (force_draws_content)
+      new_layer.ForceDrawsContent();
     // This iterates pending_layers_[first_layer_in_current_group:-1] in
     // reverse.
     for (wtf_size_t candidate_index = pending_layers_.size() - 1;
@@ -575,7 +582,8 @@
   pending_layers_.Shrink(0);
   PaintChunkSubset subset(artifact);
   auto cursor = subset.begin();
-  LayerizeGroup(subset, EffectPaintPropertyNode::Root(), cursor);
+  LayerizeGroup(subset, EffectPaintPropertyNode::Root(), cursor,
+                /*force_draws_content*/ false);
   DCHECK(cursor == subset.end());
   pending_layers_.ShrinkToReasonableCapacity();
 }
@@ -788,7 +796,7 @@
 
   host->property_trees()
       ->effect_tree_mutable()
-      .ClearSharedElementResourceIdToNodeMap();
+      .ClearTransitionPseudoElementEffectNodes();
   cc::LayerSelection layer_selection;
   for (const auto& pending_layer : pending_layers_) {
     const auto& property_state = pending_layer.GetPropertyTreeState();
@@ -860,7 +868,7 @@
     if (shared_element_id.IsValid()) {
       host->property_trees()
           ->effect_tree_mutable()
-          .SetSharedElementResourceIdForNodeId(effect_id, shared_element_id);
+          .AddTransitionPseudoElementEffectId(effect_id);
     }
   }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
index eb11cda..c041cd7 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
@@ -268,7 +268,8 @@
   // can be satisfied (and the effect node has no direct reason).
   void LayerizeGroup(const PaintChunkSubset&,
                      const EffectPaintPropertyNode&,
-                     PaintChunkIterator& chunk_cursor);
+                     PaintChunkIterator& chunk_cursor,
+                     bool force_draws_content);
   bool DecompositeEffect(const EffectPaintPropertyNode& parent_effect,
                          wtf_size_t first_layer_in_parent_group_index,
                          const EffectPaintPropertyNode& effect,
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 799f330..da64487 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -3482,10 +3482,10 @@
   auto c1 = CreateClip(c0(), t0(), rrect);
   auto c2 = CreateClip(*c1, t0(), FloatRoundedRect(60, 60, 200, 100));
 
-  auto e1 =
-      CreateOpacityEffect(e0(), t0(), c2.get(), 0.5, CompositingReason::kAll);
-  auto e2 =
-      CreateOpacityEffect(e0(), t0(), c1.get(), 0.75, CompositingReason::kAll);
+  auto e1 = CreateOpacityEffect(e0(), t0(), c2.get(), 0.5,
+                                CompositingReason::kWillChangeOpacity);
+  auto e2 = CreateOpacityEffect(e0(), t0(), c1.get(), 0.75,
+                                CompositingReason::kWillChangeOpacity);
 
   TestPaintArtifact artifact;
   artifact.Chunk(t0(), *c2, *e1)
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
index 0ced152..44e6bf7 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.cc
@@ -96,6 +96,8 @@
   if (const absl::optional<gfx::RectF>& visibility_limit =
           VisibilityLimit(property_tree_state_)) {
     bounds_.Intersect(*visibility_limit);
+    if (bounds_.IsEmpty())
+      draws_content_ = false;
   }
 
   if (IsCompositedScrollHitTest(first_chunk)) {
@@ -156,6 +158,7 @@
     json_chunks->PushString(sb.ToString());
   }
   result->SetArray("paint_chunks", std::move(json_chunks));
+  result->SetBoolean("draws_content", DrawsContent());
   return result;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
index c046bef..969dcea 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/pending_layer.h
@@ -93,6 +93,7 @@
 
   std::unique_ptr<JSONObject> ToJSON() const;
 
+  void ForceDrawsContent() { draws_content_ = true; }
   bool DrawsContent() const { return draws_content_; }
 
   bool RequiresOwnLayer() const {
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index c79a812..9d7de0b 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -674,7 +674,7 @@
   // clip, thus the clip can't be shared with sibling layers, and must be
   // closed now.
   bool clear_synthetic_effects =
-      !IsCurrentCcEffectSynthetic() && current_.effect->HasBackdropEffect();
+      !IsCurrentCcEffectSynthetic() && current_.effect->MayHaveBackdropEffect();
 
   // We are about to close an effect that was synthesized for isolating
   // a clip mask. Now emit the actual clip mask that will be composited on
@@ -887,7 +887,7 @@
     const EffectPaintPropertyNode* next_effect) {
   int backdrop_effect_clip_id = cc::kInvalidPropertyNodeId;
   bool should_realize_backdrop_effect = false;
-  if (next_effect && next_effect->HasBackdropEffect()) {
+  if (next_effect && next_effect->MayHaveBackdropEffect()) {
     // Exit all synthetic effect node if the next child has backdrop effect
     // (exotic blending mode or backdrop filter) because it has to access the
     // backdrop of enclosing effect.
@@ -1180,7 +1180,7 @@
   effect_node.opacity = effect.Opacity();
   const auto& transform = effect.LocalTransformSpace().Unalias();
   effect_node.transform_id = EnsureCompositorTransformNode(transform);
-  if (effect.HasBackdropEffect()) {
+  if (effect.MayHaveBackdropEffect()) {
     // We never have backdrop effect and filter on the same effect node.
     DCHECK(effect.Filter().IsEmpty());
     if (auto* backdrop_filter = effect.BackdropFilter()) {
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index 23545cc..596c595 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -93,9 +93,19 @@
   return color;
 }
 
+bool DarkModeFilter::ShouldApplyFilterToImage(const SkIRect& dst,
+                                              const SkIRect& src) const {
+  DarkModeImagePolicy image_policy = GetDarkModeImagePolicy();
+  if (image_policy == DarkModeImagePolicy::kFilterNone)
+    return false;
+  if (image_policy == DarkModeImagePolicy::kFilterAll)
+    return true;
+  return ImageShouldHaveFilterAppliedBasedOnSizes(dst, src);
+}
+
 bool DarkModeFilter::ImageShouldHaveFilterAppliedBasedOnSizes(
-    const SkIRect& src,
-    const SkIRect& dst) const {
+    const SkIRect& dst,
+    const SkIRect& src) const {
   // Images being drawn from very smaller |src| rect, i.e. one of the dimensions
   // is very small, can be used for the border around the content or showing
   // separator. Consider these images irrespective of size of the rect being
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
index 6166a9cd..9c6c52b4 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -41,15 +41,8 @@
 
   size_t GetInvertedColorCacheSizeForTesting();
 
-  // Decides whether to apply dark mode or not based on |src| and |dst|.
-  // DarkModeResult::kDoNotApplyFilter - Dark mode filter should not be applied.
-  // DarkModeResult::kApplyFilter - Dark mode filter should be applied and to
-  // get the color filter GetImageFilter() should be called.
-  // DarkModeResult::kNotClassified - Dark mode filter should be applied and to
-  // get the color filter ApplyToImage() should be called. This API is
-  // thread-safe.
-  bool ImageShouldHaveFilterAppliedBasedOnSizes(const SkIRect& src,
-                                                const SkIRect& dst) const;
+  // Decides whether to apply dark mode or not.
+  bool ShouldApplyFilterToImage(const SkIRect& dst, const SkIRect& src) const;
 
   // Returns dark mode color filter based on the classification done on
   // |pixmap|. The image cannot be classified if pixmap is empty or |src| is
@@ -80,6 +73,10 @@
     sk_sp<SkColorFilter> image_filter;
   };
 
+  // Decides whether to apply dark mode or not based on |dst| and |src|.
+  bool ImageShouldHaveFilterAppliedBasedOnSizes(const SkIRect& dst,
+                                                const SkIRect& src) const;
+
   bool ShouldApplyToColor(SkColor color, ElementRole role);
 
   // This is read-only data and is thread-safe.
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.cc
index 3fda931..4c3f34d19 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.cc
@@ -68,42 +68,33 @@
 }  // namespace
 
 // static
-void DarkModeFilterHelper::ApplyToImageIfNeeded(DarkModeFilter& filter,
-                                                Image* image,
-                                                cc::PaintFlags* flags,
-                                                const SkRect& src,
-                                                const SkRect& dst) {
+void DarkModeFilterHelper::ApplyFilterToImage(DarkModeFilter& filter,
+                                              Image* image,
+                                              cc::PaintFlags* flags,
+                                              const SkRect& src) {
   DCHECK(image);
   DCHECK(flags);
+  DCHECK_NE(filter.GetDarkModeImagePolicy(), DarkModeImagePolicy::kFilterNone);
 
-  DarkModeImagePolicy image_policy = filter.GetDarkModeImagePolicy();
-  if (image_policy == DarkModeImagePolicy::kFilterNone)
-    return;
-
-  if (image_policy == DarkModeImagePolicy::kFilterAll) {
+  if (filter.GetDarkModeImagePolicy() == DarkModeImagePolicy::kFilterAll) {
     flags->setColorFilter(filter.GetImageFilter());
     return;
   }
 
-  SkIRect rounded_src = src.roundOut();
-  SkIRect rounded_dst = dst.roundOut();
-  if (filter.ImageShouldHaveFilterAppliedBasedOnSizes(rounded_src,
-                                                      rounded_dst)) {
-    // Raster-side dark mode path - Just set the dark mode on flags and dark
-    // mode will be applied at compositor side during rasterization.
-    if (ShouldUseRasterSidePath(image)) {
-      flags->setUseDarkModeForImage(true);
-      return;
-    }
-
-    // Blink-side dark mode path - Apply dark mode to images in main thread
-    // only. If the result is not cached, calling this path is expensive and
-    // will block main thread.
-    sk_sp<SkColorFilter> color_filter =
-        GetDarkModeFilterForImageOnMainThread(filter, image, rounded_src);
-    if (color_filter)
-      flags->setColorFilter(std::move(color_filter));
+  // Raster-side dark mode path - Just set the dark mode on flags and dark
+  // mode will be applied at compositor side during rasterization.
+  if (ShouldUseRasterSidePath(image)) {
+    flags->setUseDarkModeForImage(true);
+    return;
   }
+
+  // Blink-side dark mode path - Apply dark mode to images in main thread
+  // only. If the result is not cached, calling this path is expensive and
+  // will block main thread.
+  sk_sp<SkColorFilter> color_filter =
+      GetDarkModeFilterForImageOnMainThread(filter, image, src.roundOut());
+  if (color_filter)
+    flags->setColorFilter(std::move(color_filter));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h
index 075ffb2..d3eda07 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h
@@ -19,11 +19,10 @@
 
 class PLATFORM_EXPORT DarkModeFilterHelper {
  public:
-  static void ApplyToImageIfNeeded(DarkModeFilter& filter,
-                                   Image* image,
-                                   cc::PaintFlags* flags,
-                                   const SkRect& src,
-                                   const SkRect& dst);
+  static void ApplyFilterToImage(DarkModeFilter& filter,
+                                 Image* image,
+                                 cc::PaintFlags* flags,
+                                 const SkRect& src);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
index dc17e463e..23772671 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -122,39 +122,39 @@
   EXPECT_EQ(2u, filter.GetInvertedColorCacheSizeForTesting());
 }
 
-TEST(DarkModeFilterTest, ImageShouldHaveFilterAppliedBasedOnSizes) {
+TEST(DarkModeFilterTest, ShouldApplyFilterToImage) {
   DarkModeSettings settings;
   settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   settings.image_policy = DarkModeImagePolicy::kFilterSmart;
   DarkModeFilter filter(settings);
 
   // |dst| is smaller than threshold size.
-  EXPECT_TRUE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(100, 100), SkIRect::MakeWH(100, 100)));
+  EXPECT_TRUE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(100, 100),
+                                              SkIRect::MakeWH(100, 100)));
 
   // |dst| is smaller than threshold size, even |src| is larger.
-  EXPECT_TRUE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(200, 200), SkIRect::MakeWH(100, 100)));
+  EXPECT_TRUE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(100, 100),
+                                              SkIRect::MakeWH(200, 200)));
 
   // |dst| is smaller than threshold size, |src| is smaller.
-  EXPECT_TRUE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(20, 20), SkIRect::MakeWH(100, 100)));
+  EXPECT_TRUE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(100, 100),
+                                              SkIRect::MakeWH(20, 20)));
 
   // |src| having very smaller width, even |dst| is larger than threshold size.
-  EXPECT_TRUE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(5, 200), SkIRect::MakeWH(5, 200)));
+  EXPECT_TRUE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(200, 5),
+                                              SkIRect::MakeWH(200, 5)));
 
   // |src| having very smaller height, even |dst| is larger than threshold size.
-  EXPECT_TRUE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(200, 5), SkIRect::MakeWH(200, 5)));
+  EXPECT_TRUE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(5, 200),
+                                              SkIRect::MakeWH(5, 200)));
 
   // |dst| is larger than threshold size.
-  EXPECT_FALSE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(20, 20), SkIRect::MakeWH(200, 200)));
+  EXPECT_FALSE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(200, 200),
+                                               SkIRect::MakeWH(20, 20)));
 
   // |dst| is larger than threshold size.
-  EXPECT_FALSE(filter.ImageShouldHaveFilterAppliedBasedOnSizes(
-      SkIRect::MakeWH(20, 200), SkIRect::MakeWH(20, 200)));
+  EXPECT_FALSE(filter.ShouldApplyFilterToImage(SkIRect::MakeWH(20, 200),
+                                               SkIRect::MakeWH(20, 200)));
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index 52e4103..9f4d264 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -169,6 +169,20 @@
   return dark_mode_filter_.get();
 }
 
+DarkModeFilter* GraphicsContext::GetDarkModeFilterForImage(
+    const AutoDarkMode& auto_dark_mode,
+    const gfx::RectF& dest,
+    const gfx::RectF& src) {
+  if (!auto_dark_mode.enabled)
+    return nullptr;
+  DarkModeFilter* dark_mode_filter = GetDarkModeFilter();
+  if (!dark_mode_filter->ShouldApplyFilterToImage(
+          gfx::RectFToSkRect(dest).roundOut(),
+          gfx::RectFToSkRect(src).roundOut()))
+    return nullptr;
+  return dark_mode_filter;
+}
+
 void GraphicsContext::UpdateDarkModeSettingsForTest(
     const DarkModeSettings& settings) {
   dark_mode_filter_ = std::make_unique<DarkModeFilter>(settings);
@@ -746,16 +760,16 @@
     return;
 
   const gfx::RectF src = src_ptr ? *src_ptr : gfx::RectF(image->Rect());
-
   cc::PaintFlags image_flags = ImmutableState()->FillFlags();
   image_flags.setBlendMode(op);
   image_flags.setColor(SK_ColorBLACK);
 
   SkSamplingOptions sampling = ComputeSamplingOptions(image, dest, src);
+  DarkModeFilter* dark_mode_filter =
+      GetDarkModeFilterForImage(auto_dark_mode, dest, src);
   ImageDrawOptions draw_options(
-      auto_dark_mode.enabled ? GetDarkModeFilter() : nullptr, sampling,
-      should_respect_image_orientation, Image::kClampImageToSourceRect,
-      decode_mode, auto_dark_mode.enabled);
+      dark_mode_filter, sampling, should_respect_image_orientation,
+      Image::kClampImageToSourceRect, decode_mode, auto_dark_mode.enabled);
 
   image->Draw(canvas_, image_flags, dest, src, draw_options);
   paint_controller_.SetImagePainted();
@@ -791,10 +805,11 @@
   image_flags.setBlendMode(op);
   image_flags.setColor(SK_ColorBLACK);
 
-  ImageDrawOptions draw_options(
-      auto_dark_mode.enabled ? GetDarkModeFilter() : nullptr, sampling,
-      respect_orientation, Image::kClampImageToSourceRect, decode_mode,
-      auto_dark_mode.enabled);
+  DarkModeFilter* dark_mode_filter =
+      GetDarkModeFilterForImage(auto_dark_mode, dest.Rect(), src_rect);
+  ImageDrawOptions draw_options(dark_mode_filter, sampling, respect_orientation,
+                                Image::kClampImageToSourceRect, decode_mode,
+                                auto_dark_mode.enabled);
 
   bool use_shader = (visible_src == src_rect) &&
                     (respect_orientation == kDoNotRespectImageOrientation ||
@@ -863,10 +878,11 @@
   cc::PaintFlags image_flags = ImmutableState()->FillFlags();
   image_flags.setBlendMode(op);
   SkSamplingOptions sampling = ImageSamplingOptions();
-  ImageDrawOptions draw_options(
-      auto_dark_mode.enabled ? GetDarkModeFilter() : nullptr, sampling,
-      respect_orientation, Image::kClampImageToSourceRect, Image::kSyncDecode,
-      auto_dark_mode.enabled);
+  DarkModeFilter* dark_mode_filter = GetDarkModeFilterForImage(
+      auto_dark_mode, dest_rect, tiling_info.image_rect);
+  ImageDrawOptions draw_options(dark_mode_filter, sampling, respect_orientation,
+                                Image::kClampImageToSourceRect,
+                                Image::kSyncDecode, auto_dark_mode.enabled);
 
   image->DrawPattern(*this, image_flags, dest_rect, tiling_info, draw_options);
   paint_controller_.SetImagePainted();
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.h b/third_party/blink/renderer/platform/graphics/graphics_context.h
index 89ea4a5..b02e77d8 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.h
@@ -156,6 +156,9 @@
   }
 
   DarkModeFilter* GetDarkModeFilter();
+  DarkModeFilter* GetDarkModeFilterForImage(const AutoDarkMode& auto_dark_mode,
+                                            const gfx::RectF& dest,
+                                            const gfx::RectF& src);
 
   void UpdateDarkModeSettingsForTest(const DarkModeSettings&);
 
diff --git a/third_party/blink/renderer/platform/graphics/image.cc b/third_party/blink/renderer/platform/graphics/image.cc
index 0f3aede1..05d6c9cc 100644
--- a/third_party/blink/renderer/platform/graphics/image.cc
+++ b/third_party/blink/renderer/platform/graphics/image.cc
@@ -292,11 +292,9 @@
   cc::PaintFlags flags(base_flags);
   flags.setColor(tile_shader ? SK_ColorBLACK : SK_ColorTRANSPARENT);
   flags.setShader(std::move(tile_shader));
-  if (draw_options.apply_dark_mode) {
-    DarkModeFilter* dark_mode_filter = draw_options.dark_mode_filter;
-    DarkModeFilterHelper::ApplyToImageIfNeeded(*dark_mode_filter, this, &flags,
-                                               gfx::RectToSkRect(subset_rect),
-                                               gfx::RectFToSkRect(dest_rect));
+  if (auto* dark_mode_filter = draw_options.dark_mode_filter) {
+    DarkModeFilterHelper::ApplyFilterToImage(*dark_mode_filter, this, &flags,
+                                             gfx::RectToSkRect(subset_rect));
   }
 
   context.DrawRect(gfx::RectFToSkRect(dest_rect), flags,
@@ -341,11 +339,9 @@
   if (!image)
     return false;
 
-  if (draw_options.apply_dark_mode) {
-    DarkModeFilter* dark_mode_filter = draw_options.dark_mode_filter;
-    DarkModeFilterHelper::ApplyToImageIfNeeded(*dark_mode_filter, this, &flags,
-                                               gfx::RectFToSkRect(src_rect),
-                                               gfx::RectFToSkRect(dst_rect));
+  if (auto* dark_mode_filter = draw_options.dark_mode_filter) {
+    DarkModeFilterHelper::ApplyFilterToImage(*dark_mode_filter, this, &flags,
+                                             gfx::RectFToSkRect(src_rect));
   }
   flags.setShader(PaintShader::MakeImage(image, SkTileMode::kClamp,
                                          SkTileMode::kClamp, &local_matrix));
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 50eaa7b..eb8a989 100644
--- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -266,11 +266,36 @@
            CompositingReason::kWillChangeBackdropFilter;
   }
 
+  // True if opacity is not 1.0, or could become non-1.0 without a compositing
+  // update via a compositor animation or direct update.
+  bool MayHaveOpacity() const {
+    return Opacity() != 1.0f || HasActiveOpacityAnimation() ||
+           RequiresCompositingForWillChangeOpacity();
+  }
+  // True if the filter is not empty, or could become non-empty without a
+  // compositing update via a compositor animation or direct update.
+  bool MayHaveFilter() const {
+    return !Filter().IsEmpty() || HasActiveFilterAnimation() ||
+           RequiresCompositingForWillChangeFilter();
+  }
+  // True if the backdrop filter is not empty, or could become non-empty
+  // without a compositing update via a compositor animation or direct update.
+  bool MayHaveBackdropFilter() const {
+    return BackdropFilter() || HasActiveBackdropFilterAnimation() ||
+           RequiresCompositingForWillChangeBackdropFilter();
+  }
+
   // Whether the effect node uses the backdrop as an input. This includes
   // exotic blending modes and backdrop filters.
-  bool HasBackdropEffect() const {
-    return BlendMode() != SkBlendMode::kSrcOver || BackdropFilter() ||
-           HasActiveBackdropFilterAnimation();
+  bool MayHaveBackdropEffect() const {
+    return BlendMode() != SkBlendMode::kSrcOver || MayHaveBackdropFilter();
+  }
+
+  // True if this effect can produce drawable content on its own. For example,
+  // a drop-shadow filter will draw a drop shadow even if the filtered content
+  // is entirely empty.
+  bool DrawsContent() const {
+    return MayHaveFilter() || MayHaveBackdropEffect();
   }
 
   CompositingReasons DirectCompositingReasonsForDebugging() const {
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
index 4a44d70a..42862df 100644
--- a/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc
@@ -76,10 +76,11 @@
   StringBuilder sb;
   sb.AppendFormat(
       "PaintChunk(begin=%u, end=%u, id=%s cacheable=%d props=(%s) bounds=%s "
-      "rect_known_to_be_opaque=%s effectively_invisible=%d",
+      "rect_known_to_be_opaque=%s effectively_invisible=%d drawscontent=%d",
       c.begin_index, c.end_index, id_string.Utf8().c_str(), c.is_cacheable,
       c.properties.ToString().Utf8().c_str(), c.bounds.ToString().c_str(),
-      c.rect_known_to_be_opaque.ToString().c_str(), c.effectively_invisible);
+      c.rect_known_to_be_opaque.ToString().c_str(), c.effectively_invisible,
+      c.DrawsContent());
   if (c.hit_test_data) {
     sb.Append(", hit_test_data=");
     sb.Append(c.hit_test_data->ToString());
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_source.cc b/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
index 50eba8692..88efbd2 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
@@ -305,8 +305,8 @@
   }
 
   auto capture_handle = media::mojom::CaptureHandle::New();
-  if (device.display_media_info.has_value()) {
-    capture_handle = device.display_media_info.value()->capture_handle.Clone();
+  if (device.display_media_info) {
+    capture_handle = device.display_media_info->capture_handle.Clone();
   }
 
   platform_source_->SetCaptureHandle(capture_handle.Clone());
diff --git a/third_party/blink/renderer/platform/widget/input/OWNERS b/third_party/blink/renderer/platform/widget/input/OWNERS
index 9468b2232..7937fc63 100644
--- a/third_party/blink/renderer/platform/widget/input/OWNERS
+++ b/third_party/blink/renderer/platform/widget/input/OWNERS
@@ -1,3 +1,4 @@
 dtapuska@chromium.org
 bokan@chromium.org
 flackr@chromium.org
+skobes@chromium.org
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
index 7801cf3..198c195d 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
@@ -181,14 +181,20 @@
 
 void ElasticOverscrollController::Overscroll(
     const gfx::Vector2dF& overscroll_delta) {
-  // The effect can be dynamically disabled by setting disallowing user
+  gfx::Vector2dF adjusted_overscroll_delta = overscroll_delta;
+
+  // The effect can be dynamically disabled by setting styles to disallow user
   // scrolling. When disabled, disallow active or momentum overscrolling, but
   // allow any current overscroll to animate back.
-  if (!helper_->IsUserScrollable())
+  if (!helper_->IsUserScrollableHorizontal())
+    adjusted_overscroll_delta.set_x(0);
+  if (!helper_->IsUserScrollableVertical())
+    adjusted_overscroll_delta.set_y(0);
+
+  if (adjusted_overscroll_delta.IsZero())
     return;
 
-  gfx::Vector2dF adjusted_overscroll_delta =
-      pending_overscroll_delta_ + overscroll_delta;
+  adjusted_overscroll_delta += pending_overscroll_delta_;
   pending_overscroll_delta_ = gfx::Vector2dF();
 
   // TODO (arakeri): Make this prefer the writing mode direction instead.
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
index e31daf62..11bcc4a 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
@@ -24,10 +24,8 @@
 
   // cc::ScrollElasticityHelper implementation:
   Size ScrollBounds() const override { return Size(1000, 1000); }
-  bool IsUserScrollable() const override { return is_user_scrollable_; }
-  void SetUserScrollable(bool is_user_scrollable) {
-    is_user_scrollable_ = is_user_scrollable;
-  }
+  bool IsUserScrollableHorizontal() const override { return true; }
+  bool IsUserScrollableVertical() const override { return true; }
   Vector2dF StretchAmount() const override { return stretch_amount_; }
   void SetStretchAmount(const Vector2dF& stretch_amount) override {
     stretch_amount_ = stretch_amount;
@@ -44,7 +42,6 @@
   }
 
  private:
-  bool is_user_scrollable_ = true;
   Vector2dF stretch_amount_;
   gfx::PointF scroll_offset_, max_scroll_offset_;
 };
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
index 84a287c..466d0906 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
@@ -38,14 +38,16 @@
 
 class MockScrollElasticityHelper : public cc::ScrollElasticityHelper {
  public:
-  MockScrollElasticityHelper()
-      : is_user_scrollable_(true),
-        set_stretch_amount_count_(0),
-        request_begin_frame_count_(0) {}
-  ~MockScrollElasticityHelper() override {}
+  MockScrollElasticityHelper() = default;
+  ~MockScrollElasticityHelper() override = default;
 
   // cc::ScrollElasticityHelper implementation:
-  bool IsUserScrollable() const override { return is_user_scrollable_; }
+  bool IsUserScrollableHorizontal() const override {
+    return is_user_scrollable_horizontal_;
+  }
+  bool IsUserScrollableVertical() const override {
+    return is_user_scrollable_vertical_;
+  }
   Vector2dF StretchAmount() const override { return stretch_amount_; }
   void SetStretchAmount(const Vector2dF& stretch_amount) override {
     set_stretch_amount_count_ += 1;
@@ -67,15 +69,17 @@
     scroll_offset_ = scroll_offset;
     max_scroll_offset_ = max_scroll_offset;
   }
-  void SetUserScrollable(bool is_user_scrollable) {
-    is_user_scrollable_ = is_user_scrollable;
+  void SetUserScrollable(bool horizontal, bool vertical) {
+    is_user_scrollable_horizontal_ = horizontal;
+    is_user_scrollable_vertical_ = vertical;
   }
 
  private:
-  bool is_user_scrollable_;
+  bool is_user_scrollable_horizontal_ = true;
+  bool is_user_scrollable_vertical_ = true;
   Vector2dF stretch_amount_;
-  int set_stretch_amount_count_;
-  int request_begin_frame_count_;
+  int set_stretch_amount_count_ = 0;
+  int request_begin_frame_count_ = 0;
 
   gfx::PointF scroll_offset_;
   gfx::PointF max_scroll_offset_;
@@ -362,7 +366,7 @@
   Vector2dF delta(0, -15);
 
   // Do an active scroll, and ensure that the stretch amount doesn't change.
-  helper_.SetUserScrollable(false);
+  helper_.SetUserScrollable(false, false);
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, delta, delta);
   SendGestureScrollUpdate(NonMomentumPhase, delta, delta);
@@ -377,7 +381,7 @@
   EXPECT_EQ(0, helper_.set_stretch_amount_count());
 
   // Re-enable user scrolling and ensure that stretching is re-enabled.
-  helper_.SetUserScrollable(true);
+  helper_.SetUserScrollable(true, true);
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, delta, delta);
   SendGestureScrollUpdate(NonMomentumPhase, delta, delta);
@@ -393,7 +397,7 @@
 
   // Disable user scrolling and tick the timer until the stretch goes back
   // to zero. Ensure that the return to zero doesn't happen immediately.
-  helper_.SetUserScrollable(false);
+  helper_.SetUserScrollable(false, false);
   int ticks_to_zero = 0;
   while (true) {
     TickCurrentTimeAndAnimate();
@@ -404,6 +408,42 @@
   EXPECT_GT(ticks_to_zero, 3);
 }
 
+TEST_F(ElasticOverscrollControllerExponentialTest, UserScrollableSingleAxis) {
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::PointF(0, 0),
+                                            gfx::PointF(10, 10));
+  Vector2dF vertical_delta(0, -15);
+  Vector2dF horizontal_delta(-15, 0);
+
+  // Attempt vertical scroll when only horizontal allowed.
+  helper_.SetUserScrollable(true, false);
+  SendGestureScrollBegin(NonMomentumPhase);
+  SendGestureScrollUpdate(NonMomentumPhase, vertical_delta, vertical_delta);
+  SendGestureScrollEnd();
+  EXPECT_EQ(helper_.StretchAmount(), Vector2dF(0, 0));
+  EXPECT_EQ(0, helper_.set_stretch_amount_count());
+
+  // Attempt horizontal scroll when only vertical allowed.
+  helper_.SetUserScrollable(false, true);
+  SendGestureScrollBegin(NonMomentumPhase);
+  SendGestureScrollUpdate(NonMomentumPhase, horizontal_delta, horizontal_delta);
+  SendGestureScrollEnd();
+  EXPECT_EQ(helper_.StretchAmount(), Vector2dF(0, 0));
+  EXPECT_EQ(0, helper_.set_stretch_amount_count());
+
+  // Vertical scroll, only vertical allowed.
+  SendGestureScrollBegin(NonMomentumPhase);
+  SendGestureScrollUpdate(NonMomentumPhase, vertical_delta, vertical_delta);
+  SendGestureScrollEnd();
+  EXPECT_LT(helper_.StretchAmount().y(), 0);
+
+  // Horizontal scroll, only horizontal allowed.
+  helper_.SetUserScrollable(true, false);
+  SendGestureScrollBegin(NonMomentumPhase);
+  SendGestureScrollUpdate(NonMomentumPhase, horizontal_delta, horizontal_delta);
+  SendGestureScrollEnd();
+  EXPECT_LT(helper_.StretchAmount().x(), 0);
+}
+
 // Verify that OverscrollBehaviorTypeNone disables the stretching on the
 // specified axis.
 TEST_F(ElasticOverscrollControllerExponentialTest, OverscrollBehavior) {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 637d5ae..f33c83e 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2840,6 +2840,7 @@
 crbug.com/1299212 [ Linux ] fast/forms/week/week-picker-ax.html [ Failure Pass ]
 crbug.com/1299212 [ Linux ] fast/forms/month/month-picker-ax.html [ Failure Pass ]
 crbug.com/1299212 [ Linux ] fast/forms/calendar-picker/date-picker-ax.html [ Failure Pass ]
+crbug.com/1299212 [ Linux ] fast/forms/select-popup/popup-menu-ax.html [ Failure Pass ]
 
 # isInputPending requires threaded compositing and layerized iframes
 crbug.com/910421 external/wpt/is-input-pending/* [ Skip ]
@@ -3332,6 +3333,10 @@
 crbug.com/626703 virtual/prerender/external/wpt/speculation-rules/prerender/workers.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac11 ] external/wpt/scroll-to-text-fragment/force-load-at-top.html [ Timeout ]
+crbug.com/626703 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/registered-property-invalidation-002.https.html [ Failure ]
+crbug.com/626703 external/wpt/geolocation-API/idlharness.https.window.html [ Skip Timeout ]
+crbug.com/626703 [ Mac11 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/background-repeat-x.https.html [ Failure ]
 crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ]
 crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy-attribute.https.sub.html [ Timeout ]
 crbug.com/626703 external/wpt/geolocation-API/enabled-by-feature-policy.https.sub.html [ Timeout ]
@@ -3349,7 +3354,6 @@
 crbug.com/626703 external/wpt/wasm/webapi/esm-integration/worker-import.tentative.html [ Timeout ]
 crbug.com/626703 external/wpt/wasm/webapi/esm-integration/worker.tentative.html [ Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/one-custom-property-animation.https.html [ Failure Timeout ]
-crbug.com/626703 [ Mac11 ] external/wpt/geolocation-API/getCurrentPosition_IDL.https.html [ Failure Skip Timeout ]
 crbug.com/626703 [ Mac10.15 ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/navigate-ancestor.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/content-security-policy/inside-worker/serviceworker-connect-src.https.sub.html [ Timeout ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/no-auto-wpt-origin-isolation/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/popups/opener-no-openee-yes-port.sub.https.html [ Timeout ]
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations
index 023c32d..8618546 100644
--- a/third_party/blink/web_tests/WebGPUExpectations
+++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -517,6 +517,12 @@
 crbug.com/dawn/1125 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,rendering,depth_clip_clamp:depth_clamp_and_clip:clampDepth=false;writeDepth=true;* [ Failure ]
 crbug.com/dawn/1125 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,rendering,depth_clip_clamp:depth_test_input_clamped:clampDepth=false;* [ Failure ]
 
+# Fails on Linux Intel only
+crbug.com/tint/1367 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,countTrailingZeros:integer_builtin_functions,countTrailingZeros_signed:* [ Failure ]
+crbug.com/tint/1367 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,countTrailingZeros:integer_builtin_functions,countTrailingZeros_unsigned:* [ Failure ]
+crbug.com/tint/1367 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,firstTrailingBit:integer_builtin_functions,firstTrailingBit_signed:* [ Failure ]
+crbug.com/tint/1367 [ Linux ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,firstTrailingBit:integer_builtin_functions,firstTrailingBit_unsigned:* [ Failure ]
+
 ###
 ### Windows (D3D12) specific
 ###
@@ -584,4 +590,8 @@
 
 # FXC failures on Windows
 crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,memory_model,barrier:workgroup_barrier_store_load:* [ Failure ]
-crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,memory_model,weak:message_passing_workgroup_memory:* [ Failure ]
\ No newline at end of file
+crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,memory_model,weak:message_passing_workgroup_memory:* [ Failure ]
+
+crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,insertBits:integer_builtin_functions,insertBits:* [ Failure ]
+crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,extractBits:integer_builtin_functions,extractBits_unsigned:* [ Failure ]
+crbug.com/tint/1452 [ Win ] wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,builtin,extractBits:integer_builtin_functions,extractBits_signed:* [ Failure ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 49b6476a..e2b047fb 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 8e7c3e5b87b0d39b3ae84818422c4525917b2f34
+Version: 1500cd163f896d78806d7ed0454808816d656fa6
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 f6e2c9c..57a52147 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
@@ -87,6 +87,13 @@
        {}
       ]
      ],
+     "delayed-ignored-change.html": [
+      "1fc98a10805a58dcd9e73c1bab2a472cf06f69f0",
+      [
+       null,
+       {}
+      ]
+     ],
      "displaylocked-serialize.html": [
       "76784291b441566da93071ed92b959829a59c846",
       [
@@ -1305,6 +1312,13 @@
       ]
      ],
      "crashtests": {
+      "chrome-bug-1293905.html": [
+       "2f1bd84528f5f6da7337f3cdae2ad77520d59a7a",
+       [
+        null,
+        {}
+       ]
+      ],
       "chrome-bug-1297118.html": [
        "5c96614db2da6ff4d5f91c3540765e85602a1ec2",
        [
@@ -1354,6 +1368,13 @@
         {}
        ]
       ],
+      "nested-multicol-and-float-with-tall-padding-before-float.html": [
+       "2a901d1f582f7a17864f9a0b0b0d6afc495dcd21",
+       [
+        null,
+        {}
+       ]
+      ],
       "nested-multicol-and-float-with-tall-padding.html": [
        "8eabef27f42df0178c01054bfa5644ce8cb52434",
        [
@@ -1720,6 +1741,13 @@
        null,
        {}
       ]
+     ],
+     "textarea-large-padding-crash.html": [
+      "b156c55b9705fc6038c7c9ee31e98800a158212e",
+      [
+       null,
+       {}
+      ]
      ]
     },
     "css-tables": {
@@ -1815,6 +1843,13 @@
         {}
        ]
       ],
+      "move-oof-inside-section-row-with-borders.html": [
+       "f6fef22ea723874f31ef68ddb432ebfb0835f32b",
+       [
+        null,
+        {}
+       ]
+      ],
       "negative_caption_margin.html": [
        "cd3c4f4bf7a83ea59ae4b97aaab94bfe3df2fb7b",
        [
@@ -2425,6 +2460,13 @@
        {}
       ]
      ],
+     "strip-space-crash.xml": [
+      "61a906a5e74b9c88061c565615187f9970baff72",
+      [
+       null,
+       {}
+      ]
+     ],
      "transformToFragment-on-node-from-inactive-document-crash.html": [
       "38a62a0a9d9c2979603c68bcea07f48f8ddbd40c",
       [
@@ -3770,15 +3812,6 @@
       ]
      ]
     }
-   },
-   "xslt": {
-    "strip-space-crash.xml": [
-     "61a906a5e74b9c88061c565615187f9970baff72",
-     [
-      null,
-      {}
-     ]
-    ]
    }
   },
   "manual": {
@@ -79820,6 +79853,97 @@
         {}
        ]
       ],
+      "multi-line-row-flex-fragmentation-032.html": [
+       "274f88a794fe1783abe7d6c580ca7c3eb8a58144",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-033.html": [
+       "eaf1aefc4a6dd37fcde82f42d7e44b1f87b024a8",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-034.html": [
+       "0fb81034688c221d0167ba5f1b45a4ef6b699e8a",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-035.html": [
+       "43653071aea705cd3e7156325c4580dcbfc8f5ff",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-036.html": [
+       "013c9e2013797d222d72fb88ae0e8d8e3a20cb52",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-037.html": [
+       "62bf337d850a912c528c4cac6cbde587d33d4da1",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "multi-line-row-flex-fragmentation-038.html": [
+       "e745987aec8377f59aa8e87c6df04effd0753521",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "single-line-column-flex-fragmentation-001.html": [
        "d1411f9a16a14585b945408b162182ed343419d2",
        [
@@ -80469,6 +80593,58 @@
         ],
         {}
        ]
+      ],
+      "single-line-row-flex-fragmentation-019.html": [
+       "149338a7e184f7f6d0b0f63dd3cbdc4c940b85d8",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "single-line-row-flex-fragmentation-020.html": [
+       "3fe75a4e4310a0db38311553ed1781f42e2fbd39",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "single-line-row-flex-fragmentation-021.html": [
+       "d4e29dd815625cd95e53b301753920223101de78",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "single-line-row-flex-fragmentation-022.html": [
+       "4d64641e4c4cc8f95eef8a3f0f5162125ee7fcaf",
+       [
+        null,
+        [
+         [
+          "/css/reference/ref-filled-green-100px-square.xht",
+          "=="
+         ]
+        ],
+        {}
+       ]
       ]
      },
      "float-000.html": [
@@ -133576,6 +133752,19 @@
        {}
       ]
      ],
+     "balance-break-avoidance-002.html": [
+      "4506ef6add52ead40e8fd9cd1326e1e1dba6e813",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square-only.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "balance-grid-container.html": [
       "64df23e09fb62c6e71aa834c96b72d4bf2330f06",
       [
@@ -206126,6 +206315,19 @@
        {}
       ]
      ],
+     "backdrop-filter-plus-will-change-opacity.html": [
+      "250a13e0f4227f25bee728fcc3cce25872ce84c0",
+      [
+       null,
+       [
+        [
+         "/css/filter-effects/reference/backdrop-filter-plus-will-change-opacity-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "backdrop-filter-reference-filter.html": [
       "60a51d674d6119e411a7600e3dc604e894832144",
       [
@@ -207662,6 +207864,19 @@
        {}
       ]
      ],
+     "repaint-added-backdrop-filter.html": [
+      "6678ba4358d1f41e3a71215af374df8ca130c5c7",
+      [
+       null,
+       [
+        [
+         "/css/filter-effects/reference/repaint-added-backdrop-filter-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "root-element-with-opacity-filter-001.html": [
       "577e2bd4c032799a159c1c7542812e66081bfcea",
       [
@@ -246314,10 +246529,6 @@
        "81e1ba5e89ba840e12b22c5475412827d6db71f5",
        []
       ],
-      "never-match-container-expected.txt": [
-       "b0da6841e3c2ecd1ea4c41112f4f099e3e9c92be",
-       []
-      ],
       "percentage-padding-orthogonal-expected.txt": [
        "7dde7f870c4d04ff81e8727b5e90aec1f79907de",
        []
@@ -278178,7 +278389,7 @@
       []
      ],
      "idlharness-expected.txt": [
-      "b4383d5de46e5c400aa7adea84fb857ac6fe97c9",
+      "4b2f21ac5efef55d1127d3f748ffd0e3e0675a70",
       []
      ],
      "iframe.html": [
@@ -278774,6 +278985,10 @@
       []
      ],
      "reference": {
+      "backdrop-filter-plus-will-change-opacity-ref.html": [
+       "56c6243809bef53423ff18d4b70a8597795cacec",
+       []
+      ],
       "backdrop-filters-grayscale-001-ref.html": [
        "ba01ac6bd07464a829817dbfc8e72438c7c97168",
        []
@@ -278942,6 +279157,10 @@
        "bde2a93360b62fcf877c270815f252b5ea0c3191",
        []
       ],
+      "repaint-added-backdrop-filter-ref.html": [
+       "caaa3061edaffc443dd949605adb5ab546ade564",
+       []
+      ],
       "root-element-with-opacity-filter-001-ref.html": [
        "cd16e54c8e5b73b02585c606d0133bb36c821b31",
        []
@@ -291499,7 +291718,7 @@
          []
         ],
         "path-objects.yaml": [
-         "e6ac79585eb76a61511e942df95f0a3e1786d798",
+         "bdabfd66cf92cef516ed406542c5fc42ff5d7436",
          []
         ],
         "pixel-manipulation.yaml": [
@@ -292724,7 +292943,7 @@
       []
      ],
      "idlharness.worker-expected.txt": [
-      "0e04c9174c346bb33240b482245fab61e1eab32c",
+      "f241abe2fe769ff4b87e34e7761dc701e6fc315f",
       []
      ],
      "new-harness.js": [
@@ -307470,6 +307689,22 @@
      "563fa6720ba3a89d6ad8add86cd903465fe456f2",
      []
     ],
+    "MediaStreamTrackGenerator-in-service-worker.https-expected.txt": [
+     "cfab5d10859d4b7df8422ef1fa89f73f1365c7a4",
+     []
+    ],
+    "MediaStreamTrackGenerator-in-shared-worker.https-expected.txt": [
+     "1bc00727ca33d15f53d9c41f9660d2229e486482",
+     []
+    ],
+    "MediaStreamTrackGenerator-in-worker.https-expected.txt": [
+     "43c364f20a26228f2cee181dc93e28c031149788",
+     []
+    ],
+    "MediaStreamTrackGenerator-pipes-data-in-worker.https-expected.txt": [
+     "df92162d3842b7f0e814d46fae1921a9195442c6",
+     []
+    ],
     "MediaStreamTrackProcessor-worker.js": [
      "51eaef80a90a6e24fce8cad4fee03e05548e4517",
      []
@@ -307614,6 +307849,10 @@
      "59a51268f3a3ede5d0d8c903f20e0bb7b5a83a68",
      []
     ],
+    "MediaStreamTrack-transfer.https-expected.txt": [
+     "356c60272e09b286efdca298e31f6f883eeff8d7",
+     []
+    ],
     "OWNERS": [
      "cc43ec1bbbb855066a4311812296c1cff7bf1d15",
      []
@@ -309197,7 +309436,7 @@
    },
    "permissions": {
     "META.yml": [
-     "b055f50f636848ceb7b1750484cc12328a121398",
+     "6a05abee46495f1eddfea549d6ec07cf7ff622b8",
      []
     ],
     "all-permissions-expected.txt": [
@@ -314539,6 +314778,18 @@
         "fac0d8de2a7361aa2f55fdcde87b969a952b92d8",
         []
        ],
+       "samesite-iframe.html": [
+        "a28b61261e82aece0e394e91802e8b98bb6e94ee",
+        []
+       ],
+       "samesite-sw-helper.html": [
+        "51fdc9ec74bd0ab3ac7000db49ac07e82cf8a825",
+        []
+       ],
+       "samesite-worker.js": [
+        "f30e5ed274dd560b4c5a33ddab364221ef644a13",
+        []
+       ],
        "wait-for-activate-worker.js": [
         "87791d2e487db7d83725d14215eff08125b05762",
         []
@@ -363740,7 +363991,7 @@
        ]
       ],
       "at-container-parsing.html": [
-       "fc6cbbdd0440f05d35ab3f8093891f157453814a",
+       "993b059acc8d36a0718a372add918f9545e4c3b7",
        [
         null,
         {}
@@ -363824,7 +364075,7 @@
        ]
       ],
       "container-name-parsing.html": [
-       "4fc6a1757f4266123463db9d3b156495e0a3fc46",
+       "77c8d0129c9d78041600d66b5b2217153e604b41",
        [
         null,
         {}
@@ -363950,7 +364201,7 @@
        ]
       ],
       "display-contents.html": [
-       "55df5df5be0cbe5ec48fd3dedc6c3e63b90f6bad",
+       "de5dd16ff6b95d8e2d0c026c75031471f23402ad",
        [
         null,
         {}
@@ -389942,7 +390193,7 @@
        ]
       ],
       "user-action-pseudo-classes-in-has.html": [
-       "bb6be827b5c0df0251f5c6a0247607c3371f58ee",
+       "466e8610fdb91a0fc27fd30cf49a7d675bec39a4",
        [
         null,
         {
@@ -423313,15 +423564,6 @@
       }
      ]
     ],
-    "getCurrentPosition_IDL.https.html": [
-     "c7ee10e7eb883f8eb7571065cf7925472d548c94",
-     [
-      null,
-      {
-       "timeout": "long"
-      }
-     ]
-    ],
     "getCurrentPosition_TypeError.https.html": [
      "953efb259bf931bce9c45e126a9938b0f0cbdafd",
      [
@@ -423346,7 +423588,7 @@
      ]
     ],
     "idlharness.https.window.js": [
-     "98c407c9bc31865dd1f73833d3e28a8f01ce4fac",
+     "57cbf59d208a5c9744bdbcb73e183268bb16bf97",
      [
       "geolocation-API/idlharness.https.window.html",
       {
@@ -423358,6 +423600,14 @@
         [
          "script",
          "/resources/idlharness.js"
+        ],
+        [
+         "script",
+         "/resources/testdriver.js"
+        ],
+        [
+         "script",
+         "/resources/testdriver-vendor.js"
         ]
        ]
       }
@@ -432956,6 +433206,13 @@
          {}
         ]
        ],
+       "2d.path.roundrect.radius.noarugment.html": [
+        "764f739710a46d584f93ce59b9c052b06e234132",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.path.roundrect.radius.none.html": [
         "16a03c1fdc5d5b77557b5ba574a233007511f63e",
         [
@@ -470230,6 +470487,13 @@
       {}
      ]
     ],
+    "inert-and-contenteditable.tentative.html": [
+     "01091d1736e87b294c3ddf118227d93f129808fe",
+     [
+      null,
+      {}
+     ]
+    ],
     "inert-canvas-fallback-content.tentative.html": [
      "f22549b50377f17b3e03cb6c26c996122b7c8e2b",
      [
@@ -472968,6 +473232,20 @@
       {}
      ]
     ],
+    "multicol-000.html": [
+     "c06cddd663b009496dd9678e6a852d52a96cbc84",
+     [
+      null,
+      {}
+     ]
+    ],
+    "multicol-001.html": [
+     "a47d5f04880d8661bed26ad3789c9d0694514862",
+     [
+      null,
+      {}
+     ]
+    ],
     "opacity-nonzero-to-zero.html": [
      "9ce0f2be9a97ecbeefa6721c239d7c8115adf05d",
      [
@@ -476586,7 +476864,7 @@
      ]
     ],
     "MediaStreamTrack-transfer.https.html": [
-     "9d582f3d9be259ad481133ca1ff6fd2fe2448d6e",
+     "0024aea0978103e47f5637111ab2a87333072ebb",
      [
       null,
       {
@@ -498924,6 +499202,13 @@
       {}
      ]
     ],
+    "scrollbars.html": [
+     "129e74e5cd969795adbf728dcdd448adfd112bac",
+     [
+      null,
+      {}
+     ]
+    ],
     "svg.html": [
      "08c1cf9a3734990dbd9bc6c60ce723f24e897f99",
      [
@@ -505069,6 +505354,13 @@
          "timeout": "long"
         }
        ]
+      ],
+      "samesite-iframe.https.html": [
+       "633da9926a8cd26210bc8171b31c94653a46ebdd",
+       [
+        null,
+        {}
+       ]
       ]
      },
      "navigation-redirect-body.https.html": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/nested-multicol-and-float-with-tall-padding-before-float.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/nested-multicol-and-float-with-tall-padding-before-float.html
new file mode 100644
index 0000000..2a901d1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/crashtests/nested-multicol-and-float-with-tall-padding-before-float.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1289532">
+<div style="columns:4; column-fill:auto; height:40px;">
+  <div style="float:left; width:100%; height:100px; padding-bottom:3000px;"></div>
+  <div style="float:left; columns:1; column-fill:auto; width:100%; height:100px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-plus-will-change-opacity.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-plus-will-change-opacity.html
new file mode 100644
index 0000000..250a13e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/backdrop-filter-plus-will-change-opacity.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>backdrop-filter: Correctly apply backdrop-filter with will-change opacity</title>
+<link rel="author" href="mailto:pdr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
+<link rel="match" href="reference/backdrop-filter-plus-will-change-opacity-ref.html">
+
+<p>Expected: A black box.</p>
+
+<div id="filter"></div>
+
+<style>
+  #filter {
+    width: 100px;
+    height: 100px;
+    backdrop-filter: invert(1);
+    will-change: opacity;
+  }
+</style>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/backdrop-filter-plus-will-change-opacity-ref.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/backdrop-filter-plus-will-change-opacity-ref.html
new file mode 100644
index 0000000..56c62438
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/backdrop-filter-plus-will-change-opacity-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<p>Expected: A black box.</p>
+<div id="blackbox"></div>
+<style>
+  #blackbox {
+    width: 100px;
+    height: 100px;
+    background-color: black;
+  }
+</style>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/repaint-added-backdrop-filter-ref.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/repaint-added-backdrop-filter-ref.html
new file mode 100644
index 0000000..caaa306
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/repaint-added-backdrop-filter-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<p>Expected: A black box.</p>
+<div id="filter"></div>
+<style>
+  #filter {
+    width: 100px;
+    height: 100px;
+    background-color: black;
+  }
+</style>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/repaint-added-backdrop-filter.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/repaint-added-backdrop-filter.html
new file mode 100644
index 0000000..6678ba4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/repaint-added-backdrop-filter.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>backdrop-filter: Correctly repaint added backdrop-filter</title>
+<link rel="author" href="mailto:pdr@chromium.org">
+<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
+<link rel="match" href="reference/repaint-added-backdrop-filter-ref.html">
+<script src="/common/reftest-wait.js"></script>
+
+<p>Expected: A black box.</p>
+
+<div id="filter"></div>
+
+<style>
+  #filter {
+    width: 100px;
+    height: 100px;
+    backdrop-filter: none;
+    will-change: opacity;
+  }
+</style>
+
+<script>
+  function doTest() {
+    requestAnimationFrame(function() {
+      requestAnimationFrame(function() {
+        document.getElementById('filter').style.backdropFilter = 'invert(1)';
+        takeScreenshot();
+      });
+    });
+  }
+  window.addEventListener('load', doTest, false);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/xslt/strip-space-crash.xml b/third_party/blink/web_tests/external/wpt/dom/xslt/strip-space-crash.xml
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/xslt/strip-space-crash.xml
rename to third_party/blink/web_tests/external/wpt/dom/xslt/strip-space-crash.xml
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html b/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html
deleted file mode 100644
index c7ee10e..0000000
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/getCurrentPosition_IDL.https.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE HTML>
-<meta charset="utf-8">
-<meta name=timeout content=long>
-<title>Geolocation Test: getCurrentPosition tests</title>
-<link rel="help" href="http://www.w3.org/TR/geolocation-API/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-
-<p>Clear all Geolocation permissions before running this test. If prompted for permission, please allow.</p>
-<div id="log"></div>
-<script>
-var geo, success, fail;
-
-setup(function() {
-  geo = navigator.geolocation;
-}, {explicit_done: true});
-
-function successCallback(position)
-{
-  var ii, oldval;
-
-  /*
-    interface GeolocationPosition {
-      readonly attribute GeolocationCoordinates coords;
-      readonly attribute DOMTimeStamp timestamp;
-    };
-  */
-
-  test(function() {
-    assert_class_string(position, "GeolocationPosition");
-  }, "GeolocationPosition toString");
-
-  test(function() {
-    assert_class_string(position.coords, "GeolocationCoordinates");
-  }, "GeolocationCoordinates toString");
-
-  test(function() {
-    assert_equals(typeof(position.timestamp), "number",
-        "position.timestamp should be of type 'number' was: " + typeof(position.timestamp));
-  }, "GeolocationPosition.timestamp is type number");
-
-  /*
-    interface GeolocationCoordinates {
-      readonly attribute double latitude;
-      readonly attribute double longitude;
-      readonly attribute double? altitude;
-      readonly attribute double accuracy;
-      readonly attribute double? altitudeAccuracy;
-      readonly attribute double? heading;
-      readonly attribute double? speed;
-    };
-  */
-
-  for (ii in position.coords) {
-    // these four can be numbers or null
-    if (ii == "altitude" || ii == "altitudeAccuracy" || ii == "heading" || ii == "speed") {
-      test(function() {
-        assert_true(position.coords[ii] === null || typeof(position.coords[ii]) === "number",
-            ii + " must be null or 'number' type, was: " + typeof(position.coords[ii]));
-      }, ii+ " is null or number");
-    } else {
-      test(function() {
-        assert_equals(typeof(position.coords[ii]), "number",
-            ii + " should be type 'number' but typeof returned: " + typeof(position.coords[ii]));
-      }, ii + " is type number");
-    }
-
-    oldval = position.coords[ii];
-    position.coords[ii] = 666;
-
-    test(function() {
-      assert_equals(position.coords[ii], oldval,
-          ii + " should be readonly, wrote: " + position.coords[ii] + " old value was " + oldval);
-    }, ii + " readonly");
-
-  }
-
-  success.done();
-  done();
-}
-
-function BadErrorCallback(error)
-{
-  success.step(function() {
-    assert_unreached("Error callback called in error");
-  });
-  success.done();
-  done();
-}
-
-function BadSuccessCallback(position)
-{
-  fail.step(function() {
-    assert_unreached("Success callback called in error");
-  });
-  fail.done();
-}
-
-function errorCallback(error)
-{
-  test(function() {
-    assert_class_string(error, "GeolocationPositionError");
-  }, "GeolocationPositionError toString");
-
-  fail.done();
-}
-
-success = async_test("getCurrentPosition success callback tests");
-
-// with a longer timeout and with the user accepting the position request,
-// this should test the successcallback
-success.step(function() {
-  geo.getCurrentPosition(
-      successCallback,
-      BadErrorCallback,
-      {maximumAge:600000, timeout:10000}
-  );
-});
-
-fail = async_test("getCurrentPosition error callback tests");
-
-// with a timeout of 0 the error callback is hopefully consistently called
-fail.step(function() {
-  geo.getCurrentPosition(
-      BadSuccessCallback,
-      errorCallback,
-      {maximumAge:00, timeout:0}
-  );
-});
-
-</script>
-
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
index 98c407c..57cbf59d 100644
--- a/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
+++ b/third_party/blink/web_tests/external/wpt/geolocation-API/idlharness.https.window.js
@@ -1,15 +1,28 @@
 // META: script=/resources/WebIDLParser.js
 // META: script=/resources/idlharness.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
 
 // https://www.w3.org/TR/geolocation-API/
 
-idl_test(
-  ['geolocation'],
-  ['hr-time', 'html'],
-  idl_array => {
+window.onload = async () => {
+  await test_driver.set_permission({ name: "geolocation" }, "denied");
+  const positionError = await new Promise((resolve, reject) => {
+    navigator.geolocation.getCurrentPosition(reject, resolve);
+  });
+
+  await test_driver.set_permission({ name: "geolocation" }, "granted");
+  const position = await new Promise((resolve, reject) => {
+    navigator.geolocation.getCurrentPosition(resolve, reject);
+  });
+
+  idl_test(["geolocation"], ["hr-time", "html"], (idl_array) => {
     idl_array.add_objects({
-      Navigator: ['navigator'],
-      Geolocation: ['navigator.geolocation'],
+      Navigator: ["navigator"],
+      Geolocation: ["navigator.geolocation"],
+      GeolocationPositionError: [positionError],
+      GeolocationPosition: [position],
+      GeolocationCoordinates: [position.coords],
     });
-  }
-);
+  });
+};
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html
new file mode 100644
index 0000000..764f7397
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/path-objects/2d.path.roundrect.radius.noarugment.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.path.roundrect.radius.noarugment</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/canvas/resources/canvas-tests.js"></script>
+<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.path.roundrect.radius.noarugment</h1>
+<p class="desc">Check that roundRect draws a rectangle when no radii are provided.</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Check that roundRect draws a rectangle when no radii are provided.");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.roundRect(10, 10, 80, 30, 0);
+ctx.fillStyle = '#0f0';
+ctx.fill();
+// upper left corner (10, 10)
+_assertPixel(canvas, 10,9, 255,0,0,255, "10,9", "255,0,0,255");
+_assertPixel(canvas, 9,10, 255,0,0,255, "9,10", "255,0,0,255");
+_assertPixel(canvas, 10,10, 0,255,0,255, "10,10", "0,255,0,255");
+
+// upper right corner (89, 10)
+_assertPixel(canvas, 90,10, 255,0,0,255, "90,10", "255,0,0,255");
+_assertPixel(canvas, 89,9, 255,0,0,255, "89,9", "255,0,0,255");
+_assertPixel(canvas, 89,10, 0,255,0,255, "89,10", "0,255,0,255");
+
+// lower right corner (89, 39)
+_assertPixel(canvas, 89,40, 255,0,0,255, "89,40", "255,0,0,255");
+_assertPixel(canvas, 90,39, 255,0,0,255, "90,39", "255,0,0,255");
+_assertPixel(canvas, 89,39, 0,255,0,255, "89,39", "0,255,0,255");
+
+// lower left corner (10, 30)
+_assertPixel(canvas, 9,39, 255,0,0,255, "9,39", "255,0,0,255");
+_assertPixel(canvas, 10,40, 255,0,0,255, "10,40", "255,0,0,255");
+_assertPixel(canvas, 10,39, 0,255,0,255, "10,39", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml
index e6ac7958..bdabfd66 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml/element/path-objects.yaml
@@ -2505,6 +2505,34 @@
   code: |
     assert_throws_js(RangeError, () => { ctx.roundRect(0, 0, 100, 50, [])});
 
+- name: 2d.path.roundrect.radius.noarugment
+  desc: Check that roundRect draws a rectangle when no radii are provided.
+  code: |
+    ctx.fillStyle = '#f00';
+    ctx.fillRect(0, 0, 100, 50);
+    ctx.roundRect(10, 10, 80, 30, 0);
+    ctx.fillStyle = '#0f0';
+    ctx.fill();
+    // upper left corner (10, 10)
+    @assert pixel 10,9 == 255,0,0,255;
+    @assert pixel 9,10 == 255,0,0,255;
+    @assert pixel 10,10 == 0,255,0,255;
+
+    // upper right corner (89, 10)
+    @assert pixel 90,10 == 255,0,0,255;
+    @assert pixel 89,9 == 255,0,0,255;
+    @assert pixel 89,10 == 0,255,0,255;
+
+    // lower right corner (89, 39)
+    @assert pixel 89,40 == 255,0,0,255;
+    @assert pixel 90,39 == 255,0,0,255;
+    @assert pixel 89,39 == 0,255,0,255;
+
+    // lower left corner (10, 30)
+    @assert pixel 9,39 == 255,0,0,255;
+    @assert pixel 10,40 == 255,0,0,255;
+    @assert pixel 10,39 == 0,255,0,255;
+
 - name: 2d.path.roundrect.radius.toomany
   desc: Check that roundRect throws an IndeSizeError if radii has more than four items.
   code: |
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
index 0e04c917..f241abe 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 822 tests; 813 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 822 tests; 811 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Document: original interface defined
@@ -316,7 +316,7 @@
 PASS Path2D interface: operation bezierCurveTo(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double)
 PASS Path2D interface: operation arcTo(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double)
 PASS Path2D interface: operation rect(unrestricted double, unrestricted double, unrestricted double, unrestricted double)
-PASS Path2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, sequence<(unrestricted double or DOMPointInit)>)
+FAIL Path2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, sequence<(unrestricted double or DOMPointInit)>) assert_equals: property has wrong .length expected 5 but got 4
 PASS Path2D interface: operation arc(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional boolean)
 PASS Path2D interface: operation ellipse(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional boolean)
 PASS ImageBitmapRenderingContext interface: existence and properties of interface object
@@ -424,7 +424,7 @@
 PASS OffscreenCanvasRenderingContext2D interface: operation bezierCurveTo(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double)
 PASS OffscreenCanvasRenderingContext2D interface: operation arcTo(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double)
 PASS OffscreenCanvasRenderingContext2D interface: operation rect(unrestricted double, unrestricted double, unrestricted double, unrestricted double)
-PASS OffscreenCanvasRenderingContext2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, sequence<(unrestricted double or DOMPointInit)>)
+FAIL OffscreenCanvasRenderingContext2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, sequence<(unrestricted double or DOMPointInit)>) assert_equals: property has wrong .length expected 5 but got 4
 PASS OffscreenCanvasRenderingContext2D interface: operation arc(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional boolean)
 PASS OffscreenCanvasRenderingContext2D interface: operation ellipse(unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional boolean)
 PASS CustomElementRegistry interface: existence and properties of interface object
diff --git a/third_party/blink/web_tests/external/wpt/permissions/META.yml b/third_party/blink/web_tests/external/wpt/permissions/META.yml
index b055f50..6a05abee 100644
--- a/third_party/blink/web_tests/external/wpt/permissions/META.yml
+++ b/third_party/blink/web_tests/external/wpt/permissions/META.yml
@@ -1,5 +1,4 @@
 spec: https://w3c.github.io/permissions/
 suggested_reviewers:
-  - jyasskin
-  - mounirlamouri
+  - miketaylr
   - marcoscaceres
diff --git a/third_party/blink/web_tests/external/wpt/resize-observer/scrollbars.html b/third_party/blink/web_tests/external/wpt/resize-observer/scrollbars.html
new file mode 100644
index 0000000..129e74e5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/resize-observer/scrollbars.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>ResizeObserver content-box size and scrollbars</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1733042">
+<style>
+  #outer {
+    position: relative;
+    width: 100px;
+    height: 200px;
+    overflow: auto;
+    background: #818182;
+  }
+
+  #inner {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 10px;
+    height: 10px;
+    background: #0a6fc0;
+  }
+</style>
+<div id="outer">
+  <div id="inner"></div>
+</div>
+<script>
+  async function animationFrame() {
+    return new Promise(r => requestAnimationFrame(r));
+  }
+
+  // This test is expected to fail with overlay scrollbars.
+  promise_test(async function() {
+    let count = 0;
+
+    const outer = document.getElementById('outer');
+    const inner = document.getElementById('inner');
+    const observer = new ResizeObserver(entries => {
+      count++;
+    });
+
+    observer.observe(outer);
+
+    inner.style.top = '1000px';
+
+    await animationFrame();
+    await animationFrame();
+
+    inner.style.top = 0;
+
+    await animationFrame();
+    await animationFrame();
+
+    assert_equals(count, 2, "ResizeObserver should subtract scrollbar sizes from content-box rect");
+  });
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html
new file mode 100644
index 0000000..a28b612
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-iframe.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>samesite</body>
+<script>
+onmessage = (e) => {
+  if (e.data === "GetBody") {
+    parent.postMessage("samesite", '*');
+  }
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html
new file mode 100644
index 0000000..51fdc9e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-sw-helper.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Navigation Preload Same Site SW registrator</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../resources/test-helpers.sub.js"></script>
+<script>
+
+/**
+ *  This is a helper file to register/unregister service worker in a same-site
+ *  iframe.
+ **/
+
+async function messageToParent(msg) {
+  parent.postMessage(msg, '*');
+}
+
+onmessage = async (e) => {
+  // t is a , but the helper function needs a test object.
+  let t = {
+    step_func: (func) => func,
+  };
+  if (e.data === "Register") {
+    let reg = await service_worker_unregister_and_register(t, "samesite-worker.js", ".");
+    let worker = reg.installing;
+    await wait_for_state(t, worker, 'activated');
+    await messageToParent("SW Registered");
+  } else if (e.data == "Unregister") {
+    await service_worker_unregister(t, ".");
+    await messageToParent("SW Unregistered");
+  }
+}
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js
new file mode 100644
index 0000000..f30e5ed2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/resources/samesite-worker.js
@@ -0,0 +1,8 @@
+self.addEventListener('activate', event => {
+    event.waitUntil(
+        self.registration.navigationPreload.enable());
+  });
+
+self.addEventListener('fetch', event => {
+    event.respondWith(event.preloadResponse);
+  });
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html
new file mode 100644
index 0000000..633da99
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-preload/samesite-iframe.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Navigation Preload for same site 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="../resources/test-helpers.sub.js"></script>
+<body></body>
+<script>
+
+const SAME_SITE = get_host_info().HTTPS_REMOTE_ORIGIN;
+const RESOURCES_DIR = "/service-workers/service-worker/navigation-preload/resources/";
+
+/**
+ * This test is used for testing the NavigationPreload works in a same site iframe.
+ * The test scenario is
+ * 1. Create a same site iframe to register service worker and wait for it be activated
+ * 2. Create a same site iframe which be intercepted by the service worker.
+ * 3. Once the iframe is loaded, service worker should set the page through the preload response.
+ *    And checking if the iframe's body content is expected.
+ * 4. Unregister the service worker.
+ * 5. remove created iframes.
+ */
+
+promise_test(async (t) => {
+    let resolver;
+    let checkValue = false;
+    window.onmessage = (e) => {
+      if (checkValue) {
+        assert_equals(e.data, "samesite");
+        checkValue = false;
+      }
+      resolver();
+    };
+
+    let helperIframe = document.createElement("iframe");
+    helperIframe.src = SAME_SITE + RESOURCES_DIR + "samesite-sw-helper.html";
+    document.body.appendChild(helperIframe);
+
+    await new Promise(resolve => {
+      resolver = resolve;
+      helperIframe.onload = async () => {
+        helperIframe.contentWindow.postMessage("Register", '*');
+     }
+    });
+
+    let sameSiteIframe = document.createElement("iframe");
+    sameSiteIframe.src = SAME_SITE + RESOURCES_DIR + "samesite-iframe.html";
+    document.body.appendChild(sameSiteIframe);
+    await new Promise(resolve => {
+      resolver = resolve;
+      sameSiteIframe.onload = async() => {
+        checkValue = true;
+        sameSiteIframe.contentWindow.postMessage("GetBody", '*')
+      }
+    });
+
+    await new Promise(resolve => {
+      resolver = resolve;
+      helperIframe.contentWindow.postMessage("Unregister", '*')
+    });
+
+    helperIframe.remove();
+    sameSiteIframe.remove();
+  });
+
+</script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
index 31eb852..88ffc0a 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/video/video-poster-expected.txt
@@ -45,6 +45,7 @@
       "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [352, 288],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 060045c..ce46b04 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [150, 60],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt
index f867ea2..d8462e0c 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/compositing/video/video-poster-expected.txt
@@ -45,6 +45,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [528, 432],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 211d236..ed99cd7 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [225, 90],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 211d236..ed99cd7 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [225, 90],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large-expected.txt
deleted file mode 100644
index 8c8116f..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Test that an attribution redirect with too large attribution data triggers an issue
-Issue reported: {
-    code : AttributionReportingIssue
-    details : {
-        attributionReportingIssueDetails : {
-            invalidParameter : 42
-            request : {
-                requestId : <string>
-            }
-            violationType : AttributionTriggerDataTooLarge
-        }
-    }
-}
-
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large.js b/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large.js
deleted file mode 100644
index 4207274..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-data-too-large.js
+++ /dev/null
@@ -1,20 +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.
-
-(async function(testRunner) {
-  const {page, dp} = await testRunner.startBlank(
-      `Test that an attribution redirect with too large attribution data triggers an issue`);
-
-  await dp.Audits.enable();
-  await page.navigate('https://devtools.test:8443/inspector-protocol/resources/empty.html');
-
-  const issuePromise = dp.Audits.onceIssueAdded();
-  await page.loadHTML(`
-    <!DOCTYPE html>
-    <img src="https://devtools.test:8443/inspector-protocol/conversion/resources/conversion-redirect.php?trigger-data=42"></img>`);
-  const issues = await issuePromise;
-  testRunner.log(issues.params.issue, "Issue reported: ", ['requestId']);
-
-  testRunner.completeTest();
-})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large-expected.txt
deleted file mode 100644
index a0f0703..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Test that an attribution redirect with too large attribution event-source data triggers an issue
-Issue reported: {
-    code : AttributionReportingIssue
-    details : {
-        attributionReportingIssueDetails : {
-            invalidParameter : 42
-            request : {
-                requestId : <string>
-            }
-            violationType : AttributionEventSourceTriggerDataTooLarge
-        }
-    }
-}
-
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large.js b/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large.js
deleted file mode 100644
index 022d2974..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/conversion/attribution-event-source-data-too-large.js
+++ /dev/null
@@ -1,20 +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.
-
-(async function(testRunner) {
-  const {page, dp} = await testRunner.startBlank(
-      `Test that an attribution redirect with too large attribution event-source data triggers an issue`);
-
-  await dp.Audits.enable();
-  await page.navigate('https://devtools.test:8443/inspector-protocol/resources/empty.html');
-
-  const issuePromise = dp.Audits.onceIssueAdded();
-  await page.loadHTML(`
-    <!DOCTYPE html>
-    <img src="https://devtools.test:8443/inspector-protocol/conversion/resources/conversion-redirect.php?trigger-data=0&event-source-trigger-data=42"></img>`);
-  const issues = await issuePromise;
-  testRunner.log(issues.params.issue, "Issue reported: ", ['requestId']);
-
-  testRunner.completeTest();
-})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/issue-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/issue-expected.txt
index 200e4187..f31a64c 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/issue-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/issue-expected.txt
@@ -1,3 +1,3 @@
 Tests that issues are triggered
-SameSiteCookieIssue
+CookieIssue
 
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/same-party-issue-invalid-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/same-party-issue-invalid-expected.txt
index 58ad288..a511e639c 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/same-party-issue-invalid-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/same-party-issue-invalid-expected.txt
@@ -1,9 +1,9 @@
 Verifies that Set-Cookie lines with invalid SameParty attribute usage file an issue.
 
 Issue reported: {
-    code : SameSiteCookieIssue
+    code : CookieIssue
     details : {
-        sameSiteCookieIssueDetails : {
+        cookieIssueDetails : {
             cookieExclusionReasons : [
                 [0] : ExcludeInvalidSameParty
             ]
@@ -17,9 +17,9 @@
     }
 }
 Issue reported: {
-    code : SameSiteCookieIssue
+    code : CookieIssue
     details : {
-        sameSiteCookieIssueDetails : {
+        cookieIssueDetails : {
             cookieExclusionReasons : [
                 [0] : ExcludeInvalidSameParty
             ]
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue.js
index 95408f5..4532fa22 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue.js
@@ -20,10 +20,10 @@
   ({requestExtraInfo} = await helper.fetchWithExtraInfo(firstPartyUrl));
 
   const issues = await Promise.all(issuePromises);
-  const sameSiteIssues = issues.filter(issue => issue.params.issue.code === 'SameSiteCookieIssue');
+  const cookieIssues = issues.filter(issue => issue.params.issue.code === 'CookieIssue');
 
   testRunner.log(requestExtraInfo.params.associatedCookies, 'Javascript initiated subresource associated cookies:');
-  testRunner.log(sameSiteIssues[0].params.issue, "Issue reported: ", ['requestId']);
+  testRunner.log(cookieIssues[0].params.issue, "Issue reported: ", ['requestId']);
 
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue.js
index 955f312..938460a 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue.js
@@ -15,12 +15,12 @@
   await helper.navigateWithExtraInfo(thirdPartyUrl);
   let {responseExtraInfo} = await helper.fetchWithExtraInfo(setCookieUrl);
 
-  // Only show same site issues
+  // Only show cookie issues
   const issues = await Promise.all(issuePromises);
-  const sameSiteIssues = issues.filter(issue => issue.params.issue.code === 'SameSiteCookieIssue');
+  const cookieIssues = issues.filter(issue => issue.params.issue.code === 'CookieIssue');
 
   testRunner.log(responseExtraInfo.params.blockedCookies, 'Javascript initiated subresource blocked set-cookies:');
-  testRunner.log(sameSiteIssues[0].params.issue, "Issue reported: ", ['requestId']);
+  testRunner.log(cookieIssues[0].params.issue, "Issue reported: ", ['requestId']);
 
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-blocked-cookie-not-secure-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-blocked-cookie-not-secure-expected.txt
index 68ade46..455a669 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-blocked-cookie-not-secure-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-blocked-cookie-not-secure-expected.txt
@@ -2,9 +2,9 @@
 
 Inspector issue:{
     issue : {
-        code : SameSiteCookieIssue
+        code : CookieIssue
         details : {
-            sameSiteCookieIssueDetails : {
+            cookieIssueDetails : {
                 cookie : {
                     domain : cookie.test
                     name : name
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-lax-subresource-context-downgrade-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-lax-subresource-context-downgrade-expected.txt
index 6124245..aeb56621 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-lax-subresource-context-downgrade-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-lax-subresource-context-downgrade-expected.txt
@@ -2,9 +2,9 @@
 
 Inspector issue:{
     issue : {
-        code : SameSiteCookieIssue
+        code : CookieIssue
         details : {
-            sameSiteCookieIssueDetails : {
+            cookieIssueDetails : {
                 cookie : {
                     domain : cookie.test
                     name : name
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-navigation-context-downgrade-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-navigation-context-downgrade-expected.txt
index 6c687ff3..451b4df0 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-navigation-context-downgrade-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-navigation-context-downgrade-expected.txt
@@ -2,9 +2,9 @@
 
 Inspector issue:{
     issue : {
-        code : SameSiteCookieIssue
+        code : CookieIssue
         details : {
-            sameSiteCookieIssueDetails : {
+            cookieIssueDetails : {
                 cookie : {
                     domain : cookie.test
                     name : name
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-strict-subresource-context-downgrade-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-strict-subresource-context-downgrade-expected.txt
index 74a91e6f..7e0cf7ef 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-strict-subresource-context-downgrade-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/same-site-issue-warn-cookie-strict-subresource-context-downgrade-expected.txt
@@ -2,9 +2,9 @@
 
 Inspector issue:{
     issue : {
-        code : SameSiteCookieIssue
+        code : CookieIssue
         details : {
-            sameSiteCookieIssueDetails : {
+            cookieIssueDetails : {
                 cookie : {
                     domain : cookie.test
                     name : name
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index eb16f6f..2f3bf8c 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [150, 60],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
index ae935f5..5d2502f 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/compositing/video/video-poster-expected.txt
@@ -45,6 +45,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [352, 288],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 2280a61..e841af8 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [150, 60],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
index 5db5b0d2..e481296 100644
--- a/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
+++ b/third_party/blink/web_tests/platform/win/compositing/video/video-poster-expected.txt
@@ -45,6 +45,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [352, 288],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
index 1f9ff19..0f075a0 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/image/canvas-composite-repaint-by-all-imagesource-expected.txt
@@ -61,6 +61,7 @@
       "name": "LayoutNGFlexibleBox DIV class='sizing-small phase-pre-ready state-no-source'",
       "bounds": [150, 60],
       "contentsOpaqueForText": true,
+      "drawsContent": false,
       "transform": 1
     },
     {
diff --git a/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue-expected.txt b/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue-expected.txt
index 300943f3..83d3adf 100644
--- a/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue-expected.txt
+++ b/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-cookie-same-party-issue-expected.txt
@@ -24,9 +24,9 @@
     }
 ]
 Issue reported: {
-    code : SameSiteCookieIssue
+    code : CookieIssue
     details : {
-        sameSiteCookieIssueDetails : {
+        cookieIssueDetails : {
             cookie : {
                 domain : cookie.test
                 name : name
diff --git a/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue-expected.txt b/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue-expected.txt
index a9eead6..25a75372 100644
--- a/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue-expected.txt
+++ b/third_party/blink/web_tests/virtual/first-party-sets/http/tests/inspector-protocol/network/blocked-setcookie-same-party-cross-party-issue-expected.txt
@@ -25,9 +25,9 @@
     }
 ]
 Issue reported: {
-    code : SameSiteCookieIssue
+    code : CookieIssue
     details : {
-        sameSiteCookieIssueDetails : {
+        cookieIssueDetails : {
             cookie : {
                 domain : cookie.test
                 name : name
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity-ref.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity-ref.html
index 8a3100c..73a84b1 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity-ref.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity-ref.html
@@ -18,7 +18,7 @@
 #e3 { opacity: 0.25; top: 300px; left: 20px; }
 body { background: lightpink; }
 </style>
-<div id=e1 class=box>one</div>
-<div id=e2 class=box>two</div>
-<div id=e3 class=box>three</div>
+<div id=e1 class=box></div>
+<div id=e2 class=box></div>
+<div id=e3 class=box></div>
 
diff --git a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
index 38f43fd..ae759ee 100644
--- a/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
+++ b/third_party/blink/web_tests/wpt_internal/document-transition/new-content-captures-opacity.html
@@ -28,9 +28,9 @@
 html::page-transition-container(root) { animation-duration: 0s; opacity: 0; }
 html::page-transition { background: lightpink; }
 </style>
-<div id=e1 class=box>one</div>
-<div id=e2 class=box>two</div>
-<div id=e3 class=box>three</div>
+<div id=e1 class=box></div>
+<div id=e2 class=box></div>
+<div id=e3 class=box></div>
 <script>
 async function runTest() {
   await document.documentTransition.prepare({
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
index e3a62d7b..0f994638 100644
--- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
+++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
@@ -2715,6 +2715,16 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,clamp:integer_builtin_functions,signed_clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,clamp:float_builtin_functions,clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,cos:float_builtin_functions,cos:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,countLeadingZeros:integer_builtin_functions,countLeadingZeros_unsigned:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,countLeadingZeros:integer_builtin_functions,countLeadingZeros_signed:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,countTrailingZeros:integer_builtin_functions,countTrailingZeros_unsigned:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,countTrailingZeros:integer_builtin_functions,countTrailingZeros_signed:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,extractBits:integer_builtin_functions,extractBits_unsigned:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,extractBits:integer_builtin_functions,extractBits_signed:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,firstLeadingBit:integer_builtin_functions,firstLeadingBit_unsigned:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,firstLeadingBit:integer_builtin_functions,firstLeadingBit_signed:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,firstTrailingBit:integer_builtin_functions,firstTrailingBit_unsigned:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,firstTrailingBit:integer_builtin_functions,firstTrailingBit_signed:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,acos:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,asin:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,atan2:*'>
@@ -2753,6 +2763,7 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,trunc:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,floor:float_builtin_functions,floor:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,fract:float_builtin_functions,fract:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,insertBits:integer_builtin_functions,insertBits:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,count_1_bits:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,bit_reversal:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,inversesqrt:float_builtin_functions,inverseSqrt:*'>
diff --git a/third_party/robolectric/3pp/fetch.py b/third_party/robolectric/3pp/fetch.py
index cb45dbb..d603b340 100755
--- a/third_party/robolectric/3pp/fetch.py
+++ b/third_party/robolectric/3pp/fetch.py
@@ -1,10 +1,8 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # 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.
 
-from __future__ import print_function
-
 import argparse
 import json
 import os
diff --git a/third_party/tflite/BUILD.gn b/third_party/tflite/BUILD.gn
index 822bef6..4cf12de 100644
--- a/third_party/tflite/BUILD.gn
+++ b/third_party/tflite/BUILD.gn
@@ -14,6 +14,9 @@
 
 config("tflite_config") {
   include_dirs = [ "src" ]
+  if (is_android) {
+    libs = [ "log" ]
+  }
 }
 
 config("tflite_flags") {
diff --git a/third_party/turbine/3pp/fetch.py b/third_party/turbine/3pp/fetch.py
index 2a10227..f4e97e9 100755
--- a/third_party/turbine/3pp/fetch.py
+++ b/third_party/turbine/3pp/fetch.py
@@ -1,16 +1,13 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # 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.
 
-from __future__ import print_function
-
 import argparse
 import datetime
 import json
 import os
-
-from six.moves import urllib
+import urllib.request
 
 _COMMITS_URL = 'https://api.github.com/repos/google/turbine/commits?per_page=1&until={}'
 _ARCHIVE_URL = 'https://github.com/google/turbine/archive/{}.tar.gz'
diff --git a/third_party/updater/chrome_mac_universal/3pp/fetch.py b/third_party/updater/chrome_mac_universal/3pp/fetch.py
index 099747a..4ece784 100755
--- a/third_party/updater/chrome_mac_universal/3pp/fetch.py
+++ b/third_party/updater/chrome_mac_universal/3pp/fetch.py
@@ -2,13 +2,13 @@
 # Copyright 2022 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+
 import argparse
 import datetime
 import json
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # TODO(crbug.com/1268555): This is compared lexically. Remove it before M1000.
 MIN_VERSION = '100.0.4876.0'
diff --git a/third_party/updater/chrome_win_x86/3pp/fetch.py b/third_party/updater/chrome_win_x86/3pp/fetch.py
index 064fa3b..d2d52855 100755
--- a/third_party/updater/chrome_win_x86/3pp/fetch.py
+++ b/third_party/updater/chrome_win_x86/3pp/fetch.py
@@ -2,13 +2,13 @@
 # Copyright 2022 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+
 import argparse
 import datetime
 import json
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # TODO(crbug.com/1268555): This is compared lexically. Remove it before M1000.
 MIN_VERSION = '100.0.4876.0'
diff --git a/third_party/updater/chrome_win_x86_64/3pp/fetch.py b/third_party/updater/chrome_win_x86_64/3pp/fetch.py
index e6ec653..a81fc90 100755
--- a/third_party/updater/chrome_win_x86_64/3pp/fetch.py
+++ b/third_party/updater/chrome_win_x86_64/3pp/fetch.py
@@ -2,13 +2,13 @@
 # Copyright 2022 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+
 import argparse
 import datetime
 import json
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # TODO(crbug.com/1268555): This is compared lexically. Remove it before M1000.
 MIN_VERSION = '100.0.4876.0'
diff --git a/third_party/updater/chromium_mac_amd64/3pp/fetch.py b/third_party/updater/chromium_mac_amd64/3pp/fetch.py
index 10ffc469..3e3a39516 100755
--- a/third_party/updater/chromium_mac_amd64/3pp/fetch.py
+++ b/third_party/updater/chromium_mac_amd64/3pp/fetch.py
@@ -2,14 +2,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 argparse
 import functools
 import json
 import math
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # MIN_VERSION is the earliest working version of the updater for self-update
 # testing. If a backwards-incompatible change to the updater is made, it may be
diff --git a/third_party/updater/chromium_mac_arm64/3pp/fetch.py b/third_party/updater/chromium_mac_arm64/3pp/fetch.py
index 38dd7e5..2abc76e 100755
--- a/third_party/updater/chromium_mac_arm64/3pp/fetch.py
+++ b/third_party/updater/chromium_mac_arm64/3pp/fetch.py
@@ -2,14 +2,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 argparse
 import functools
 import json
 import math
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # MIN_VERSION is the earliest working version of the updater for self-update
 # testing. If a backwards-incompatible change to the updater is made, it may be
diff --git a/third_party/updater/chromium_win_x86/3pp/fetch.py b/third_party/updater/chromium_win_x86/3pp/fetch.py
index da98a18..9ae41d44 100755
--- a/third_party/updater/chromium_win_x86/3pp/fetch.py
+++ b/third_party/updater/chromium_win_x86/3pp/fetch.py
@@ -2,14 +2,14 @@
 # Copyright 2022 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+
 import argparse
 import functools
 import json
 import math
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # MIN_VERSION is the earliest working version of the updater for self-update
 # testing. If a backwards-incompatible change to the updater is made, it may be
diff --git a/third_party/updater/chromium_win_x86_64/3pp/fetch.py b/third_party/updater/chromium_win_x86_64/3pp/fetch.py
index 56e4698..7750ade 100755
--- a/third_party/updater/chromium_win_x86_64/3pp/fetch.py
+++ b/third_party/updater/chromium_win_x86_64/3pp/fetch.py
@@ -2,14 +2,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 argparse
 import functools
 import json
 import math
 import os
 import sys
-
-from six.moves import urllib
+import urllib.request
 
 # MIN_VERSION is the earliest working version of the updater for self-update
 # testing. If a backwards-incompatible change to the updater is made, it may be
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index 2ad6224f..82db475 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -258,9 +258,15 @@
 src/webgpu/shader/execution/builtin/ceil.spec.ts
 src/webgpu/shader/execution/builtin/clamp.spec.ts
 src/webgpu/shader/execution/builtin/cos.spec.ts
+src/webgpu/shader/execution/builtin/countLeadingZeros.spec.ts
+src/webgpu/shader/execution/builtin/countTrailingZeros.spec.ts
+src/webgpu/shader/execution/builtin/extractBits.spec.ts
+src/webgpu/shader/execution/builtin/firstLeadingBit.spec.ts
+src/webgpu/shader/execution/builtin/firstTrailingBit.spec.ts
 src/webgpu/shader/execution/builtin/float_built_functions.spec.ts
 src/webgpu/shader/execution/builtin/floor.spec.ts
 src/webgpu/shader/execution/builtin/fract.spec.ts
+src/webgpu/shader/execution/builtin/insertBits.spec.ts
 src/webgpu/shader/execution/builtin/integer_built_in_functions.spec.ts
 src/webgpu/shader/execution/builtin/inversesqrt.spec.ts
 src/webgpu/shader/execution/builtin/logical_built_in_functions.spec.ts
diff --git a/tools/OWNERS b/tools/OWNERS
index 16faaef..942bb100 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -10,6 +10,9 @@
 scottmg@chromium.org
 thakis@chromium.org
 
+per-file add_header*.py=dcheng@chromium.org
+per-file add_header*.py=xhwang@chromium.org
+
 per-file autotest.py=mthiesse@chromium.org
 
 per-file bisect*.py=anantha@chromium.org
diff --git a/tools/add_header.py b/tools/add_header.py
index 62b1a38..8eecf17 100755
--- a/tools/add_header.py
+++ b/tools/add_header.py
@@ -333,9 +333,6 @@
 def SerializeIncludes(includes):
   """Turns includes back into the corresponding C++ source text.
 
-  This function assumes that the list of input Include objects is already sorted
-  according to Google style.
-
   Args:
     includes: a list of Include objects.
 
@@ -344,6 +341,56 @@
   """
   source = []
 
+  special_headers = [
+      # Must be included before ws2tcpip.h.
+      # Doesn't need to be included before <windows.h> with
+      # WIN32_LEAN_AND_MEAN but why chance it?
+      '<winsock2.h>',
+      # Must be before lots of things, e.g. shellapi.h, winbase.h,
+      # versionhelpers.h, memoryapi.h, hidclass.h, ncrypt.h., ...
+      '<windows.h>',
+      # Must be before iphlpapi.h.
+      '<ws2tcpip.h>',
+      # Must be before propkey.h.
+      '<shobjidl.h>',
+      # Must be before atlapp.h.
+      '<atlbase.h>',
+      # Must be before intshcut.h.
+      '<ole2.h>',
+      # Must be before intshcut.h.
+      '<unknwn.h>',
+      # Must be before uiautomation.h.
+      '<objbase.h>',
+      # Must be before tpcshrd.h.
+      '<tchar.h>',
+  ]
+
+  # Ensure that headers are sorted as follows:
+  #
+  # 1. The primary header, if any, appears first.
+  # 2. All headers of the same type (e.g. C system, C++ system headers, et
+  #    cetera) are grouped contiguously.
+  # 3. Any special sorting rules needed within each group for satisfying
+  #    platform header idiosyncrasies. In practice, this only applies to C
+  #    system headers.
+  # 4. The remaining headers without special sorting rules are sorted
+  #    lexicographically.
+  #
+  # The for loop below that outputs the actual source text depends on #2 above
+  # to insert newlines between different groups of headers.
+  def SortKey(include):
+    def SpecialSortKey(include):
+      lower_name = include.decorated_name.lower()
+      for i in range(len(special_headers)):
+        if special_headers[i] == lower_name:
+          return i
+      return len(special_headers)
+
+    return (not include.is_primary_header, include.header_type,
+            SpecialSortKey(include), include.decorated_name)
+
+  includes.sort(key=SortKey)
+
   # Assume there's always at least one include.
   previous_include = None
   for include in includes:
@@ -399,13 +446,6 @@
 
   MarkPrimaryInclude(includes, filename)
 
-  # TODO(dcheng): It may be worth considering adding special sorting heuristics
-  # for windows.h, et cetera.
-  def SortKey(include):
-    return (not include.is_primary_header, include.header_type,
-            include.decorated_name)
-
-  includes.sort(key=SortKey)
   lines[begin:end] = SerializeIncludes(includes)
   lines.append('')  # To avoid eating the newline at the end of the file.
   return '\n'.join(lines)
diff --git a/tools/add_header_test.py b/tools/add_header_test.py
index f4060bc..8c145c4 100755
--- a/tools/add_header_test.py
+++ b/tools/add_header_test.py
@@ -3,6 +3,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import random
 import unittest
 
 import add_header
@@ -370,6 +371,34 @@
         '#include "moo.h"'
     ])
 
+  def testSpecialHeaders(self):
+    includes = []
+    primary_header = add_header.Include('"cow.h"', 'include', [], None)
+    primary_header.is_primary_header = True
+    includes.append(primary_header)
+    includes.append(add_header.Include('<winsock2.h>', 'include', [], None))
+    includes.append(add_header.Include('<windows.h>', 'include', [], None))
+    includes.append(add_header.Include('<ws2tcpip.h>', 'include', [], None))
+    includes.append(add_header.Include('<shobjidl.h>', 'include', [], None))
+    includes.append(add_header.Include('<atlbase.h>', 'include', [], None))
+    includes.append(add_header.Include('<ole2.h>', 'include', [], None))
+    includes.append(add_header.Include('<unknwn.h>', 'include', [], None))
+    includes.append(add_header.Include('<objbase.h>', 'include', [], None))
+    includes.append(add_header.Include('<tchar.h>', 'include', [], None))
+    includes.append(add_header.Include('<string.h>', 'include', [], None))
+    includes.append(add_header.Include('<stddef.h>', 'include', [], None))
+    includes.append(add_header.Include('<stdio.h>', 'include', [], None))
+    includes.append(add_header.Include('"moo.h"', 'include', [], None))
+    random.shuffle(includes)
+    source = add_header.SerializeIncludes(includes)
+    self.assertEqual(source, [
+        '#include "cow.h"', '', '#include <winsock2.h>', '#include <windows.h>',
+        '#include <ws2tcpip.h>', '#include <shobjidl.h>',
+        '#include <atlbase.h>', '#include <ole2.h>', '#include <unknwn.h>',
+        '#include <objbase.h>', '#include <tchar.h>', '#include <stddef.h>',
+        '#include <stdio.h>', '#include <string.h>', '', '#include "moo.h"'
+    ])
+
 
 class AddHeaderToSourceTest(unittest.TestCase):
   def testAddInclude(self):
diff --git a/tools/android/avd/3pp/fetch.py b/tools/android/avd/3pp/fetch.py
index ba4c8570..1029829 100755
--- a/tools/android/avd/3pp/fetch.py
+++ b/tools/android/avd/3pp/fetch.py
@@ -17,8 +17,6 @@
 
 """
 
-from __future__ import print_function
-
 import argparse
 import hashlib
 import os
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py
index 98e8efa..38b2bbe 100755
--- a/tools/clang/scripts/package.py
+++ b/tools/clang/scripts/package.py
@@ -583,19 +583,25 @@
 
   # Copy LLVM includes. The llvm source and build directory includes must be
   # merged. llvm-c for C bindings is also included.
+  #
+  # Headers and libs are copied from LLVM_BOOTSTRAP_DIR, not LLVM_RELEASE_DIR,
+  # because the release libs have LTO so they contain LLVM bitcode while the
+  # bootstrap libs do not. The Rust build consumes these,the first stage of
+  # which cannot handle newer LLVM bitcode. The stage 0 rustc is linked against
+  # an older LLVM.
   shutil.copytree(os.path.join(LLVM_DIR, 'llvm', 'include', 'llvm'),
                   os.path.join(clang_libs_dir, 'include', 'llvm'))
   shutil.copytree(os.path.join(LLVM_DIR, 'llvm', 'include', 'llvm-c'),
                   os.path.join(clang_libs_dir, 'include', 'llvm-c'))
-  shutil.copytree(os.path.join(LLVM_RELEASE_DIR, 'include', 'llvm'),
+  shutil.copytree(os.path.join(LLVM_BOOTSTRAP_DIR, 'include', 'llvm'),
                   os.path.join(clang_libs_dir, 'include', 'llvm'),
                   dirs_exist_ok=True)
 
   # Copy llvm-config and FileCheck which the Rust build needs
   os.makedirs(os.path.join(clang_libs_dir, 'bin'))
-  shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'llvm-config' + exe_ext),
+  shutil.copy(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin', 'llvm-config' + exe_ext),
               os.path.join(clang_libs_dir, 'bin'))
-  shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'bin', 'FileCheck' + exe_ext),
+  shutil.copy(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin', 'FileCheck' + exe_ext),
               os.path.join(clang_libs_dir, 'bin'))
 
   os.makedirs(os.path.join(clang_libs_dir, 'lib'))
@@ -607,10 +613,10 @@
     clang_libs_want = [
         '*.a',
     ]
-  for lib_path in os.listdir(os.path.join(LLVM_RELEASE_DIR, 'lib')):
+  for lib_path in os.listdir(os.path.join(LLVM_BOOTSTRAP_DIR, 'lib')):
     for lib_want in clang_libs_want:
       if fnmatch.fnmatch(lib_path, lib_want):
-        shutil.copy(os.path.join(LLVM_RELEASE_DIR, 'lib', lib_path),
+        shutil.copy(os.path.join(LLVM_BOOTSTRAP_DIR, 'lib', lib_path),
                     os.path.join(clang_libs_dir, 'lib'))
   PackageInArchive(clang_libs_dir, clang_libs_dir + '.tgz')
   MaybeUpload(args.upload, clang_libs_dir + '.tgz', gcs_platform)
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 0fb53bb..e4b868f 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -36,7 +36,7 @@
 # Reverting problematic clang rolls is safe, though.
 # This is the output of `git describe` and is usable as a commit-ish.
 CLANG_REVISION = 'llvmorg-15-init-1995-g5bec1ea7'
-CLANG_SUB_REVISION = 1
+CLANG_SUB_REVISION = 2
 
 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION)
 RELEASE_VERSION = '15.0.0'
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 87a3fdd..656b3f8 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -815,7 +815,6 @@
       'android-inverse-fieldtrials-pie-x86-fyi-rel': 'android_release_trybot_x86_fastbuild_webview_google_invert_fieldtrials',
       'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_resource_allowlisting_fastbuild_java_coverage',
       'android-marshmallow-x86-rel': 'android_release_trybot_x86_fastbuild_resource_allowlisting_webview_google_coverage',
-      'android-marshmallow-x86-rel-orchestrator': 'android_release_trybot_x86_fastbuild_resource_allowlisting_webview_google_coverage',
       'android-marshmallow-x86-rel-non-cq': 'android_release_trybot_x86_fastbuild_resource_allowlisting_webview_google',
       'android-oreo-arm64-cts-networkservice-dbg': 'android_debug_trybot_arm64',
       # TODO(crbug/1182468) Remove android coverage bots after coverage is
@@ -1048,7 +1047,6 @@
       'linux-perfetto-rel': 'perfetto_release_trybot',
       'linux-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage_do_typecheck',
       'linux-rel-warmed': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage',
-      'linux-rel-orchestrator': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage_do_typecheck',
       'linux-trusty-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange',
       'linux-viz-rel': 'release_trybot',
       'linux-wpt-fyi-rel': 'release_trybot',
@@ -1058,7 +1056,6 @@
       'linux-xenial-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange',
       'linux_chromium_archive_rel_ng': 'release_bot',
       'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot',
-      'linux_chromium_asan_rel_ng-orchestrator': 'asan_lsan_release_trybot',
       'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_goma',
       'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_bot_dcheck_always_on',
       'linux_chromium_chromeos_msan_rel_ng': 'chromeos_msan_release_bot',
@@ -1075,7 +1072,6 @@
       'linux_chromium_msan_rel_ng': 'msan_release_bot',
 
       'linux_chromium_tsan_rel_ng': 'tsan_disable_nacl_release_trybot',
-      'linux_chromium_tsan_rel_ng-orchestrator': 'tsan_disable_nacl_release_trybot',
 
       # This is intentionally a release_bot and not a release_trybot to match
       # the CI configuration, where no debug builder exists.
@@ -1143,7 +1139,6 @@
       'mac-builder-next-rel': 'mac_arm64_gpu_tests_release_bot_minimal_symbols_no_nacl',
       'mac-inverse-fieldtrials-fyi-rel': 'gpu_tests_release_trybot_invert_fieldtrials',
       'mac-rel': 'gpu_tests_release_trybot_no_symbols_mac_code_coverage',
-      'mac-rel-orchestrator': 'gpu_tests_release_trybot_no_symbols_mac_code_coverage',
       'mac11-arm64-rel': 'mac_arm64_gpu_tests_release_trybot_no_symbols',
     },
 
@@ -1213,7 +1208,6 @@
       'win10_chromium_x64_dbg_ng': 'gpu_tests_debug_bot',
       'win10_chromium_x64_rel_ng': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
       'win10_chromium_x64_rel_ng_exp': 'release_trybot',
-      'win10-rel-orchestrator': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
       'win11-x64-fyi-rel': 'gpu_tests_release_trybot_resource_allowlisting_code_coverage',
       'win-annotator-rel': 'release_trybot',
       'win-asan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release',
@@ -1673,7 +1667,7 @@
     ],
 
     'angle_deqp_release_trybot_reclient': [
-      'angle_deqp_tests', 'shared_release_bot_dcheck_always_on', 'reclient',
+      'angle_deqp_tests', 'shared_release_bot_dcheck_always_on_reclient',
     ],
 
     'angle_deqp_release_trybot_x86': [
@@ -4047,6 +4041,10 @@
       'mixins': ['shared_release_bot', 'minimal_symbols', 'dcheck_always_on'],
     },
 
+    'shared_release_bot_dcheck_always_on_reclient': {
+      'mixins': ['shared_release_bot_reclient', 'minimal_symbols', 'dcheck_always_on'],
+    },
+
     'shared_release_bot_reclient': {
       'mixins': ['shared', 'release', 'reclient']
     },
diff --git a/tools/mb/mb_config_expectations/chromium.swangle.json b/tools/mb/mb_config_expectations/chromium.swangle.json
index 272eb76..872614b 100644
--- a/tools/mb/mb_config_expectations/chromium.swangle.json
+++ b/tools/mb/mb_config_expectations/chromium.swangle.json
@@ -19,7 +19,6 @@
       "is_component_build": true,
       "is_debug": false,
       "symbol_level": 1,
-      "use_goma": true,
       "use_rbe": true,
       "use_remoteexec": true
     }
@@ -31,7 +30,6 @@
       "is_component_build": true,
       "is_debug": false,
       "symbol_level": 1,
-      "use_goma": true,
       "use_rbe": true,
       "use_remoteexec": true
     }
@@ -43,7 +41,6 @@
       "is_component_build": true,
       "is_debug": false,
       "symbol_level": 1,
-      "use_goma": true,
       "use_rbe": true,
       "use_remoteexec": true
     }
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index d5f597db..a7a6bf7 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -605,26 +605,6 @@
       "use_goma": true
     }
   },
-  "android-marshmallow-x86-rel-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "disable_android_lint": true,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "strip_debug_info": true,
-      "symbol_level": 0,
-      "system_webview_package_name": "com.google.android.webview",
-      "target_cpu": "x86",
-      "target_os": "android",
-      "use_errorprone_java_compiler": false,
-      "use_goma": true,
-      "use_jacoco_coverage": true
-    }
-  },
   "android-opus-arm-rel": {
     "gn_args": {
       "blink_enable_generated_code_formatting": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
index 11b2551..222d53b 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -675,22 +675,6 @@
       "use_goma": true
     }
   },
-  "linux-rel-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "devtools_skip_typecheck": false,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "use_clang_coverage": true,
-      "use_dummy_lastchange": true,
-      "use_goma": true
-    }
-  },
   "linux-rel-warmed": {
     "gn_args": {
       "blink_enable_generated_code_formatting": false,
@@ -820,18 +804,6 @@
       "use_goma": true
     }
   },
-  "linux_chromium_asan_rel_ng-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "dcheck_always_on": true,
-      "is_asan": true,
-      "is_component_build": false,
-      "is_debug": false,
-      "is_lsan": true,
-      "symbol_level": 1,
-      "use_goma": true
-    }
-  },
   "linux_chromium_cfi_rel_ng": {
     "gn_args": {
       "dcheck_always_on": true,
@@ -948,18 +920,6 @@
       "use_goma": true
     }
   },
-  "linux_chromium_tsan_rel_ng-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "dcheck_always_on": true,
-      "enable_nacl": false,
-      "is_component_build": false,
-      "is_debug": false,
-      "is_tsan": true,
-      "symbol_level": 1,
-      "use_goma": true
-    }
-  },
   "linux_chromium_ubsan_rel_ng": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index b938792..f5085c1 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -511,20 +511,6 @@
       "use_goma": true
     }
   },
-  "mac-rel-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "use_clang_coverage": true,
-      "use_goma": true
-    }
-  },
   "mac11-arm64-rel": {
     "gn_args": {
       "blink_enable_generated_code_formatting": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.win.json b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
index 0b02b47..6b6df087 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.win.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.win.json
@@ -239,21 +239,6 @@
       "use_goma": true
     }
   },
-  "win10-rel-orchestrator": {
-    "gn_args": {
-      "blink_enable_generated_code_formatting": false,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "enable_resource_allowlist_generation": false,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "use_clang_coverage": true,
-      "use_goma": true
-    }
-  },
   "win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng": {
     "gn_args": {
       "blink_enable_generated_code_formatting": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8b49de9..2ddadcb 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8173,6 +8173,7 @@
 </enum>
 
 <enum name="BackgroundTaskId">
+  <int value="-1" label="Not found"/>
   <int value="0" label="Test task (should not appear)"/>
   <int value="1" label="Omaha"/>
   <int value="2" label="GCM Background Task"/>
@@ -51676,6 +51677,7 @@
   <int value="-1928198763" label="enable-async-dns"/>
   <int value="-1927968708" label="OmniboxPedalsAndroidBatch1:disabled"/>
   <int value="-1927080237" label="Vulkan:enabled"/>
+  <int value="-1926236767" label="DynamicColorButtonsAndroid:enabled"/>
   <int value="-1926124919" label="WebViewOriginTrials:enabled"/>
   <int value="-1925453192" label="BlockInsecurePrivateNetworkRequests:enabled"/>
   <int value="-1925214028"
@@ -53031,6 +53033,7 @@
   <int value="-1013986101" label="FirstScrollLatencyMeasurement:disabled"/>
   <int value="-1011390415" label="AutofillRejectCompanyBirthyear:enabled"/>
   <int value="-1010588306" label="SlideTopChromeWithPageScrolls:disabled"/>
+  <int value="-1009111883" label="NearbyShareVisibilityReminder:enabled"/>
   <int value="-1008511612" label="EnableCustomMacPaperSizes:disabled"/>
   <int value="-1008130438" label="PageEntitiesPageContentAnnotations:enabled"/>
   <int value="-1007961880" label="PrivacySandboxSettings:enabled"/>
@@ -53893,6 +53896,7 @@
   <int value="-395259448" label="VideoPlayerJsModules:disabled"/>
   <int value="-394734604" label="FillingPasswordsFromAnyOrigin:disabled"/>
   <int value="-392813122" label="LibinputHandleTouchpad"/>
+  <int value="-390798267" label="DynamicColorButtonsAndroid:disabled"/>
   <int value="-390624541" label="RestrictedApiOrigins:disabled"/>
   <int value="-389664522"
       label="OmniboxUIExperimentHideSteadyStateUrlPathQueryAndRefOnInteraction:enabled"/>
@@ -54015,7 +54019,6 @@
   <int value="-304777110" label="PreconnectToSearch:disabled"/>
   <int value="-303992327" label="SwipeToMoveCursor:disabled"/>
   <int value="-302407285" label="WipeDataOnChildAccountSignin:disabled"/>
-  <int value="-302083217" label="WebViewDarkModeMatchTheme:enabled"/>
   <int value="-301689561" label="PermissionQuietChip:disabled"/>
   <int value="-301228557" label="PageInfoDiscoverability:disabled"/>
   <int value="-300018686" label="disable-cloud-import"/>
@@ -54104,6 +54107,7 @@
   <int value="-238415226" label="GlobalVaapiLock:disabled"/>
   <int value="-237367320" label="AssistantAudioEraser:disabled"/>
   <int value="-236433493" label="ArcKeyboardShortcutHelperIntegration:enabled"/>
+  <int value="-236071174" label="NearbyShareVisibilityReminder:disabled"/>
   <int value="-235949168" label="DrawPredictedInkPoint:enabled"/>
   <int value="-234966279" label="PointerEvent:disabled"/>
   <int value="-234687894"
@@ -56149,7 +56153,6 @@
   <int value="1206140820" label="RelatedSearchesInBar:disabled"/>
   <int value="1210298193" label="FontAccessPersistent:enabled"/>
   <int value="1210343926" label="enable-drop-sync-credential"/>
-  <int value="1210958725" label="WebViewDarkModeMatchTheme:disabled"/>
   <int value="1211284676" label="V8NoTurbo:enabled"/>
   <int value="1211756417"
       label="SessionRestorePrioritizesBackgroundUseCases:disabled"/>
@@ -58275,6 +58278,7 @@
   <int value="23" label="Is not stacking context (obsolete)"/>
   <int value="24" label="Blocking wheel event handler region"/>
   <int value="25" label="Blocking touch event handler region"/>
+  <int value="26" label="Popup scrolling (no threaded input handler)"/>
 </enum>
 
 <enum name="MakeChromeDefaultResult">
@@ -79893,6 +79897,17 @@
   <int value="7" label="Unable to determine leaf hash"/>
 </enum>
 
+<enum name="SCTLookupQueryResult">
+  <int value="0" label="HTTP error"/>
+  <int value="1" label="Invalid JSON"/>
+  <int value="2" label="Status not OK"/>
+  <int value="3" label="Certificate expired"/>
+  <int value="4" label="Log not found"/>
+  <int value="5" label="Log not yet ingested"/>
+  <int value="6" label="SCT suffix found"/>
+  <int value="7" label="SCT suffix not found"/>
+</enum>
+
 <enum name="SCTOrigin">
   <int value="0" label="SCT_EMBEDDED"/>
   <int value="1" label="SCT_FROM_TLS_EXTENSION"/>
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml
index fd8cc0ee..4038daa 100644
--- a/tools/metrics/histograms/metadata/accessibility/histograms.xml
+++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -158,6 +158,27 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.Android.Cache.MaxNodesInCache" units="count"
+    expires_after="2022-08-22">
+  <owner>mschillaci@google.com</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    Tracks the maximum number of AccessibilityNodeInfo objects that were stored
+    in the Java-side cache during a single session.
+  </summary>
+</histogram>
+
+<histogram name="Accessibility.Android.Cache.PercentageRetrievedFromCache"
+    units="%" expires_after="2022-08-22">
+  <owner>mschillaci@google.com</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    Tracks the percentage of calls from the Android framework to create a new
+    AccessibilityNodeInfo object that were serviced from the cache rather than
+    constructing the object from scratch during a single session.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.Android.OnDemand.EventsDropped" units="count"
     expires_after="2022-08-07">
   <owner>mschillaci@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 7b4e324..96e81ef 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -1500,6 +1500,16 @@
   <summary>Records the number of tabs in a template when it is saved.</summary>
 </histogram>
 
+<histogram name="Ash.DeskTemplate.TimeToLoadTemplate" units="ms"
+    expires_after="2023-01-18">
+  <owner>avynn@google.com</owner>
+  <owner>janetmac@chromium.org</owner>
+  <summary>
+    Measures the amount of time it takes to launch a template from the time that
+    the launch is invoked to the time that the last window is opened.
+  </summary>
+</histogram>
+
 <histogram name="Ash.DeskTemplate.UnsupportedAppDialogShow" units="count"
     expires_after="2023-01-04">
   <owner>avynn@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index b932afc..207b0b6f 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -335,7 +335,8 @@
   <obsolete>
     Replaced by Browser.Responsiveness.JankyIntervalsPerThirtySeconds3
   </obsolete>
-  <owner>erikchen@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
+  <owner>etienneb@chromium.org</owner>
   <owner>fdoray@chromium.org</owner>
   <summary>
     This metric is emitted every 30 seconds after main message loop start, when
@@ -386,7 +387,8 @@
     units="janks" expires_after="never">
 <!-- expires-never: guiding metric (internal: go/chrome-browser-guiding-metrics) -->
 
-  <owner>erikchen@chromium.org</owner>
+  <owner>gab@chromium.org</owner>
+  <owner>etienneb@chromium.org</owner>
   <owner>chrome-analysis-team@google.com</owner>
   <summary>
     This metric is emitted every 30 seconds [when there is user activity]. Each
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index 5080af7..e307e98 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <variants name="AnnotationType">
-  <variant name="CotentVisibility" summary="Cotent Visibility"/>
+  <variant name="ContentVisibility" summary="Content Visibility"/>
   <variant name="PageEntities" summary="Page Entities"/>
   <variant name="PageTopics" summary="Page Topics"/>
   <variant name="Unknown" summary="Unknown"/>
@@ -501,6 +501,32 @@
   <token key="OptimizationTarget" variants="OptimizationTarget"/>
 </histogram>
 
+<histogram
+    name="OptimizationGuide.ModelHandler.HandlerCreated.{OptimizationTarget}"
+    enum="BooleanCreated" expires_after="M106">
+  <owner>sophiechang@chromium.org</owner>
+  <owner>chrome-intelligence-core@google.com</owner>
+  <summary>
+    Records that the model handler has been created for {OptimizationTarget}.
+    Recorded once for each session (profile start) that the model handler is
+    created for {OptimizationTarget}.
+  </summary>
+  <token key="OptimizationTarget" variants="OptimizationTarget"/>
+</histogram>
+
+<histogram
+    name="OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable.{OptimizationTarget}"
+    units="ms" expires_after="M106">
+  <owner>sophiechang@chromium.org</owner>
+  <owner>chrome-intelligence-core@google.com</owner>
+  <summary>
+    Records the time duration between the handler getting created to the model
+    being available for {OptimizationTarget}. Recorded once for each session
+    (profile start) that the model handler is created for {OptimizationTarget}.
+  </summary>
+  <token key="OptimizationTarget" variants="OptimizationTarget"/>
+</histogram>
+
 <histogram name="OptimizationGuide.OptimizationFilterStatus.{OptimizationType}"
     enum="OptimizationGuideOptimizationFilterStatus" expires_after="M106">
   <owner>mcrouse@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index bf2c562..6aa9353 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -576,6 +576,17 @@
   </summary>
 </histogram>
 
+<histogram name="Security.SCTAuditing.OptOut.LookupQueryResult"
+    enum="SCTLookupQueryResult" expires_after="M104">
+  <owner>cthomp@chromium.org</owner>
+  <owner>nsatragno@chromium.org</owner>
+  <owner>trusty-transport@chromium.org</owner>
+  <summary>
+    Records the result of a hashdance lookup query. Recorded once per query
+    regardless of whether the query succeeded, failed, or is a retry.
+  </summary>
+</histogram>
+
 <histogram name="Security.SCTAuditing.OptOut.PopularSCTSkipped" enum="Boolean"
     expires_after="M104">
   <owner>cthomp@chromium.org</owner>
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index b5e04ae..32463c97 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -1,7 +1,8 @@
 # Test Expectation file for telemetry tests.
 # Instructions of how to use this file:
 # https://chromium.googlesource.com/chromium/src/+/main/docs/speed/bot_health_sheriffing/how_to_disable_a_story.md
-# tags: [ android chromeos chromeos-local chromeos-remote linux mac mac-10.12 mac-10.13 win win10 win7 win-laptop
+# tags: [ android chromeos chromeos-local chromeos-remote
+#         linux mac mac-10.12 mac-10.13 mac-arm64 mac-x86_64 win win10 win7 win-laptop
 #         sierra highsierra android-marshmallow android-lollipop android-nougat android-oreo android-pie android-10
 #         android-kitkat ubuntu fuchsia fuchsia-board-astro fuchsia-board-sherlock fuchsia-chrome ]
 # tags: [ android-go android-low-end android-nexus-5 android-nexus-5x android-nexus-6
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py
index c5eaa93..8f57862 100755
--- a/tools/rust/build_rust.py
+++ b/tools/rust/build_rust.py
@@ -52,9 +52,10 @@
 from update import (CHROMIUM_DIR, CLANG_REVISION, CLANG_SUB_REVISION,
                     LLVM_BUILD_DIR, GetDefaultHostOs, RmTree, UpdatePackage)
 import build
+from build import (LLVM_BOOTSTRAP_DIR)
 
-# Trunk on 2/10/2021
-RUST_REVISION = '502d6aa'
+# Trunk on 2/24/2022
+RUST_REVISION = '4b043fa'
 RUST_SUB_REVISION = 1
 
 PACKAGE_VERSION = '%s-%s-%s-%s' % (RUST_REVISION, RUST_SUB_REVISION,
@@ -127,14 +128,14 @@
   sys.exit(1)
 
 
-def Configure():
+def Configure(llvm_libs_root):
   # Read the config.toml template file...
   with open(RUST_CONFIG_TEMPLATE_PATH, 'r') as input:
     template = string.Template(input.read())
 
   subs = {}
   subs['INSTALL_DIR'] = RUST_TOOLCHAIN_OUT_DIR
-  subs['LLVM_ROOT'] = LLVM_BUILD_DIR
+  subs['LLVM_ROOT'] = llvm_libs_root
   subs['PACKAGE_VERSION'] = PACKAGE_VERSION
 
   # ...and apply substitutions, writing to config.toml in Rust tree.
@@ -173,8 +174,8 @@
   RUSTENV['RUSTFLAGS_NOT_BOOTSTRAP'] = RUSTENV['RUSTFLAGS_BOOTSTRAP']
   os.chdir(RUST_SRC_DIR)
   cmd = [sys.executable, 'x.py', sub]
-  if verbose:
-    cmd.append('-v')
+  if verbose and verbose > 0:
+    cmd.append('-' + verbose * 'v')
   RunCommand(cmd + args, env=RUSTENV)
 
 
@@ -183,7 +184,7 @@
       description='Build and package Rust toolchain')
   parser.add_argument('-v',
                       '--verbose',
-                      action='store_true',
+                      action='count',
                       help='run subcommands with verbosity')
   parser.add_argument(
       '--skip-checkout',
@@ -201,12 +202,27 @@
   parser.add_argument(
       '--fetch-llvm-libs',
       action='store_true',
-      help='fetch Clang/LLVM libs and extract into LLVM_BUILD_DIR')
+      help='fetch Clang/LLVM libs and extract into LLVM_BUILD_DIR. Useless '
+      'without --llvm-not-bootstrap-dir.')
+  parser.add_argument(
+      '--llvm-not-bootstrap-dir',
+      action='store_true',
+      help='use libs in LLVM_BUILD_DIR instead of LLVM_BOOTSTRAP_DIR. Useful '
+      'with --fetch-llvm-libs for local builds.')
   args = parser.parse_args()
 
   if args.fetch_llvm_libs:
     UpdatePackage('clang-libs', GetDefaultHostOs())
 
+  # Get the LLVM root for libs. We use LLVM_BUILD_DIR tools either way.
+  #
+  # TODO(https://crbug.com/1245714): use LTO libs from LLVM_BUILD_DIR for
+  # stage 2+.
+  if args.llvm_not_bootstrap_dir:
+    llvm_libs_root = LLVM_BUILD_DIR
+  else:
+    llvm_libs_root = LLVM_BOOTSTRAP_DIR
+
   # Fetch GCC package to build against same libstdc++ as Clang. This function
   # will only download it if necessary.
   args.gcc_toolchain = None
@@ -223,7 +239,7 @@
       shutil.rmtree(dir)
 
   # Set up config.toml in Rust source tree to configure build.
-  Configure()
+  Configure(llvm_libs_root)
 
   if not args.skip_clean:
     RunXPy('clean', [], args.gcc_toolchain, args.verbose)
diff --git a/ui/accessibility/platform/ax_fragment_root_win.cc b/ui/accessibility/platform/ax_fragment_root_win.cc
index 706ab53..70e679b06 100644
--- a/ui/accessibility/platform/ax_fragment_root_win.cc
+++ b/ui/accessibility/platform/ax_fragment_root_win.cc
@@ -17,13 +17,11 @@
 
 class AXFragmentRootPlatformNodeWin : public AXPlatformNodeWin,
                                       public IItemContainerProvider,
-                                      public IRawElementProviderFragmentRoot,
-                                      public IRawElementProviderAdviseEvents {
+                                      public IRawElementProviderFragmentRoot {
  public:
   BEGIN_COM_MAP(AXFragmentRootPlatformNodeWin)
   COM_INTERFACE_ENTRY(IItemContainerProvider)
   COM_INTERFACE_ENTRY(IRawElementProviderFragmentRoot)
-  COM_INTERFACE_ENTRY(IRawElementProviderAdviseEvents)
   COM_INTERFACE_ENTRY_CHAIN(AXPlatformNodeWin)
   END_COM_MAP()
 
@@ -219,45 +217,6 @@
 
     return S_OK;
   }
-
-  //
-  // IRawElementProviderAdviseEvents methods.
-  //
-  IFACEMETHODIMP AdviseEventAdded(EVENTID event_id,
-                                  SAFEARRAY* property_ids) override {
-    WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ADVISE_EVENT_ADDED);
-    if (event_id == UIA_LiveRegionChangedEventId) {
-      live_region_change_listeners_++;
-
-      if (live_region_change_listeners_ == 1) {
-        // Fire a LiveRegionChangedEvent for each live-region to tell the
-        // newly-attached assistive technology about the regions.
-        //
-        // Ideally we'd be able to direct these events to only the
-        // newly-attached AT, but we don't have that capability, so we only
-        // fire events when the *first* AT attaches. (A common scenario will
-        // be an attached screen-reader, then a software-keyboard attaches to
-        // handle an input field; we don't want the screen-reader to announce
-        // that every live-region has changed.) There isn't a perfect solution,
-        // but this heuristic seems to work well in practice.
-        FireLiveRegionChangeRecursive();
-      }
-    }
-    return S_OK;
-  }
-
-  IFACEMETHODIMP AdviseEventRemoved(EVENTID event_id,
-                                    SAFEARRAY* property_ids) override {
-    WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_ADVISE_EVENT_REMOVED);
-    if (event_id == UIA_LiveRegionChangedEventId) {
-      DCHECK(live_region_change_listeners_ > 0);
-      live_region_change_listeners_--;
-    }
-    return S_OK;
-  }
-
- private:
-  int32_t live_region_change_listeners_ = 0;
 };
 
 class AXFragmentRootMapWin {
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index a78d01f..7a6ba2d0 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -7158,6 +7158,8 @@
     switch (GetRole()) {
       case ax::mojom::Role::kArticle:
       case ax::mojom::Role::kBlockquote:
+      case ax::mojom::Role::kCell:
+      case ax::mojom::Role::kColumn:
       case ax::mojom::Role::kDetails:
       case ax::mojom::Role::kFigure:
       case ax::mojom::Role::kFooter:
@@ -7169,6 +7171,7 @@
       case ax::mojom::Role::kListItem:
       case ax::mojom::Role::kMeter:
       case ax::mojom::Role::kProgressIndicator:
+      case ax::mojom::Role::kRow:
       case ax::mojom::Role::kSection:
       case ax::mojom::Role::kSplitter:
       case ax::mojom::Role::kTime:
@@ -7974,27 +7977,6 @@
   return nullptr;
 }
 
-void AXPlatformNodeWin::FireLiveRegionChangeRecursive() {
-  const auto live_status_attr = ax::mojom::StringAttribute::kLiveStatus;
-  if (HasStringAttribute(live_status_attr) &&
-      GetStringAttribute(live_status_attr) != "off") {
-    DCHECK(GetDelegate()->IsWebContent());
-    ::UiaRaiseAutomationEvent(this, UIA_LiveRegionChangedEventId);
-    return;
-  }
-
-  for (int index = 0; index < GetChildCount(); ++index) {
-    auto* child = static_cast<AXPlatformNodeWin*>(
-        FromNativeViewAccessible(ChildAtIndex(index)));
-
-    // We assume that only web-content will have live regions; also because
-    // this will be called on each fragment-root, there is no need to walk
-    // through non-content nodes.
-    if (child->GetDelegate()->IsWebContent())
-      child->FireLiveRegionChangeRecursive();
-  }
-}
-
 AXPlatformNodeWin* AXPlatformNodeWin::GetLowestAccessibleElementForUIA() {
   AXPlatformNodeWin* node = this;
   while (node) {
diff --git a/ui/accessibility/platform/ax_platform_node_win.h b/ui/accessibility/platform/ax_platform_node_win.h
index 1cd4653..a34338d 100644
--- a/ui/accessibility/platform/ax_platform_node_win.h
+++ b/ui/accessibility/platform/ax_platform_node_win.h
@@ -1134,22 +1134,19 @@
   void GetRuntimeIdArray(RuntimeIdArray& runtime_id);
 
   // Updates the active composition range and fires UIA text edit event about
-  // composition (active or committed)
+  // composition (active or committed).
   void OnActiveComposition(const gfx::Range& range,
                            const std::u16string& active_composition_text,
                            bool is_composition_committed);
-  // Returns true if there is an active composition
+  // Returns true if there is an active composition.
   bool HasActiveComposition() const;
-  // Returns the start/end offsets of the active composition
+  // Returns the start/end offsets of the active composition.
   gfx::Range GetActiveCompositionOffsets() const;
 
-  // Helper to recursively find live-regions and fire a change event on them
-  void FireLiveRegionChangeRecursive();
-
   // Returns the first ancestor node that is accessible for UIA.
   AXPlatformNodeWin* GetLowestAccessibleElementForUIA();
 
-  // Returns the first |IsTextOnlyObject| descendant using
+  // Returns the first |IsTextOnlyObject| descendant using.
   // depth-first pre-order traversal.
   AXPlatformNodeWin* GetFirstTextOnlyDescendant();
 
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index fbc2cef..7343de1e 100644
--- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -4073,6 +4073,57 @@
       L"required=false");
 }
 
+TEST_F(AXPlatformNodeWinTest, UIAControlContentProperty) {
+  AXNodeData root;
+  root.id = 1;
+  root.role = ax::mojom::Role::kTable;
+
+  AXNodeData row1;
+  row1.id = 2;
+  row1.role = ax::mojom::Role::kRow;
+  root.child_ids.push_back(row1.id);
+
+  AXNodeData cell1;
+  cell1.id = 3;
+  cell1.role = ax::mojom::Role::kCell;
+  row1.child_ids.push_back(cell1.id);
+
+  AXNodeData generic_container;
+  generic_container.id = 4;
+  generic_container.role = ax::mojom::Role::kGenericContainer;
+  cell1.child_ids.push_back(generic_container.id);
+
+  Init(root, row1, cell1, generic_container);
+
+  // Turn on web content mode for the AXTree.
+  TestAXNodeWrapper::SetGlobalIsWebContent(true);
+
+  ComPtr<IRawElementProviderSimple> root_node =
+      GetRootIRawElementProviderSimple();
+  EXPECT_UIA_BOOL_EQ(root_node, UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(root_node, UIA_IsContentElementPropertyId, true);
+
+  ComPtr<IRawElementProviderSimple> row =
+      QueryInterfaceFromNode<IRawElementProviderSimple>(
+          GetRootAsAXNode()->children()[0]);
+  EXPECT_UIA_BOOL_EQ(row, UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(row, UIA_IsContentElementPropertyId, true);
+
+  ComPtr<IRawElementProviderSimple> cell =
+      QueryInterfaceFromNode<IRawElementProviderSimple>(
+          GetRootAsAXNode()->children()[0]->children()[0]);
+  EXPECT_UIA_BOOL_EQ(cell, UIA_IsControlElementPropertyId, true);
+  EXPECT_UIA_BOOL_EQ(cell, UIA_IsContentElementPropertyId, true);
+
+  ComPtr<IRawElementProviderSimple> generic_container_provider =
+      QueryInterfaceFromNode<IRawElementProviderSimple>(
+          GetRootAsAXNode()->children()[0]->children()[0]->children()[0]);
+  EXPECT_UIA_BOOL_EQ(generic_container_provider, UIA_IsControlElementPropertyId,
+                     false);
+  EXPECT_UIA_BOOL_EQ(generic_container_provider, UIA_IsContentElementPropertyId,
+                     false);
+}
+
 TEST_F(AXPlatformNodeWinTest, UIAGetPropertyValueClickablePoint) {
   AXNodeData root;
   root.id = 1;
diff --git a/ui/android/java/src/org/chromium/ui/base/DragAndDropDelegateImpl.java b/ui/android/java/src/org/chromium/ui/base/DragAndDropDelegateImpl.java
index f121064..72f785d 100644
--- a/ui/android/java/src/org/chromium/ui/base/DragAndDropDelegateImpl.java
+++ b/ui/android/java/src/org/chromium/ui/base/DragAndDropDelegateImpl.java
@@ -16,6 +16,7 @@
 import android.view.DragEvent;
 import android.view.View;
 import android.view.View.DragShadowBuilder;
+import android.view.accessibility.AccessibilityManager;
 import android.widget.ImageView;
 
 import androidx.annotation.IntDef;
@@ -75,6 +76,13 @@
     @RequiresApi(api = VERSION_CODES.N)
     public boolean startDragAndDrop(@NonNull View containerView, @NonNull Bitmap shadowImage,
             @NonNull DropDataAndroid dropData) {
+        // Drag and drop is disabled when gesture related a11y service is enabled.
+        // See https://crbug.com/1250067.
+        AccessibilityManager a11yManager =
+                (AccessibilityManager) containerView.getContext().getSystemService(
+                        Context.ACCESSIBILITY_SERVICE);
+        if (a11yManager.isEnabled() && a11yManager.isTouchExplorationEnabled()) return false;
+
         ClipData clipdata = buildClipData(dropData);
         if (clipdata == null) {
             return false;
diff --git a/ui/android/java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java b/ui/android/java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java
index 53896d07..5a755753 100644
--- a/ui/android/java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java
+++ b/ui/android/java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java
@@ -4,6 +4,7 @@
 
 package org.chromium.ui.text;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.text.TextPaint;
 import android.text.style.ClickableSpan;
@@ -11,7 +12,6 @@
 
 import androidx.annotation.ColorRes;
 
-import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
 import org.chromium.ui.R;
 
@@ -23,21 +23,21 @@
     private final Callback<View> mOnClick;
 
     /**
-     * @param resources The {@link Resources} used for accessing colors.
+     * @param context The {@link Context} used for accessing colors.
      * @param onClickCallback The callback notified when the span is clicked.
      */
-    public NoUnderlineClickableSpan(Resources resources, Callback<View> onClickCallback) {
-        this(resources, R.color.default_text_color_link_baseline, onClickCallback);
+    public NoUnderlineClickableSpan(Context context, Callback<View> onClickCallback) {
+        this(context, R.color.default_text_color_link_baseline, onClickCallback);
     }
 
     /**
-     * @param resources The {@link Resources} used for accessing colors.
+     * @param context The {@link Resources} used for accessing colors.
      * @param colorResId The {@link ColorRes} of this clickable span.
      * @param onClickCallback The callback notified when the span is clicked.
      */
     public NoUnderlineClickableSpan(
-            Resources resources, @ColorRes int colorResId, Callback<View> onClickCallback) {
-        mColor = ApiCompatibilityUtils.getColor(resources, colorResId);
+            Context context, @ColorRes int colorResId, Callback<View> onClickCallback) {
+        mColor = context.getColor(colorResId);
         mOnClick = onClickCallback;
     }
 
diff --git a/ui/android/junit/src/org/chromium/ui/base/DragAndDropDelegateImplUnitTest.java b/ui/android/junit/src/org/chromium/ui/base/DragAndDropDelegateImplUnitTest.java
index e048dee..6f440e9 100644
--- a/ui/android/junit/src/org/chromium/ui/base/DragAndDropDelegateImplUnitTest.java
+++ b/ui/android/junit/src/org/chromium/ui/base/DragAndDropDelegateImplUnitTest.java
@@ -6,11 +6,14 @@
 
 import static org.mockito.Mockito.doReturn;
 
+import android.content.ClipData;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.util.Pair;
 import android.view.DragEvent;
 import android.view.View;
+import android.view.View.DragShadowBuilder;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.test.core.app.ApplicationProvider;
 
@@ -21,8 +24,13 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowAccessibilityManager;
 import org.robolectric.shadows.ShadowDisplay;
 
+import org.chromium.base.compat.ApiHelperForN;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.ui.base.DragAndDropDelegateImpl.DragTargetType;
@@ -36,6 +44,16 @@
 @Config(shadows = {ShadowDisplay.class, ShadowRecordHistogram.class},
         qualifiers = "w1000dp-h2000dp-mdpi")
 public class DragAndDropDelegateImplUnitTest {
+    /** Helper shadow class to make sure #startDragAndDrop is accepted by Android. */
+    @Implements(ApiHelperForN.class)
+    static class ShadowApiHelperForN {
+        @Implementation
+        public static boolean startDragAndDrop(View view, ClipData data,
+                DragShadowBuilder shadowBuilder, Object myLocalState, int flags) {
+            return true;
+        }
+    }
+
     private Context mContext;
     private DragAndDropDelegateImpl mDragAndDropDelegateImpl;
 
@@ -123,6 +141,26 @@
     }
 
     @Test
+    @Config(shadows = {ShadowApiHelperForN.class, ShadowAccessibilityManager.class})
+    public void testStartDragAndDrop_NotSupportedForA11y() {
+        final View containerView = new View(mContext);
+        final Bitmap shadowImage = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+        final DropDataAndroid dropData = DropDataAndroid.create("text", null, null, null);
+
+        Assert.assertTrue("Drag and drop should start.",
+                mDragAndDropDelegateImpl.startDragAndDrop(containerView, shadowImage, dropData));
+
+        AccessibilityManager a11yManager =
+                (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        ShadowAccessibilityManager shadowA11yManager = Shadow.extract(a11yManager);
+        shadowA11yManager.setEnabled(true);
+        shadowA11yManager.setTouchExplorationEnabled(true);
+
+        Assert.assertFalse("Drag and drop should not start when isTouchExplorationEnabled=true.",
+                mDragAndDropDelegateImpl.startDragAndDrop(containerView, shadowImage, dropData));
+    }
+
+    @Test
     public void testDragImage_DragHandled() {
         final View containerView = new View(mContext);
         final Bitmap shadowImage = Bitmap.createBitmap(100, 200, Bitmap.Config.ALPHA_8);
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 6bc16c51..851bff2 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -9,6 +9,7 @@
     <title>$i18n{FILEMANAGER_APP_NAME}</title>
 
     <meta name="google" value="notranslate">
+    <meta name="color-scheme" content="light dark">
 
     <link rel="stylesheet" href="chrome://resources/css/action_link.css">
     <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
diff --git a/ui/gfx/buffer_types.h b/ui/gfx/buffer_types.h
index 41fd034..45d2469 100644
--- a/ui/gfx/buffer_types.h
+++ b/ui/gfx/buffer_types.h
@@ -36,11 +36,13 @@
 
 // The usage mode affects how a buffer can be used. Only buffers created with
 // *_CPU_READ_WRITE_* can be mapped into the client's address space and accessed
-// by the CPU. SCANOUT implies GPU_READ_WRITE.
-// *_VDA_WRITE is for cases where a video decode accellerator writes into
-// the buffers.
+// by the CPU.
+// *_VDA_WRITE is for cases where a video decode accelerator writes into the
+// buffers.
 // PROTECTED_* are for HW protected buffers that cannot be read by the CPU and
 // can only be read in protected GPU contexts or scanned out to overlays.
+// At present, SCANOUT implies GPU_READ_WRITE. This doesn't apply to other
+// SCANOUT_* values.
 
 // TODO(reveman): Add GPU_READ_WRITE for use-cases where SCANOUT is not
 // required.
diff --git a/ui/gfx/color_conversion_sk_filter_cache.cc b/ui/gfx/color_conversion_sk_filter_cache.cc
index 2f6b559..14d53702 100644
--- a/ui/gfx/color_conversion_sk_filter_cache.cc
+++ b/ui/gfx/color_conversion_sk_filter_cache.cc
@@ -31,16 +31,6 @@
 
 }  // namespace
 
-bool IsHLGOrPQ(const gfx::ColorSpace& color_space) {
-  switch (color_space.GetTransferID()) {
-    case gfx::ColorSpace::TransferID::HLG:
-    case gfx::ColorSpace::TransferID::PQ:
-      return true;
-    default:
-      return false;
-  }
-}
-
 ColorConversionSkFilterCache::ColorConversionSkFilterCache() = default;
 ColorConversionSkFilterCache::~ColorConversionSkFilterCache() = default;
 
@@ -80,14 +70,14 @@
     float dst_max_luminance_relative) {
   // Set unused parameters to bogus values, so that they do not result in
   // different keys for the same conversion.
-  if (!IsHLGOrPQ(src)) {
+  if (!src.IsPQOrHLG()) {
     // If the source is not HLG or PQ, then `dst_max_luminance_relative` will
     // not be used, so set it to a nonsense value.
     dst_max_luminance_relative = 0;
 
     // If neither source nor destination are HLG or PQ, then
     // `sdr_max_luminance_nits` will not be used, so set it to a nonsense value.
-    if (!IsHLGOrPQ(dst)) {
+    if (!dst.IsPQOrHLG()) {
       sdr_max_luminance_nits = 0;
     }
   }
@@ -155,7 +145,7 @@
   static bool image_tone_mapping_enabled =
       base::FeatureList::IsEnabled(kImageToneMapping);
 
-  SkColorSpace* image_sk_color_space = image->colorSpace();
+  sk_sp<SkColorSpace> image_sk_color_space = image->refColorSpace();
   if (!image_sk_color_space || !image_tone_mapping_enabled)
     return image->makeColorSpace(target_color_space, context);
 
@@ -171,7 +161,7 @@
   SkImageInfo image_info =
       SkImageInfo::Make(image->dimensions(),
                         SkColorInfo(kRGBA_F16_SkColorType, kPremul_SkAlphaType,
-                                    target_color_space));
+                                    image_sk_color_space));
   sk_sp<SkSurface> surface;
   if (context) {
     // TODO(https://crbug.com/1286088): Consider adding mipmap support here.
@@ -193,10 +183,10 @@
   paint.setBlendMode(SkBlendMode::kSrc);
   paint.setColorFilter(filter);
   SkSamplingOptions sampling_options(SkFilterMode::kNearest);
-  surface->getCanvas()->drawImage(
-      image->reinterpretColorSpace(target_color_space),
-      /*x=*/0, /*y=*/0, sampling_options, &paint);
-  return surface->makeImageSnapshot();
+  surface->getCanvas()->drawImage(image,
+                                  /*x=*/0, /*y=*/0, sampling_options, &paint);
+  return surface->makeImageSnapshot()->reinterpretColorSpace(
+      target_color_space);
 }
 
 }  // namespace gfx
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc
index 7e72b71..9bb81c1 100644
--- a/ui/gfx/color_space.cc
+++ b/ui/gfx/color_space.cc
@@ -358,6 +358,10 @@
          transfer_ == TransferID::PIECEWISE_HDR;
 }
 
+bool ColorSpace::IsPQOrHLG() const {
+  return transfer_ == TransferID::PQ || transfer_ == TransferID::HLG;
+}
+
 bool ColorSpace::FullRangeEncodedValues() const {
   return transfer_ == TransferID::LINEAR_HDR ||
          transfer_ == TransferID::SRGB_HDR ||
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h
index 158caae7..307d4d21 100644
--- a/ui/gfx/color_space.h
+++ b/ui/gfx/color_space.h
@@ -276,6 +276,9 @@
   // Returns true if the transfer function is an HDR one (SMPTE 2084, HLG, etc).
   bool IsHDR() const;
 
+  // Returns true if the transfer function is PQ or HLG.
+  bool IsPQOrHLG() const;
+
   // Returns true if the encoded values can be outside of the 0.0-1.0 range.
   bool FullRangeEncodedValues() const;
 
diff --git a/ui/gfx/x/BUILD.gn b/ui/gfx/x/BUILD.gn
index 417ae05..6cdcb6e 100644
--- a/ui/gfx/x/BUILD.gn
+++ b/ui/gfx/x/BUILD.gn
@@ -211,6 +211,7 @@
   deps = [
     "//base",
     "//skia",
+    "//ui/gfx/geometry",
   ]
   public_deps = [ ":xproto" ]
 }
@@ -225,6 +226,7 @@
   deps = [
     "//base",
     "//testing/gtest",
+    "//ui/gfx/geometry",
     "//ui/gfx/x",
   ]
 }
diff --git a/ui/gfx/x/window_cache.cc b/ui/gfx/x/window_cache.cc
index d4f48d7..80b163ab 100644
--- a/ui/gfx/x/window_cache.cc
+++ b/ui/gfx/x/window_cache.cc
@@ -9,9 +9,11 @@
 #include "base/containers/cxx20_erase_vector.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/x/connection.h"
 #include "ui/gfx/x/event.h"
 #include "ui/gfx/x/future.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_window_event_manager.h"
 #include "ui/gfx/x/xproto.h"
 
@@ -37,7 +39,9 @@
 WindowCache* WindowCache::instance_ = nullptr;
 
 WindowCache::WindowCache(Connection* connection, Window root)
-    : connection_(connection), root_(root) {
+    : connection_(connection),
+      root_(root),
+      gtk_frame_extents_(GetAtom("_GTK_FRAME_EXTENTS")) {
   DCHECK(!instance_) << "Only one WindowCache should be active at a time";
   instance_ = this;
 
@@ -97,6 +101,17 @@
         }
       }
     }
+  } else if (auto* property = event.As<PropertyNotifyEvent>()) {
+    if (auto* info = GetInfo(property->window)) {
+      if (property->atom == Atom::WM_NAME) {
+        info->has_wm_name = property->state != Property::Delete;
+      } else if (property->atom == gtk_frame_extents_) {
+        if (property->state == Property::Delete)
+          info->gtk_frame_extents_px = gfx::Insets();
+        else
+          GetProperty(property->window, gtk_frame_extents_, 4);
+      }
+    }
   } else if (auto* create = event.As<CreateNotifyEvent>()) {
     if (auto* info = GetInfo(create->parent)) {
       info->children.push_back(create->window);
@@ -158,7 +173,7 @@
   // Events must be selected before getting the initial window info to prevent
   // race conditions.
   info.events = std::make_unique<XScopedEventSelector>(
-      window, EventMask::SubstructureNotify);
+      window, EventMask::SubstructureNotify | EventMask::PropertyChange);
 
   connection_->GetWindowAttributes(window).OnResponse(
       base::BindOnce(&WindowCache::OnGetWindowAttributesResponse,
@@ -169,6 +184,9 @@
       &WindowCache::OnQueryTreeResponse, weak_factory_.GetWeakPtr(), window));
   pending_requests_ += 3;
 
+  GetProperty(window, Atom::WM_NAME, 1);
+  GetProperty(window, gtk_frame_extents_, 4);
+
   auto& shape = connection_->shape();
   if (shape.present()) {
     info.shape_events =
@@ -196,6 +214,15 @@
   return nullptr;
 }
 
+void WindowCache::GetProperty(Window window, Atom property, uint32_t length) {
+  connection_
+      ->GetProperty(
+          {.window = window, .property = property, .long_length = length})
+      .OnResponse(base::BindOnce(&WindowCache::OnGetPropertyResponse,
+                                 weak_factory_.GetWeakPtr(), window, property));
+  pending_requests_++;
+}
+
 WindowCache::WindowInfo* WindowCache::OnResponse(Window window,
                                                  bool has_reply) {
   pending_requests_--;
@@ -236,6 +263,26 @@
   }
 }
 
+void WindowCache::OnGetPropertyResponse(Window window,
+                                        Atom atom,
+                                        GetPropertyResponse response) {
+  if (auto* info = OnResponse(window, response.reply.get())) {
+    if (atom == Atom::WM_NAME) {
+      info->has_wm_name = response->format;
+    } else if (atom == gtk_frame_extents_) {
+      if (response->format == CHAR_BIT * sizeof(int32_t) &&
+          response->value_len == 4) {
+        const int32_t* frame_extents = response->value->front_as<int32_t>();
+        info->gtk_frame_extents_px = gfx::Insets(
+            frame_extents[2] /* top */, frame_extents[0] /* left */,
+            frame_extents[3] /* bottom */, frame_extents[1] /* right */);
+      } else {
+        info->gtk_frame_extents_px = gfx::Insets();
+      }
+    }
+  }
+}
+
 void WindowCache::OnGetRectanglesResponse(
     Window window,
     Shape::Sk kind,
diff --git a/ui/gfx/x/window_cache.h b/ui/gfx/x/window_cache.h
index d7284b2..bd35787 100644
--- a/ui/gfx/x/window_cache.h
+++ b/ui/gfx/x/window_cache.h
@@ -11,6 +11,7 @@
 
 #include "base/component_export.h"
 #include "base/memory/weak_ptr.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/x/connection.h"
 #include "ui/gfx/x/shape.h"
 #include "ui/gfx/x/xproto.h"
@@ -40,6 +41,10 @@
     Window parent = Window::None;
     bool mapped = false;
 
+    // Properties
+    bool has_wm_name = false;
+    gfx::Insets gtk_frame_extents_px;
+
     int16_t x_px = 0;
     int16_t y_px = 0;
     uint16_t width_px = 0;
@@ -85,6 +90,9 @@
   // Returns a vector of child windows or nullptr if `window` is not cached.
   std::vector<Window>* GetChildren(Window window);
 
+  // Makes a GetProperty request with a callback to OnGetPropertyResponse().
+  void GetProperty(Window window, Atom property, uint32_t length);
+
   // Common response handler that's called at the beginning of each On*Response.
   // Returns the WindowInfo for `window` or nullptr if `window` is not cached
   // or `has_reply` is false.
@@ -97,6 +105,10 @@
 
   void OnQueryTreeResponse(Window window, QueryTreeResponse response);
 
+  void OnGetPropertyResponse(Window window,
+                             Atom atom,
+                             GetPropertyResponse response);
+
   void OnGetRectanglesResponse(Window window,
                                Shape::Sk kind,
                                Shape::GetRectanglesResponse response);
@@ -105,6 +117,7 @@
 
   Connection* const connection_;
   const Window root_;
+  const Atom gtk_frame_extents_;
   std::unique_ptr<XScopedEventSelector> root_events_;
 
   std::unordered_map<Window, WindowInfo> windows_;
diff --git a/ui/gfx/x/window_cache_unittest.cc b/ui/gfx/x/window_cache_unittest.cc
index c0c0262..fc5dd11 100644
--- a/ui/gfx/x/window_cache_unittest.cc
+++ b/ui/gfx/x/window_cache_unittest.cc
@@ -5,8 +5,11 @@
 #include "ui/gfx/x/window_cache.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/x/connection.h"
 #include "ui/gfx/x/future.h"
+#include "ui/gfx/x/x11_atom_cache.h"
+#include "ui/gfx/x/xproto_util.h"
 
 namespace x11 {
 
@@ -260,4 +263,43 @@
   EXPECT_EQ(info.input_rects_px, input_rects);
 }
 
+TEST_F(WindowCacheTest, WmName) {
+  const WindowCache::WindowInfo& info = cache()->windows().at(root());
+  EXPECT_FALSE(info.has_wm_name);
+
+  SetStringProperty(root(), Atom::WM_NAME, Atom::STRING, "Foo");
+  cache()->SyncForTest();
+  EXPECT_TRUE(info.has_wm_name);
+
+  connection()->DeleteProperty(root(), Atom::WM_NAME);
+  cache()->SyncForTest();
+  EXPECT_FALSE(info.has_wm_name);
+}
+
+TEST_F(WindowCacheTest, GtkFrameExtents) {
+  const WindowCache::WindowInfo& info = cache()->windows().at(root());
+  EXPECT_EQ(info.gtk_frame_extents_px, gfx::Insets());
+
+  const Atom gtk_frame_extents = GetAtom("_GTK_FRAME_EXTENTS");
+  SetArrayProperty(root(), gtk_frame_extents, Atom::CARDINAL,
+                   std::vector<uint32_t>{1, 2, 3, 4});
+  cache()->SyncForTest();
+  EXPECT_EQ(info.gtk_frame_extents_px, gfx::Insets(3, 1, 4, 2));
+
+  connection()->DeleteProperty(root(), gtk_frame_extents);
+  cache()->SyncForTest();
+  EXPECT_EQ(info.gtk_frame_extents_px, gfx::Insets());
+
+  // Make sure malformed values don't get cached.
+  SetArrayProperty(root(), gtk_frame_extents, Atom::CARDINAL,
+                   std::vector<uint32_t>{1, 2});
+  cache()->SyncForTest();
+  EXPECT_EQ(info.gtk_frame_extents_px, gfx::Insets());
+
+  SetArrayProperty(root(), gtk_frame_extents, Atom::CARDINAL,
+                   std::vector<uint8_t>{1, 2, 3, 4});
+  cache()->SyncForTest();
+  EXPECT_EQ(info.gtk_frame_extents_px, gfx::Insets());
+}
+
 }  // namespace x11
\ No newline at end of file
diff --git a/ui/native_theme/native_theme.cc b/ui/native_theme/native_theme.cc
index 5376b01..f3b25e58 100644
--- a/ui/native_theme/native_theme.cc
+++ b/ui/native_theme/native_theme.cc
@@ -40,8 +40,15 @@
 ColorProviderManager::Key NativeTheme::GetColorProviderKey(
     scoped_refptr<ColorProviderManager::InitializerSupplier> custom_theme)
     const {
-  return GetColorProviderKeyForColorScheme(std::move(custom_theme),
-                                           GetDefaultSystemColorScheme());
+  return ColorProviderManager::Key(
+      (GetDefaultSystemColorScheme() == ColorScheme::kDark)
+          ? ColorProviderManager::ColorMode::kDark
+          : ColorProviderManager::ColorMode::kLight,
+      UserHasContrastPreference() ? ColorProviderManager::ContrastMode::kHigh
+                                  : ColorProviderManager::ContrastMode::kNormal,
+      is_custom_system_theme_ ? ColorProviderManager::SystemTheme::kCustom
+                              : ColorProviderManager::SystemTheme::kDefault,
+      std::move(custom_theme));
 }
 
 SkColor NativeTheme::GetSystemButtonPressedColor(SkColor base_color) const {
@@ -268,19 +275,4 @@
   return ShouldUseDarkColors() ? ColorScheme::kDark : ColorScheme::kLight;
 }
 
-ColorProviderManager::Key NativeTheme::GetColorProviderKeyForColorScheme(
-    scoped_refptr<ColorProviderManager::InitializerSupplier> custom_theme,
-    ColorScheme color_scheme) const {
-  return ColorProviderManager::Key(
-      (color_scheme == ColorScheme::kDark)
-          ? ColorProviderManager::ColorMode::kDark
-          : ColorProviderManager::ColorMode::kLight,
-      (color_scheme == ColorScheme::kPlatformHighContrast)
-          ? ColorProviderManager::ContrastMode::kHigh
-          : ColorProviderManager::ContrastMode::kNormal,
-      is_custom_system_theme_ ? ColorProviderManager::SystemTheme::kCustom
-                              : ColorProviderManager::SystemTheme::kDefault,
-      std::move(custom_theme));
-}
-
 }  // namespace ui
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index e46bc2c..beadf20 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -546,10 +546,6 @@
   mutable std::map<SystemThemeColor, SkColor> system_colors_;
 
  private:
-  ColorProviderManager::Key GetColorProviderKeyForColorScheme(
-      scoped_refptr<ColorProviderManager::InitializerSupplier> custom_theme,
-      ColorScheme color_scheme) const;
-
   // Observers to notify when the native theme changes.
   base::ObserverList<NativeThemeObserver>::Unchecked native_theme_observers_;
 
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn
index d85d01f..23a78ac 100644
--- a/ui/ozone/BUILD.gn
+++ b/ui/ozone/BUILD.gn
@@ -89,6 +89,7 @@
     "public/gl_ozone.h",
     "public/gpu_platform_support_host.cc",
     "public/gpu_platform_support_host.h",
+    "public/hardware_capabilities.h",
     "public/input_controller.cc",
     "public/input_controller.h",
     "public/overlay_candidates_ozone.cc",
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
index 0a8a953..c6eeb8a 100644
--- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
+++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
@@ -107,9 +107,9 @@
 
 DrmGpuDisplayManager::~DrmGpuDisplayManager() = default;
 
-void DrmGpuDisplayManager::SetClearOverlayCacheCallback(
+void DrmGpuDisplayManager::SetDisplaysConfiguredCallback(
     base::RepeatingClosure callback) {
-  clear_overlay_cache_callback_ = std::move(callback);
+  displays_configured_callback_ = std::move(callback);
 }
 
 MovableDisplaySnapshots DrmGpuDisplayManager::GetDisplays() {
@@ -236,12 +236,13 @@
     controllers_to_configure.push_back(std::move(params));
   }
 
-  if (clear_overlay_cache_callback_)
-    clear_overlay_cache_callback_.Run();
-
   bool config_success =
       screen_manager_->ConfigureDisplayControllers(controllers_to_configure);
 
+  if (displays_configured_callback_) {
+    displays_configured_callback_.Run();
+  }
+
   for (const auto& controller : controllers_to_configure) {
     if (config_success) {
       FindDisplay(controller.display_id)->SetOrigin(controller.origin);
diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
index 0382fab..009f0fb 100644
--- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
+++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
@@ -43,8 +43,8 @@
   ~DrmGpuDisplayManager();
 
   // Sets a callback that will be notified when display configuration may have
-  // changed to clear the overlay configuration cache.
-  void SetClearOverlayCacheCallback(base::RepeatingClosure callback);
+  // changed, so we should update state for managing overlays.
+  void SetDisplaysConfiguredCallback(base::RepeatingClosure callback);
 
   // Returns a list of the connected displays. When this is called the list of
   // displays is refreshed.
@@ -87,7 +87,7 @@
 
   std::vector<std::unique_ptr<DrmDisplay>> displays_;
 
-  base::RepeatingClosure clear_overlay_cache_callback_;
+  base::RepeatingClosure displays_configured_callback_;
 };
 
 }  // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc b/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc
index 1ca2737..886e66cc 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc
@@ -16,6 +16,7 @@
 
 DrmOverlayCandidates::~DrmOverlayCandidates() {
   overlay_manager_->RegisterOverlayRequirement(widget_, false);
+  overlay_manager_->StopObservingHardwareCapabilities(widget_);
 }
 
 void DrmOverlayCandidates::CheckOverlaySupport(
@@ -23,6 +24,12 @@
   overlay_manager_->CheckOverlaySupport(candidates, widget_);
 }
 
+void DrmOverlayCandidates::ObserveHardwareCapabilities(
+    HardwareCapabilitiesCallback receive_callback) {
+  overlay_manager_->StartObservingHardwareCapabilities(
+      widget_, std::move(receive_callback));
+}
+
 void DrmOverlayCandidates::RegisterOverlayRequirement(bool requires_overlay) {
 #if !BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
   DCHECK(!requires_overlay);
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h b/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h
index cbbd6d7b..c1f9cc4 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_candidates_ozone.h"
 
 namespace ui {
@@ -29,6 +30,8 @@
   // OverlayCandidatesOzone:
   void CheckOverlaySupport(
       std::vector<OverlaySurfaceCandidate>* candidates) override;
+  void ObserveHardwareCapabilities(
+      HardwareCapabilitiesCallback receive_callback) override;
   void RegisterOverlayRequirement(bool requires_overlay) override;
 
  private:
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc b/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
index 79227e5..6f51baf3 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
@@ -54,10 +54,26 @@
   return std::make_unique<DrmOverlayCandidates>(this, widget);
 }
 
-void DrmOverlayManager::ResetCache() {
-  TRACE_EVENT0("hwoverlays", "DrmOverlayManager::ResetCache");
+void DrmOverlayManager::DisplaysConfigured() {
+  TRACE_EVENT0("hwoverlays", "DrmOverlayManager::DisplaysConfigured");
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   widget_cache_map_.clear();
+
+  for (auto& entry : hardware_capabilities_callbacks_) {
+    GetHardwareCapabilities(entry.first, entry.second);
+  }
+}
+
+void DrmOverlayManager::StartObservingHardwareCapabilities(
+    gfx::AcceleratedWidget widget,
+    HardwareCapabilitiesCallback receive_callback) {
+  GetHardwareCapabilities(widget, receive_callback);
+  hardware_capabilities_callbacks_.emplace(widget, std::move(receive_callback));
+}
+
+void DrmOverlayManager::StopObservingHardwareCapabilities(
+    gfx::AcceleratedWidget widget) {
+  hardware_capabilities_callbacks_.erase(widget);
 }
 
 void DrmOverlayManager::CheckOverlaySupport(
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager.h b/ui/ozone/platform/drm/gpu/drm_overlay_manager.h
index c9927dd4..28fa530 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_manager.h
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager.h
@@ -12,6 +12,7 @@
 #include "base/containers/lru_cache.h"
 #include "base/threading/thread_checker.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_candidates_ozone.h"
 #include "ui/ozone/public/overlay_manager_ozone.h"
 
@@ -35,15 +36,26 @@
   std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
       gfx::AcceleratedWidget w) override;
 
+  // Called when notified by the DRM thread of a display configuration change.
   // Resets the cache of OverlaySurfaceCandidates and if they can be displayed
-  // as an overlay. For use when display configuration changes.
-  void ResetCache();
+  // as an overlay. Requests an updated HardwareCapabilities for any observing
+  // OverlayProcessors.
+  void DisplaysConfigured();
 
   // Checks if overlay candidates can be displayed as overlays. Modifies
   // |candidates| to indicate if they can.
   void CheckOverlaySupport(std::vector<OverlaySurfaceCandidate>* candidates,
                            gfx::AcceleratedWidget widget);
 
+  void StartObservingHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      HardwareCapabilitiesCallback receive_callback);
+  void StopObservingHardwareCapabilities(gfx::AcceleratedWidget widget);
+
+  virtual void GetHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      HardwareCapabilitiesCallback& receive_callback) = 0;
+
   // Should be called by the overlay processor to indicate if a widget has a
   // candidate that requires an overlay. This is to prioritize which display
   // gets the overlay in a multiple display environment.
@@ -98,6 +110,9 @@
 
   base::flat_set<gfx::AcceleratedWidget> widgets_with_required_overlays_;
 
+  std::map<gfx::AcceleratedWidget, HardwareCapabilitiesCallback>
+      hardware_capabilities_callbacks_;
+
   THREAD_CHECKER(thread_checker_);
 };
 
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
index 13dc7cb..803c45f2 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
@@ -28,7 +28,7 @@
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
       "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest",
       TRACE_ID_LOCAL(this));
-  SetClearCacheCallbackIfNecessary();
+  SetDisplaysConfiguredCallbackIfNecessary();
   drm_thread_proxy_->CheckOverlayCapabilities(
       widget, candidates,
       base::BindOnce(&DrmOverlayManagerGpu::ReceiveOverlayValidationResponse,
@@ -41,21 +41,30 @@
     gfx::AcceleratedWidget widget) {
   TRACE_EVENT0("hwoverlays",
                "DrmOverlayManagerGpu::SendOverlayValidationRequestSync");
-  SetClearCacheCallbackIfNecessary();
+  SetDisplaysConfiguredCallbackIfNecessary();
   return drm_thread_proxy_->CheckOverlayCapabilitiesSync(widget, candidates);
 }
 
-void DrmOverlayManagerGpu::SetClearCacheCallbackIfNecessary() {
+void DrmOverlayManagerGpu::GetHardwareCapabilities(
+    gfx::AcceleratedWidget widget,
+    HardwareCapabilitiesCallback& receive_callback) {
+  TRACE_EVENT0("hwoverlays",
+               "DrmOverlayManagerGpu::SendMaxOverlaysRequestSync");
+  SetDisplaysConfiguredCallbackIfNecessary();
+  drm_thread_proxy_->GetHardwareCapabilities(widget, receive_callback);
+}
+
+void DrmOverlayManagerGpu::SetDisplaysConfiguredCallbackIfNecessary() {
   // Adds a callback for the DRM thread to let us know when display
-  // configuration has changed and to reset cache of valid overlay
-  // configurations. This happens in SendOverlayValidationRequest() because the
-  // DrmThread has been started by this point *and* we are on the thread the
-  // callback should run on. Those two conditions are not necessarily true in
-  // the constructor.
-  if (!has_set_clear_cache_callback_) {
-    has_set_clear_cache_callback_ = true;
-    drm_thread_proxy_->SetClearOverlayCacheCallback(base::BindRepeating(
-        &DrmOverlayManagerGpu::ResetCache, weak_ptr_factory_.GetWeakPtr()));
+  // configuration may have changed.
+  // This happens in SendOverlayValidationRequest() because the DrmThread has
+  // been started by this point *and* we are on the thread the callback should
+  // run on. Those two conditions are not necessarily true in the constructor.
+  if (!has_set_displays_configured_callback_) {
+    has_set_displays_configured_callback_ = true;
+    drm_thread_proxy_->SetDisplaysConfiguredCallback(
+        base::BindRepeating(&DrmOverlayManagerGpu::DisplaysConfigured,
+                            weak_ptr_factory_.GetWeakPtr()));
   }
 }
 
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
index 93f77bb4..1942d754 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
@@ -35,7 +35,11 @@
       const std::vector<OverlaySurfaceCandidate>& candidates,
       gfx::AcceleratedWidget widget) override;
 
-  void SetClearCacheCallbackIfNecessary();
+  void GetHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      HardwareCapabilitiesCallback& receive_callback) override;
+
+  void SetDisplaysConfiguredCallbackIfNecessary();
 
   void ReceiveOverlayValidationResponse(
       gfx::AcceleratedWidget widget,
@@ -44,7 +48,7 @@
 
   DrmThreadProxy* const drm_thread_proxy_;
 
-  bool has_set_clear_cache_callback_ = false;
+  bool has_set_displays_configured_callback_ = false;
 
   base::WeakPtrFactory<DrmOverlayManagerGpu> weak_ptr_factory_{this};
 };
diff --git a/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc b/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc
index 24e93a0..47784e5 100644
--- a/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc
@@ -38,6 +38,16 @@
       gfx::AcceleratedWidget widget) override {
     return {};
   }
+  void GetHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      ui::HardwareCapabilitiesCallback& receive_callback) override {
+    ui::HardwareCapabilities hardware_capabilities;
+    hardware_capabilities.num_overlay_capable_planes = num_planes_response_;
+    // Immediately respond to the callback.
+    receive_callback.Run(hardware_capabilities);
+  }
+
+  int num_planes_response_ = 0;
 
  private:
   std::vector<std::vector<OverlaySurfaceCandidate>> requests_;
@@ -308,4 +318,50 @@
   EXPECT_EQ(manager.requests().size(), 1u);
 }
 
+TEST(DrmOverlayManagerTest, ObservingHardwareCapabilities) {
+  TestDrmOverlayManager manager;
+  manager.num_planes_response_ = 2;
+
+  int primary_calls = 0;
+  HardwareCapabilitiesCallback primary_callback = base::BindRepeating(
+      [](int* calls, HardwareCapabilities hc) {
+        (*calls)++;
+        EXPECT_EQ(hc.num_overlay_capable_planes, 2);
+      },
+      &primary_calls);
+  manager.StartObservingHardwareCapabilities(kPrimaryWidget, primary_callback);
+  EXPECT_EQ(primary_calls, 1);
+
+  manager.DisplaysConfigured();
+
+  EXPECT_EQ(primary_calls, 2);
+
+  int secondary_calls = 0;
+  HardwareCapabilitiesCallback secondary_callback = base::BindRepeating(
+      [](int* calls, HardwareCapabilities hc) {
+        (*calls)++;
+        EXPECT_EQ(hc.num_overlay_capable_planes, 2);
+      },
+      &secondary_calls);
+  manager.StartObservingHardwareCapabilities(kSecondaryWidget,
+                                             secondary_callback);
+  // Only the secondary callback should be called.
+  EXPECT_EQ(primary_calls, 2);
+  EXPECT_EQ(secondary_calls, 1);
+
+  manager.DisplaysConfigured();
+
+  // Both callbacks are called.
+  EXPECT_EQ(primary_calls, 3);
+  EXPECT_EQ(secondary_calls, 2);
+
+  manager.StopObservingHardwareCapabilities(kPrimaryWidget);
+  manager.DisplaysConfigured();
+  manager.DisplaysConfigured();
+
+  // The primary callback won't be called anymore.
+  EXPECT_EQ(primary_calls, 3);
+  EXPECT_EQ(secondary_calls, 4);
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc
index 805e82b8..02066666 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -26,6 +26,7 @@
 #include "ui/gfx/presentation_feedback.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
+#include "ui/ozone/platform/drm/gpu/drm_device.h"
 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
 #include "ui/ozone/platform/drm/gpu/drm_dumb_buffer.h"
@@ -214,8 +215,8 @@
   *out_framebuffer = std::move(framebuffer);
 }
 
-void DrmThread::SetClearOverlayCacheCallback(base::RepeatingClosure callback) {
-  display_manager_->SetClearOverlayCacheCallback(std::move(callback));
+void DrmThread::SetDisplaysConfiguredCallback(base::RepeatingClosure callback) {
+  display_manager_->SetDisplaysConfiguredCallback(std::move(callback));
 }
 
 void DrmThread::SchedulePageFlip(
@@ -337,6 +338,41 @@
       kMinTime, kMaxTime, kTimeBuckets);
 }
 
+void DrmThread::GetHardwareCapabilities(
+    gfx::AcceleratedWidget widget,
+    ui::HardwareCapabilitiesCallback receive_callback) {
+  TRACE_EVENT0("drm,hwoverlays", "DrmThread::GetHardwareCapabilities");
+  DCHECK(screen_manager_->GetWindow(widget));
+  DCHECK(device_manager_->GetDrmDevice(widget));
+  HardwareDisplayController* hdc =
+      screen_manager_->GetWindow(widget)->GetController();
+  HardwareDisplayPlaneManager* plane_manager =
+      device_manager_->GetDrmDevice(widget)->plane_manager();
+
+  if (!hdc || !plane_manager) {
+    // Assume only the primary plane exists.
+    ui::HardwareCapabilities hardware_capabilities;
+    hardware_capabilities.num_overlay_capable_planes = 1;
+    std::move(receive_callback).Run(hardware_capabilities);
+    return;
+  }
+
+  const auto& crtc_controllers = hdc->crtc_controllers();
+  // We almost always expect only one CRTC. Multiple CRTCs for one widget was
+  // the old way mirror mode was supported.
+  if (crtc_controllers.size() == 1) {
+    std::move(receive_callback)
+        .Run(plane_manager->GetHardwareCapabilities(
+            crtc_controllers[0]->crtc()));
+  } else {
+    // If there are multiple CRTCs for this widget, we shouldn't rely on
+    // overlays working, so we'll say only the primary plane exists.
+    ui::HardwareCapabilities hardware_capabilities;
+    hardware_capabilities.num_overlay_capable_planes = 1;
+    std::move(receive_callback).Run(hardware_capabilities);
+  }
+}
+
 void DrmThread::GetDeviceCursor(
     mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver) {
   cursor_receivers_.Add(this, std::move(receiver));
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.h b/ui/ozone/platform/drm/gpu/drm_thread.h
index fa20e5b..0a1249e 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread.h
+++ b/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -25,6 +25,7 @@
 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
 #include "ui/ozone/platform/drm/mojom/device_cursor.mojom.h"
 #include "ui/ozone/platform/drm/mojom/drm_device.mojom.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_surface_candidate.h"
 #include "ui/ozone/public/swap_completion_callback.h"
 
@@ -107,7 +108,7 @@
                               gfx::NativePixmapHandle handle,
                               std::unique_ptr<GbmBuffer>* buffer,
                               scoped_refptr<DrmFramebuffer>* framebuffer);
-  void SetClearOverlayCacheCallback(base::RepeatingClosure callback);
+  void SetDisplaysConfiguredCallback(base::RepeatingClosure callback);
   void AddDrmDeviceReceiver(
       mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
 
@@ -128,6 +129,11 @@
       gfx::AcceleratedWidget widget,
       const std::vector<OverlaySurfaceCandidate>& candidates,
       std::vector<OverlayStatus>* result);
+  // Calls `receive_callback` with a `HardwareCapabilities` containing
+  // information about overlay support on the current hardware.
+  void GetHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      ui::HardwareCapabilitiesCallback receive_callback);
 
   // DrmWindowProxy (on GPU thread) is the client for these methods.
   void SchedulePageFlip(gfx::AcceleratedWidget widget,
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
index a785ee1..078ee8a 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
+++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -130,13 +130,13 @@
                               base::Unretained(&drm_thread_), std::move(task)));
 }
 
-void DrmThreadProxy::SetClearOverlayCacheCallback(
+void DrmThreadProxy::SetDisplaysConfiguredCallback(
     base::RepeatingClosure callback) {
   DCHECK(drm_thread_.task_runner());
 
   drm_thread_.task_runner()->PostTask(
       FROM_HERE,
-      base::BindOnce(&DrmThread::SetClearOverlayCacheCallback,
+      base::BindOnce(&DrmThread::SetDisplaysConfiguredCallback,
                      base::Unretained(&drm_thread_),
                      CreateSafeRepeatingCallback(std::move(callback))));
 }
@@ -172,6 +172,20 @@
   return result;
 }
 
+void DrmThreadProxy::GetHardwareCapabilities(
+    gfx::AcceleratedWidget widget,
+    const HardwareCapabilitiesCallback& receive_callback) {
+  TRACE_EVENT0("drm", "DrmThreadProxy::GetHardwareCapabilities");
+  DCHECK(drm_thread_.task_runner());
+  base::RepeatingClosure task = base::BindRepeating(
+      &DrmThread::GetHardwareCapabilities, base::Unretained(&drm_thread_),
+      widget, CreateSafeRepeatingCallback(receive_callback));
+  drm_thread_.task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&DrmThread::RunTaskAfterDeviceReady,
+                     base::Unretained(&drm_thread_), std::move(task), nullptr));
+}
+
 void DrmThreadProxy::AddDrmDeviceReceiver(
     mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver) {
   DCHECK(drm_thread_.task_runner()) << "DrmThreadProxy::AddDrmDeviceReceiver "
diff --git a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
index 16204ce..f50c939 100644
--- a/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
+++ b/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
@@ -13,6 +13,7 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "ui/ozone/platform/drm/gpu/drm_thread.h"
 #include "ui/ozone/platform/drm/mojom/device_cursor.mojom.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_surface_candidate.h"
 
 namespace ui {
@@ -66,9 +67,9 @@
                               scoped_refptr<DrmFramebuffer>* framebuffer);
 
   // Sets a callback that will be notified when display configuration may have
-  // changed to clear the overlay configuration cache. |callback| will be run on
-  // origin thread.
-  void SetClearOverlayCacheCallback(base::RepeatingClosure reset_callback);
+  // changed, so we should update state for managing overlays.
+  // |callback| will be run on origin thread.
+  void SetDisplaysConfiguredCallback(base::RepeatingClosure callback);
 
   // Checks if overlay |candidates| can be displayed asynchronously and then
   // runs |callback|. Testing the overlay configuration requires posting a task
@@ -83,6 +84,10 @@
       gfx::AcceleratedWidget widget,
       const std::vector<OverlaySurfaceCandidate>& candidates);
 
+  void GetHardwareCapabilities(
+      gfx::AcceleratedWidget widget,
+      const HardwareCapabilitiesCallback& receive_callback);
+
   void AddDrmDeviceReceiver(
       mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
 
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 70bd00b..689f636 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -520,4 +520,16 @@
   crtc_state.modeset_framebuffers.clear();
 }
 
+ui::HardwareCapabilities HardwareDisplayPlaneManager::GetHardwareCapabilities(
+    uint32_t crtc_id) {
+  ui::HardwareCapabilities hc;
+  hc.num_overlay_capable_planes = std::count_if(
+      planes_.begin(), planes_.end(),
+      [crtc_id](const std::unique_ptr<HardwareDisplayPlane>& plane) {
+        return plane->type() != DRM_PLANE_TYPE_CURSOR &&
+               plane->CanUseForCrtcId(crtc_id);
+      });
+  return hc;
+}
+
 }  // namespace ui
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 b576165..ba1ee168 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -9,6 +9,7 @@
 #include <stdint.h>
 #include <xf86drmMode.h>
 #include <cstdint>
+#include <map>
 #include <memory>
 #include <vector>
 
@@ -19,6 +20,7 @@
 #include "ui/ozone/platform/drm/gpu/crtc_commit_request.h"
 #include "ui/ozone/platform/drm/gpu/drm_device.h"
 #include "ui/ozone/platform/drm/gpu/drm_overlay_plane.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/swap_completion_callback.h"
 
 namespace gfx {
@@ -204,6 +206,11 @@
   // caller.
   void ResetModesetStateForCrtc(uint32_t crtc_id);
 
+  // Gets `HardwareCapabilities` based on planes available to the specified
+  // CRTC. num_overlay_capable_planes counts both `DRM_PLANE_TYPE_PRIMARY` and
+  // `DRM_PLANE_TYPE_OVERLAY` planes.
+  ui::HardwareCapabilities GetHardwareCapabilities(uint32_t crtc_id);
+
  protected:
   struct ConnectorProperties {
     uint32_t id;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index 8af1afe..2b12979 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -1180,6 +1180,51 @@
   }
 }
 
+TEST_P(HardwareDisplayPlaneManagerTest, GetHardwareCapabilities) {
+  InitializeDrmState(/*crtc_count=*/4, /*planes_per_crtc=*/7);
+  fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+                             plane_properties_, property_names_, use_atomic_);
+
+  for (int i = 0; i < 4; ++i) {
+    // Legacy doesn't support OVERLAY planes.
+    int expected_planes = use_atomic_ ? 7 : 1;
+    EXPECT_EQ(fake_drm_->plane_manager()
+                  ->GetHardwareCapabilities(kCrtcIdBase + i)
+                  .num_overlay_capable_planes,
+              expected_planes);
+  }
+
+  {
+    // Change the last (CURSOR) plane into a PRIMARY plane that is available to
+    // only the first two CRTCs.
+    auto& last_props = plane_properties_[plane_properties_.size() - 1];
+    last_props.crtc_mask = (1 << 0) | (1 << 1);
+    // Find the type property and change it to PRIMARY.
+    for (auto& property : last_props.properties) {
+      if (property.id == kTypePropId) {
+        property.value = DRM_PLANE_TYPE_PRIMARY;
+        break;
+      }
+    }
+
+    fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+                               plane_properties_, property_names_, use_atomic_);
+  }
+
+  for (int i = 0; i < 4; ++i) {
+    // Legacy doesn't support OVERLAY planes.
+    int expected_planes = use_atomic_ ? 7 : 1;
+    // First two CRTCs have the newly added plane available.
+    if (i == 0 || i == 1) {
+      expected_planes++;
+    }
+    EXPECT_EQ(fake_drm_->plane_manager()
+                  ->GetHardwareCapabilities(kCrtcIdBase + i)
+                  .num_overlay_capable_planes,
+              expected_planes);
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          HardwareDisplayPlaneManagerTest,
                          testing::Values(false, true));
diff --git a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
index 06b1c49..de5cfbd 100644
--- a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
+++ b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
@@ -648,8 +648,7 @@
   vk_image_info->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                          VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-  if (usage_ == gfx::BufferUsage::SCANOUT ||
-      usage_ == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE) {
+  if (usage_ == gfx::BufferUsage::SCANOUT) {
     vk_image_info->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   }
 
diff --git a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc
index fb585e20..4b86c0ce 100644
--- a/ui/ozone/platform/scenic/sysmem_buffer_collection.cc
+++ b/ui/ozone/platform/scenic/sysmem_buffer_collection.cc
@@ -634,8 +634,7 @@
   vk_image_info->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                          VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-  if (usage_ == gfx::BufferUsage::SCANOUT ||
-      usage_ == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE) {
+  if (usage_ == gfx::BufferUsage::SCANOUT) {
     vk_image_info->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
   }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_screen.cc b/ui/ozone/platform/wayland/host/wayland_screen.cc
index 6201f46..3fde4d13 100644
--- a/ui/ozone/platform/wayland/host/wayland_screen.cc
+++ b/ui/ozone/platform/wayland/host/wayland_screen.cc
@@ -40,11 +40,11 @@
     case WL_OUTPUT_TRANSFORM_NORMAL:
       return display::Display::ROTATE_0;
     case WL_OUTPUT_TRANSFORM_90:
-      return display::Display::ROTATE_90;
+      return display::Display::ROTATE_270;
     case WL_OUTPUT_TRANSFORM_180:
       return display::Display::ROTATE_180;
     case WL_OUTPUT_TRANSFORM_270:
-      return display::Display::ROTATE_270;
+      return display::Display::ROTATE_90;
     // ui::display::Display does not support flipped rotation.
     // see ui::display::Display::Rotation comment.
     case WL_OUTPUT_TRANSFORM_FLIPPED:
diff --git a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
index b2f23a67..f159a5b 100644
--- a/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
@@ -764,6 +764,34 @@
   display::Display::ResetForceDeviceScaleFactorForTesting();
 }
 
+// Checks that transform is properly translated to Display orientation. The
+// first one is counter-clockwise, and the second is clockwise.
+TEST_P(WaylandScreenTest, Transform) {
+  constexpr std::array<
+      std::pair<wl_output_transform, display::Display::Rotation>, 8>
+      test_data = {{
+          {WL_OUTPUT_TRANSFORM_NORMAL, display::Display::ROTATE_0},
+          {WL_OUTPUT_TRANSFORM_90, display::Display::ROTATE_270},
+          {WL_OUTPUT_TRANSFORM_180, display::Display::ROTATE_180},
+          {WL_OUTPUT_TRANSFORM_270, display::Display::ROTATE_90},
+          // Flipped transforms are not supported.
+          {WL_OUTPUT_TRANSFORM_FLIPPED, display::Display::ROTATE_0},
+          {WL_OUTPUT_TRANSFORM_FLIPPED_90, display::Display::ROTATE_0},
+          {WL_OUTPUT_TRANSFORM_FLIPPED_180, display::Display::ROTATE_0},
+          {WL_OUTPUT_TRANSFORM_FLIPPED_270, display::Display::ROTATE_0},
+      }};
+
+  for (const auto& i : test_data) {
+    output_->SetTransform(i.first);
+    output_->Flush();
+
+    Sync();
+
+    auto main_display = platform_screen_->GetPrimaryDisplay();
+    EXPECT_EQ(main_display.rotation(), i.second);
+  }
+}
+
 namespace {
 
 class LazilyConfiguredScreenTest
diff --git a/ui/ozone/platform/wayland/test/test_output.cc b/ui/ozone/platform/wayland/test/test_output.cc
index 59db804b..3d8b0d2 100644
--- a/ui/ozone/platform/wayland/test/test_output.cc
+++ b/ui/ozone/platform/wayland/test/test_output.cc
@@ -27,6 +27,10 @@
   pending_scale_ = factor;
 }
 
+void TestOutput::SetTransform(wl_output_transform transform) {
+  pending_transform_ = transform;
+}
+
 void TestOutput::Flush() {
   constexpr char kUnknownMake[] = "unknown_make";
   constexpr char kUnknownModel[] = "unknown_model";
@@ -34,12 +38,16 @@
   if (!pending_rect_ && !pending_scale_)
     return;
 
-  if (pending_rect_) {
-    rect_ = std::move(pending_rect_.value());
+  if (pending_rect_ || pending_transform_) {
+    if (pending_rect_)
+      rect_ = std::move(pending_rect_.value());
+    if (pending_transform_)
+      transform_ = std::move(pending_transform_.value());
+
     wl_output_send_geometry(resource(), rect_.x(), rect_.y(),
                             0 /* physical_width */, 0 /* physical_height */,
                             0 /* subpixel */, kUnknownMake, kUnknownModel,
-                            0 /* transform */);
+                            transform_);
     wl_output_send_mode(resource(), WL_OUTPUT_MODE_CURRENT, rect_.width(),
                         rect_.height(), 0);
   }
diff --git a/ui/ozone/platform/wayland/test/test_output.h b/ui/ozone/platform/wayland/test/test_output.h
index 2819c905c..b8ed75c8 100644
--- a/ui/ozone/platform/wayland/test/test_output.h
+++ b/ui/ozone/platform/wayland/test/test_output.h
@@ -5,6 +5,7 @@
 #ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_OUTPUT_H_
 #define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_OUTPUT_H_
 
+#include <wayland-server-protocol.h>
 #include <cstdint>
 
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -27,6 +28,7 @@
   void SetRect(const gfx::Rect& rect);
   int32_t GetScale() const { return scale_; }
   void SetScale(int32_t factor);
+  void SetTransform(wl_output_transform transform);
 
   void Flush();
 
@@ -36,9 +38,11 @@
  private:
   gfx::Rect rect_;
   int32_t scale_;
+  wl_output_transform transform_{WL_OUTPUT_TRANSFORM_NORMAL};
 
   absl::optional<gfx::Rect> pending_rect_ = absl::nullopt;
   absl::optional<int32_t> pending_scale_ = absl::nullopt;
+  absl::optional<wl_output_transform> pending_transform_ = absl::nullopt;
 };
 
 }  // namespace wl
diff --git a/ui/ozone/public/hardware_capabilities.h b/ui/ozone/public/hardware_capabilities.h
new file mode 100644
index 0000000..16bebaf0
--- /dev/null
+++ b/ui/ozone/public/hardware_capabilities.h
@@ -0,0 +1,23 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PUBLIC_HARDWARE_CAPABILITIES_H_
+#define UI_OZONE_PUBLIC_HARDWARE_CAPABILITIES_H_
+
+#include "base/callback.h"
+
+namespace ui {
+
+struct HardwareCapabilities {
+  // Number of planes available to the current CRTC(s).
+  // This is specifically the count of non-CURSOR planes, because some boards
+  // may have extra PRIMARY planes that could be used for overlays.
+  int num_overlay_capable_planes = 0;
+};
+using HardwareCapabilitiesCallback =
+    base::RepeatingCallback<void(HardwareCapabilities)>;
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PUBLIC_HARDWARE_CAPABILITIES_H_
diff --git a/ui/ozone/public/overlay_candidates_ozone.cc b/ui/ozone/public/overlay_candidates_ozone.cc
index 2973027..36be2a3 100644
--- a/ui/ozone/public/overlay_candidates_ozone.cc
+++ b/ui/ozone/public/overlay_candidates_ozone.cc
@@ -13,6 +13,9 @@
   NOTREACHED();
 }
 
-OverlayCandidatesOzone::~OverlayCandidatesOzone() {}
+void OverlayCandidatesOzone::ObserveHardwareCapabilities(
+    ui::HardwareCapabilitiesCallback receive_callback) {}
+
+OverlayCandidatesOzone::~OverlayCandidatesOzone() = default;
 
 }  // namespace ui
diff --git a/ui/ozone/public/overlay_candidates_ozone.h b/ui/ozone/public/overlay_candidates_ozone.h
index 27e32a9a..f6d2db2 100644
--- a/ui/ozone/public/overlay_candidates_ozone.h
+++ b/ui/ozone/public/overlay_candidates_ozone.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include "base/component_export.h"
+#include "ui/ozone/public/hardware_capabilities.h"
 #include "ui/ozone/public/overlay_surface_candidate.h"
 
 namespace ui {
@@ -27,6 +28,14 @@
   // if necessary.
   virtual void CheckOverlaySupport(OverlaySurfaceCandidateList* surfaces);
 
+  // Register `receive_callback` to be called with the latest
+  // HardwareCapbalitites, whenever displays are configured.
+  // `receive_callback` may be called once after OverlayCandidatesOzone is
+  // destroyed if there is an in-flight callback, so it should be bound with a
+  // WeakPtr.
+  virtual void ObserveHardwareCapabilities(
+      ui::HardwareCapabilitiesCallback receive_callback);
+
   // This should be invoked during overlay processing to indicate if there are
   // any candidates for this processor that have an overlay requirement.
   virtual void RegisterOverlayRequirement(bool requires_overlay) {}
diff --git a/ui/shell_dialogs/select_file_dialog_lacros.cc b/ui/shell_dialogs/select_file_dialog_lacros.cc
index df6fc20..c5eb1f4 100644
--- a/ui/shell_dialogs/select_file_dialog_lacros.cc
+++ b/ui/shell_dialogs/select_file_dialog_lacros.cc
@@ -97,7 +97,8 @@
 }
 
 bool SelectFileDialogLacros::IsRunning(gfx::NativeWindow owning_window) const {
-  return true;
+  return !owning_shell_window_id_.empty() &&
+         GetShellWindowUniqueId(owning_window) == owning_shell_window_id_;
 }
 
 void SelectFileDialogLacros::SelectFileImpl(
@@ -128,8 +129,10 @@
         GetMojoAllowedPaths(file_types->allowed_paths);
   }
   // Modeless file dialogs have no owning window.
-  if (owning_window)
-    options->owning_shell_window_id = GetShellWindowUniqueId(owning_window);
+  if (owning_window) {
+    owning_shell_window_id_ = GetShellWindowUniqueId(owning_window);
+    options->owning_shell_window_id = owning_shell_window_id_;
+  }
 
   // Send request to ash-chrome.
   chromeos::LacrosService::Get()
@@ -142,6 +145,7 @@
     crosapi::mojom::SelectFileResult result,
     std::vector<crosapi::mojom::SelectedFileInfoPtr> mojo_files,
     int file_type_index) {
+  owning_shell_window_id_.clear();
   if (!listener_)
     return;
   if (mojo_files.empty()) {
diff --git a/ui/shell_dialogs/select_file_dialog_lacros.h b/ui/shell_dialogs/select_file_dialog_lacros.h
index a2c633e..7d513c6 100644
--- a/ui/shell_dialogs/select_file_dialog_lacros.h
+++ b/ui/shell_dialogs/select_file_dialog_lacros.h
@@ -61,6 +61,9 @@
 
   // Cached parameters from the call to SelectFileImpl.
   void* params_ = nullptr;
+
+  // The unique ID of the wayland shell surface that owns this dialog.
+  std::string owning_shell_window_id_;
 };
 
 }  // namespace ui
diff --git a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
index ff08be88..d6d85f8 100644
--- a/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/ca_trust_edit_dialog.ts
@@ -27,10 +27,11 @@
 export interface CaTrustEditDialogElement {
   $: {
     dialog: CrDialogElement,
-    ssl: CrCheckboxElement,
     email: CrCheckboxElement,
     objSign: CrCheckboxElement,
+    ok: HTMLElement,
     spinner: PaperSpinnerLiteElement,
+    ssl: CrCheckboxElement,
   };
 }
 
@@ -113,4 +114,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'ca-trust-edit-dialog': CaTrustEditDialogElement;
+  }
+}
+
 customElements.define(CaTrustEditDialogElement.is, CaTrustEditDialogElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
index e8717e12..45121090 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_delete_confirmation_dialog.ts
@@ -22,6 +22,7 @@
 export interface CertificateDeleteConfirmationDialogElement {
   $: {
     dialog: CrDialogElement,
+    ok: HTMLElement,
   };
 }
 
@@ -109,6 +110,13 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-delete-confirmation-dialog':
+        CertificateDeleteConfirmationDialogElement;
+  }
+}
+
 customElements.define(
     CertificateDeleteConfirmationDialogElement.is,
     CertificateDeleteConfirmationDialogElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
index dec7761..f2385da 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
@@ -20,6 +20,15 @@
 import {CertificateAction, CertificateActionEvent} from './certificate_manager_types.js';
 import {CertificatesBrowserProxyImpl, CertificatesError, CertificatesImportError, CertificatesOrgGroup, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js';
 
+export interface CertificateListElement {
+  $: {
+    import: HTMLElement,
+    // <if expr="chromeos_ash or chromeos_lacros">
+    importAndBind: HTMLElement,
+    // </if>
+  };
+}
+
 const CertificateListElementBase = I18nMixin(PolymerElement);
 
 export class CertificateListElement extends CertificateListElementBase {
@@ -169,4 +178,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-list': CertificateListElement;
+  }
+}
+
 customElements.define(CertificateListElement.is, CertificateListElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
index 4db93d9..c7f7d68 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.html
@@ -17,8 +17,7 @@
       </certificate-delete-confirmation-dialog>
     </template>
     <template is="dom-if" if="[[showPasswordEncryptionDialog_]]" restamp>
-      <certificate-password-encryption-dialog
-          model="[[dialogModel_]]">
+      <certificate-password-encryption-dialog>
       </certificate-password-encryption-dialog>
     </template>
     <template is="dom-if" if="[[showPasswordDecryptionDialog_]]" restamp>
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
index ec754c0..f4dffd6 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
@@ -277,4 +277,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-manager': CertificateManagerElement;
+  }
+}
+
 customElements.define(CertificateManagerElement.is, CertificateManagerElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
index e312939..6ae57aa 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_decryption_dialog.ts
@@ -13,6 +13,7 @@
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {CrButtonElement} from '../../cr_elements/cr_button/cr_button.m.js';
 import {CrDialogElement} from '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 
@@ -21,6 +22,7 @@
 export interface CertificatePasswordDecryptionDialogElement {
   $: {
     dialog: CrDialogElement,
+    ok: CrButtonElement,
   };
 }
 
@@ -75,6 +77,13 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-password-decryption-dialog':
+        CertificatePasswordDecryptionDialogElement;
+  }
+}
+
 customElements.define(
     CertificatePasswordDecryptionDialogElement.is,
     CertificatePasswordDecryptionDialogElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
index 5f95b6d6..8ab3c8a 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_password_encryption_dialog.ts
@@ -42,8 +42,6 @@
 
   static get properties() {
     return {
-      model: Object,
-
       password_: {
         type: String,
         value: '',
@@ -92,6 +90,13 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-password-encryption-dialog':
+        CertificatePasswordEncryptionDialogElement;
+  }
+}
+
 customElements.define(
     CertificatePasswordEncryptionDialogElement.is,
     CertificatePasswordEncryptionDialogElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.ts
index aaa8a71..53cf602 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_details_dialog.ts
@@ -20,6 +20,7 @@
 export interface CertificateProvisioningDetailsDialogElement {
   $: {
     dialog: CrDialogElement,
+    refresh: HTMLElement,
   };
 }
 
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
index 54439a8..59fed70 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_entry.ts
@@ -70,6 +70,12 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-provisioning-entry': CertificateProvisioningEntryElement;
+  }
+}
+
 customElements.define(
     CertificateProvisioningEntryElement.is,
     CertificateProvisioningEntryElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.ts
index f15ad69..239952c 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_provisioning_list.ts
@@ -122,5 +122,11 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-provisioning-list': CertificateProvisioningListElement;
+  }
+}
+
 customElements.define(
     CertificateProvisioningListElement.is, CertificateProvisioningListElement);
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
index 5185106..a9653fb 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
@@ -156,5 +156,11 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'certificate-subentry': CertificateSubentryElement;
+  }
+}
+
 customElements.define(
     CertificateSubentryElement.is, CertificateSubentryElement);
diff --git a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
index 657873b..208788b 100644
--- a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
+++ b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.js
@@ -155,6 +155,14 @@
    */
   updateTimerId_: undefined,
 
+  /**
+   * Updates the current state to account for whether dark mode is enabled.
+   * @private
+   */
+  onDarkModeChanged_() {
+    this.updateAnimationAsset_();
+  },
+
   /** @override */
   attached() {
     this.scale_ = this.circleRadius / DEFAULT_CANVAS_CIRCLE_RADIUS;
@@ -162,6 +170,97 @@
   },
 
   /**
+   * Reset the element to initial state, when the enrollment just starts.
+   * @public
+   */
+  reset() {
+    this.cancelAnimations_();
+    this.clearCanvas_();
+    this.isComplete_ = false;
+    // Draw an empty background for the progress circle.
+    this.drawProgressCircle_(/** currentPercent = */ 0);
+    this.$.enrollmentDone.hidden = true;
+
+    const scanningAnimation =
+        /** @type {CrLottieElement|HTMLElement} */ (this.$.scanningAnimation);
+    scanningAnimation.singleLoop = false;
+    scanningAnimation.classList.add('translucent');
+    this.updateAnimationAsset_();
+    this.resizeAndCenterIcon_(scanningAnimation);
+    scanningAnimation.hidden = false;
+  },
+
+  /**
+   * Animates the progress circle. Animates an arc that starts at the top of
+   * the circle to prevPercentComplete, to an arc that starts at the top of the
+   * circle to currPercentComplete.
+   * @param {number} prevPercentComplete The previous progress indicates the
+   *                 start angle of the arc we want to draw.
+   * @param {number} currPercentComplete The current progress indicates the end
+   *                 angle of the arc we want to draw.
+   * @param {boolean} isComplete Indicate whether enrollment is complete.
+   * @public
+   */
+  setProgress(prevPercentComplete, currPercentComplete, isComplete) {
+    if (this.isComplete_) {
+      return;
+    }
+    this.isComplete_ = isComplete;
+    this.cancelAnimations_();
+
+    let nextPercentToDraw = prevPercentComplete;
+    const endPercent = isComplete ? 100 : Math.min(100, currPercentComplete);
+    // The value by which to update the progress percent each tick.
+    const step = (endPercent - prevPercentComplete) /
+        (ANIMATE_DURATION_MS / ANIMATE_TICKS_MS);
+
+    // Function that is called every tick of the interval, draws the arc a bit
+    // closer to the final destination each tick, until it reaches the final
+    // destination.
+    const doAnimate = () => {
+      if (nextPercentToDraw >= endPercent) {
+        if (this.progressAnimationIntervalId_) {
+          clearInterval(this.progressAnimationIntervalId_);
+          this.progressAnimationIntervalId_ = undefined;
+        }
+        nextPercentToDraw = endPercent;
+      }
+
+      this.clearCanvas_();
+      this.drawProgressCircle_(nextPercentToDraw);
+      if (!this.progressAnimationIntervalId_) {
+        this.fire('cr-fingerprint-progress-arc-drawn');
+      }
+      nextPercentToDraw += step;
+    };
+
+    this.progressAnimationIntervalId_ =
+        setInterval(doAnimate, ANIMATE_TICKS_MS);
+
+    if (isComplete) {
+      this.animateScanComplete_();
+    } else {
+      this.animateScanProgress_();
+    }
+  },
+
+  /**
+   * Controls the animation based on the value of |shouldPlay|.
+   * @param {boolean} shouldPlay Will play the animation if true else pauses it.
+   * @public
+   */
+  setPlay(shouldPlay) {
+    const scanningAnimation =
+        /** @type {CrLottieElement|HTMLElement} */ (this.$.scanningAnimation);
+    scanningAnimation.setPlay(shouldPlay);
+  },
+
+  /** @public */
+  isComplete() {
+    return this.isComplete_;
+  },
+
+  /**
    * Draws an arc on the canvas element around the center with radius
    * |circleRadius|.
    * @param {number} startAngle The start angle of the arc we want to draw.
@@ -169,8 +268,9 @@
    * @param {string} color The color of the arc we want to draw. The string is
    *     in the format rgba(r',g',b',a'). r', g', b' are values from [0-255]
    *     and a' is a value from [0-1].
+   * @private
    */
-  drawArc(startAngle, endAngle, color) {
+  drawArc_(startAngle, endAngle, color) {
     const c = this.$.canvas;
     const ctx = c.getContext('2d');
 
@@ -183,94 +283,29 @@
 
   /**
    * Draws a circle on the canvas element around the center with radius
-   * |circleRadius| and color |CANVAS_CIRCLE_BACKGROUND_COLOR|.
-   */
-  drawBackgroundCircle() {
-    this.drawArc(0, 2 * Math.PI, this.canvasCircleBackgroundColor);
-  },
-
-  /**
-   * Animates the progress circle. Animates an arc that starts at the top of
-   * the circle to prevPercentComplete, to an arc that starts at the top of the
-   * circle to currPercentComplete.
-   * @param {number} prevPercentComplete The previous progress indicates the
-   *                 start angle of the arc we want to draw.
-   * @param {number} currPercentComplete The current progress indicates the end
-   *                 angle of the arc we want to draw.
-   * @param {boolean} isComplete Indicate whether enrollment is complete.
-   */
-  setProgress(prevPercentComplete, currPercentComplete, isComplete) {
-    if (this.isComplete_) {
-      return;
-    }
-    this.isComplete_ = isComplete;
-    this.cancelAnimations_();
-
-    const slice = 2 * Math.PI / 100;
-    const startAngle = prevPercentComplete * slice;
-    const endAngle = isComplete ?
-        2 * Math.PI :
-        Math.min(2 * Math.PI, currPercentComplete * slice);
-    let currentAngle = startAngle;
-    // The value to update the angle by each tick.
-    const step =
-        (endAngle - startAngle) / (ANIMATE_DURATION_MS / ANIMATE_TICKS_MS);
-    // Function that is called every tick of the interval, draws the arc a bit
-    // closer to the final destination each tick, until it reaches the final
-    // destination.
-    const doAnimate = () => {
-      if (currentAngle >= endAngle) {
-        if (this.progressAnimationIntervalId_) {
-          clearInterval(this.progressAnimationIntervalId_);
-          this.progressAnimationIntervalId_ = undefined;
-        }
-        currentAngle = endAngle;
-      }
-
-      // Clears the canvas and draws the new progress circle.
-      this.clearCanvas_();
-      // Drawing two arcs to form a circle gives a nicer look than drawing
-      // an arc on top of a circle. If |currentAngle| is 0, draw from
-      // |start| + |currentAngle| to 7 * Math.PI / 2 (start is 3 * Math.PI /
-      // 2) otherwise the regular draw from |start| to |currentAngle| will
-      // draw nothing which will cause a flicker for one frame.
-      this.drawArc(start, start + currentAngle, this.canvasCircleProgressColor);
-      this.drawArc(
-          start + currentAngle, currentAngle <= 0 ? 7 * Math.PI / 2 : start,
-          this.canvasCircleBackgroundColor);
-      currentAngle += step;
-    };
-
-    this.progressAnimationIntervalId_ =
-        setInterval(doAnimate, ANIMATE_TICKS_MS);
-    // Circles on html canvas have 0 radians on the positive x-axis and go in
-    // clockwise direction. We want to start at the top of the circle which is
-    // 3pi/2.
-    const start = 3 * Math.PI / 2;
-
-    if (isComplete) {
-      this.animateScanComplete_();
-    } else {
-      this.animateScanProgress_();
-    }
-  },
-
-  /**
-   * Controls the animation based on the value of |shouldPlay|.
-   * @param {boolean} shouldPlay Will play the animation if true else pauses it.
-   */
-  setPlay(shouldPlay) {
-    const scanningAnimation =
-        /** @type {CrLottieElement|HTMLElement} */ (this.$.scanningAnimation);
-    scanningAnimation.setPlay(shouldPlay);
-  },
-
-  /**
-   * Updates the current state to account for whether dark mode is enabled.
+   * |circleRadius|. The first |currentPercent| of the circle, starting at the
+   * top, is painted with |CANVAS_CIRCLE_PROGRESS_COLOR|; the remainder of the
+   * circle is painted |CANVAS_CIRCLE_BACKGROUND_COLOR|.
+   * @param {number} currentPercent A value from [0-100] indicating the
+   *     percentage of progress to display.
    * @private
    */
-  onDarkModeChanged_() {
-    this.updateAnimationAsset_();
+  drawProgressCircle_(currentPercent) {
+    // Angles on HTML canvases start at 0 radians on the positive x-axis and
+    // increase in the clockwise direction. We want to start at the top of the
+    // circle, which is 3pi/2.
+    const start = 3 * Math.PI / 2;
+    const currentAngle = 2 * Math.PI * currentPercent / 100;
+
+    // Drawing two arcs to form a circle gives a nicer look than drawing an arc
+    // on top of a circle (i.e., compared to drawing a full background circle
+    // first). If |currentAngle| is 0, draw from 3pi/2 to 7pi/2 explicitly;
+    // otherwise, the regular draw from |start| + |currentAngle| to |start|
+    // will do nothing.
+    this.drawArc_(start, start + currentAngle, this.canvasCircleProgressColor);
+    this.drawArc_(
+        start + currentAngle, currentAngle <= 0 ? 7 * Math.PI / 2 : start,
+        this.canvasCircleBackgroundColor);
   },
 
   /**
@@ -343,25 +378,6 @@
   },
 
   /**
-   * Reset the element to initial state, when the enrollment just starts.
-   */
-  reset() {
-    this.cancelAnimations_();
-    this.clearCanvas_();
-    this.isComplete_ = false;
-    this.drawBackgroundCircle();
-    this.$.enrollmentDone.hidden = true;
-
-    const scanningAnimation =
-        /** @type {CrLottieElement|HTMLElement} */ (this.$.scanningAnimation);
-    scanningAnimation.singleLoop = false;
-    scanningAnimation.classList.add('translucent');
-    this.updateAnimationAsset_();
-    this.resizeAndCenterIcon_(scanningAnimation);
-    scanningAnimation.hidden = false;
-  },
-
-  /**
    * Update the size and position of the animation images.
    * @private
    */
@@ -409,11 +425,6 @@
     target.style.left = left + 'px';
     target.style.top = top + 'px';
   },
-
-  /** @public */
-  isComplete() {
-    return this.isComplete_;
-  },
 });
 /* #ignore */ console.warn('crbug/1173575, non-JS module files deprecated.');
 })();
diff --git a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.d.ts b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.d.ts
index 3457791..f2bac1e 100644
--- a/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.d.ts
+++ b/ui/webui/resources/cr_elements/cr_fingerprint/cr_fingerprint_progress_arc.m.d.ts
@@ -15,13 +15,11 @@
   canvasCircleBackgroundColor: string;
   canvasCircleProgressColor: string;
 
-  drawArc(startAngle: number, endAngle: number, color: string): void;
-  drawBackgroundCircle(): void;
-
+  reset(): void;
   setProgress(
       prevPercentComplete: number, currPercentComplete: number,
       isComplete: boolean): void;
-  reset(): void;
+  setPlay(shouldPlay: boolean): void;
   isComplete(): boolean;
   $: {
     canvas: HTMLCanvasElement,
diff --git a/ui/webui/resources/css/md_colors.css b/ui/webui/resources/css/md_colors.css
index 7f76f9f5..634850f 100644
--- a/ui/webui/resources/css/md_colors.css
+++ b/ui/webui/resources/css/md_colors.css
@@ -7,18 +7,10 @@
    * --google equivalent. */
   --md-background-color: rgb(248, 249, 250);
   --md-loading-message-color: #6e6e6e;
-  /* --google-blue-700, rewritten as a native custom property for speed. */
-  --md-toolbar-color: rgb(51, 103, 214);
+  --md-toolbar-color: white;
   --md-toolbar-height: 56px;
 }
 
-@media (prefers-color-scheme: light) {
-  html[enable-branding-update] {
-    --md-background-color: white;
-    --md-toolbar-color: white;
-  }
-}
-
 @media (prefers-color-scheme: dark) {
   html {
     --md-background-color: rgb(32, 33, 36);  /* --google-grey-900 */
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java
index 4c096b1..5ac82e31 100644
--- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java
+++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/TabTest.java
@@ -8,6 +8,7 @@
 import android.graphics.Color;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.LinearLayout;
 
 import androidx.fragment.app.Fragment;
 import androidx.test.filters.SmallTest;
@@ -32,6 +33,7 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -124,18 +126,19 @@
 
     private Bitmap captureScreenShot(float scale) throws TimeoutException {
         Bitmap[] bitmapHolder = new Bitmap[1];
+        int[] errorCodeHolder = new int[1];
         CallbackHelper callbackHelper = new CallbackHelper();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             Tab tab = mActivity.getTab();
             tab.captureScreenShot(scale, (Bitmap bitmap, int errorCode) -> {
-                Assert.assertNotNull(bitmap);
-                Assert.assertEquals(0, errorCode);
+                errorCodeHolder[0] = errorCode;
                 bitmapHolder[0] = bitmap;
-                // Failure is ok here, so not checking |bitmap| or |errorCode|.
                 callbackHelper.notifyCalled();
             });
         });
         callbackHelper.waitForFirst();
+        Assert.assertNotNull(bitmapHolder[0]);
+        Assert.assertEquals(0, errorCodeHolder[0]);
         return bitmapHolder[0];
     }
 
@@ -167,6 +170,33 @@
 
     @Test
     @SmallTest
+    @MinWebLayerVersion(101)
+    public void testCaptureScreenShotAfterResize() throws TimeoutException, ExecutionException {
+        String url = mActivityTestRule.getTestDataURL("quadrant_colors.html");
+        mActivity = mActivityTestRule.launchShellWithUrl(url);
+
+        int newHeight = TestThreadUtils.runOnUiThreadBlocking(() -> {
+            View view = mActivity.getFragment().getView();
+            int height = view.getHeight() + 10;
+            LinearLayout.LayoutParams params =
+                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
+            view.setLayoutParams(params);
+            view.requestLayout();
+            return height;
+        });
+
+        CriteriaHelper.pollUiThread(() -> {
+            View view = mActivity.getFragment().getView();
+            int height = view.getHeight();
+            Criteria.checkThat(height, Matchers.is(newHeight));
+        });
+
+        Bitmap bitmap = captureScreenShot(1.f);
+        checkQuadrantColors(bitmap);
+    }
+
+    @Test
+    @SmallTest
     public void testCaptureScreenShotDoesNotHang() throws TimeoutException {
         String startupUrl = "about:blank";
         mActivity = mActivityTestRule.launchShellWithUrl(startupUrl);
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index 9db135b..8c31bf2 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -1052,7 +1052,7 @@
         embedder_support::kOriginTrialPublicKey,
     };
     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
-                                   base::size(kSwitchNames));
+                                   std::size(kSwitchNames));
   }
 }
 
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
index e675a3e..dce3fad 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -177,7 +177,7 @@
             }
             ContentViewRenderViewJni.get().surfaceChanged(mNativeContentViewRenderView,
                     canBeUsedWithSurfaceControl, width, height, transparentBackground, surface);
-            mCompositorHasSurface = surface != null;
+            mCompositorHasSurface = mLastSurface != null;
             maybeUpdatePhysicalBackingSize(width, height);
             updateBackgroundColor();
         }
diff --git a/weblayer/browser/persistence/browser_persister_file_utils.cc b/weblayer/browser/persistence/browser_persister_file_utils.cc
index 2bddbf5..796d447b 100644
--- a/weblayer/browser/persistence/browser_persister_file_utils.cc
+++ b/weblayer/browser/persistence/browser_persister_file_utils.cc
@@ -4,7 +4,6 @@
 
 #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"
@@ -58,11 +57,11 @@
   for (base::FilePath name = iter.Next(); !name.empty(); name = iter.Next()) {
     // The name is base32 encoded, which is ascii.
     const std::string base_name = iter.GetInfo().GetName().MaybeAsASCII();
-    if (base_name.size() <= base::size(BrowserImpl::kPersistenceFilePrefix))
+    if (base_name.size() <= std::size(BrowserImpl::kPersistenceFilePrefix))
       continue;
 
     const std::string encoded_id_and_timestamp =
-        base_name.substr(base::size(BrowserImpl::kPersistenceFilePrefix) - 1);
+        base_name.substr(std::size(BrowserImpl::kPersistenceFilePrefix) - 1);
     const size_t separator_index = encoded_id_and_timestamp.find(
         base::FilePath(sessions::kTimestampSeparator).MaybeAsASCII());
     const std::string encoded_id =
diff --git a/weblayer/shell/browser/shell_views.cc b/weblayer/shell/browser/shell_views.cc
index f64ef700..6137355 100644
--- a/weblayer/shell/browser/shell_views.cc
+++ b/weblayer/shell/browser/shell_views.cc
@@ -2,16 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/raw_ptr.h"
-#include "weblayer/shell/browser/shell.h"
-
 #include <stddef.h>
 
 #include <memory>
 
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/cxx17_backports.h"
+#include "base/memory/raw_ptr.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -37,6 +34,7 @@
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 #include "weblayer/public/tab.h"
+#include "weblayer/shell/browser/shell.h"
 
 #if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS)
 #include "ui/display/screen.h"
@@ -216,7 +214,7 @@
     DCHECK(GetWidget());
     static const ui::KeyboardCode keys[] = {ui::VKEY_F5, ui::VKEY_BROWSER_BACK,
                                             ui::VKEY_BROWSER_FORWARD};
-    for (size_t i = 0; i < base::size(keys); ++i) {
+    for (size_t i = 0; i < std::size(keys); ++i) {
       GetFocusManager()->RegisterAccelerator(
           ui::Accelerator(keys[i], ui::EF_NONE),
           ui::AcceleratorManager::kNormalPriority, this);