diff --git a/DEPS b/DEPS
index e5dd7543..2951c58f 100644
--- a/DEPS
+++ b/DEPS
@@ -269,23 +269,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': '1f99c991d8c9d0c7573605ce23926af3b8bdfe7b',
+  'skia_revision': '133f1203c2b86bb848e7d8f18398ad031ef6b4ee',
   # 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': '3b5cd6ee74eadd207f05cbc1583c259e69af8f1b',
+  'v8_revision': 'd7df14edfa8c475d1d4047a8c5268538b4123ee5',
   # 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': '84e42c3b04da9e2c9d93d35bb6f2b1830fef22f4',
+  'angle_revision': '9ad43bdd2acaaab418c2cad21308284b15345ce5',
   # 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': 'e617219743aaba9cf3bd8ec9bad2447f7a236996',
+  'swiftshader_revision': 'c75846ead9a0fdabcc2a567d539b988b71f6cef0',
   # 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': '17be9fefade8fa1030a6c1e02c1a6db05f0b1de9',
+  'pdfium_revision': 'ee0c29691b42600190db18168cb94e16e913d97f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -336,7 +336,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': 'eebb0a0e637f95a79da9f8d2b0cd7f227005c425',
+  'catapult_revision': 'd3c44146a63526b5ef7e40adf7668fd934a4b42f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -344,7 +344,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': 'aa669efba00a00bfa3ee9b75ff4b15b5eb83575e',
+  'devtools_frontend_revision': 'a062a6afd7adbad75b099c7e2321e49f96a409b7',
   # 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.
@@ -380,7 +380,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': 'a1a3e0484c489bb7fd52be91be0388c99dde6e30',
+  'dawn_revision': '7212ad32057e4ccb5334a5cf28ce827c88670837',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -737,11 +737,11 @@
     Var('chromium_git') + '/external/github.com/toji/webvr.info.git' + '@' + 'c58ae99b9ff9e2aa4c524633519570bf33536248',
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '450552850fbd0f452995c2fa1c6a9f2e99ab56b9',
+    'url': Var('chromium_git') + '/website.git' + '@' + '7c8496556a5b3900d846bca8ea895f46283e62b5',
   },
 
   'src/ios/third_party/earl_grey2/src': {
-      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '588e74da038881dbd6ac1378c53340229944b718',
+      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '639c85ddc517350b0e37f85b6b526bba84bd1d92',
       'condition': 'checkout_ios',
   },
 
@@ -910,7 +910,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '5lNM3F4iN06ifNmpRsHMr0HuYciW6jkC2V6cduIaL64C',
+          'version': 'gA0vvkGrsh9eQymdSOfRTYnYJpY-Wq7wonB0rx2eiMcC',
       },
     ],
     'condition': 'checkout_android',
@@ -1103,7 +1103,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6fa9486eb2536d1358d8919511dc4cd55e655bfb',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9f3d50fc5896e944135aded49ccadd8ad96b6168',
       'condition': 'checkout_chromeos',
   },
 
@@ -1126,7 +1126,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e06e30775077e195581f58170455e4f59f5839ae',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fb8cf9cc784053e97b29efca560cf13a3c98a3d7',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
@@ -1512,7 +1512,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f233f88ebb954879424a5401ea2aee222d1787da',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f8b405298bd883ba95f7a14acfce230b37487ad3',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1703,7 +1703,7 @@
       'condition': 'checkout_android',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@4ca7acf898690c22794554d7d3299117d9f75d5a',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@3e76ffe3d4b39f7ec38581712dbde5c2e63ef0fb',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1739,10 +1739,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'cf04aebdf9b53bb2853f22a81465688daf879ec6',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '547d67bc2212c0d203b9598d8ed3e1589ffb085a',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '5906dcba4de95d2f18dd8d4adcd52345a539cc19',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '9a743179cfe311d64a97710d066328071f8ee131',
+    Var('webrtc_git') + '/src.git' + '@' + '00579e8bcec66fab2e7babef25d4423ef7b3591f',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1815,7 +1815,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@be962c348e7e238241448890ec5521442f5643fc',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b0923472acb970009c494e46ed333aae2ebc4666',
     'condition': 'checkout_src_internal',
   },
 
@@ -1845,7 +1845,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'oqkSVtR-9vLgbahio-TVYizM6Dk_zfwhf1nRfo0T--sC',
+        'version': 'SXXgkxFBSbI6c8_wO6Q0V3Axb9VESR816SdqMg_6e_IC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1856,7 +1856,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'wYaFK7exMbT9TAmZKvpu_EPC54-us6mkJLYhK2fmHNEC',
+        'version': 'whtlcNpoS3yXW5MkBK5x_wlfpid2geTTH_hI5C5Dx6wC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3592,6 +3592,7 @@
   "+third_party/abseil-cpp/absl/numeric/int128.h",
   '+third_party/abseil-cpp/absl/types/optional.h',
   '+third_party/abseil-cpp/absl/types/variant.h',
+  '+third_party/abseil-cpp/absl/utility/utility.h',
 ]
 
 
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn
index 77ca8fc..3e9bc66b 100644
--- a/android_webview/test/BUILD.gn
+++ b/android_webview/test/BUILD.gn
@@ -507,7 +507,6 @@
   ]
   deps = [
     "//android_webview:common_variations_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/component_updater/android:embedded_component_loader_java",
@@ -645,7 +644,6 @@
   testonly = true
   deps = [
     "//android_webview:android_webview_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/test/android:content_java_test_support",
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn
index ad3c0dd..b03681a 100644
--- a/android_webview/test/embedded_test_server/BUILD.gn
+++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -13,7 +13,6 @@
     "java/src/org/chromium/android_webview/test/AwEmbeddedTestServerService.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
@@ -68,7 +67,6 @@
 
   deps = [
     ":aw_net_java_test_support",
-    "//base:base_java",
     "//build/android:build_java",
   ]
   android_manifest = "java/AndroidManifest.xml"
diff --git a/android_webview/tools/system_webview_shell/BUILD.gn b/android_webview/tools/system_webview_shell/BUILD.gn
index b2f066c7..e9b416a1 100644
--- a/android_webview/tools/system_webview_shell/BUILD.gn
+++ b/android_webview/tools/system_webview_shell/BUILD.gn
@@ -120,7 +120,6 @@
   sources = [ "page_cycler/src/org/chromium/webview_shell/page_cycler/PageCyclerTest.java" ]
   deps = [
     ":system_webview_shell_apk_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//content/public/android:content_java",
diff --git a/android_webview/tools/system_webview_shell/apk/AndroidManifest.xml b/android_webview/tools/system_webview_shell/apk/AndroidManifest.xml
index 6e9b3a0..7a8b23f 100644
--- a/android_webview/tools/system_webview_shell/apk/AndroidManifest.xml
+++ b/android_webview/tools/system_webview_shell/apk/AndroidManifest.xml
@@ -89,6 +89,7 @@
                 <action android:name="android.intent.action.VIEW" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="content" />
                 <data android:scheme="http" />
                 <data android:scheme="https" />
                 <data android:mimeType="text/html"/>
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
index b15de68..f370d96 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -736,6 +736,7 @@
         settings.setDatabaseEnabled(true);
         settings.setDomStorageEnabled(true);
         settings.setAllowFileAccess(true);
+        settings.setAllowContentAccess(true);
 
         // Default layout behavior for chrome on android.
         settings.setUseWideViewPort(true);
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 6f829226..dad65ea 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -146,6 +146,7 @@
       std::make_unique<RoundedScrollBar>(/*horizontal=*/false);
   vertical_scroll->SetInsets(kVerticalScrollInsets);
   vertical_scroll->SetSnapBackOnDragOutside(false);
+  scroll_bar_ = vertical_scroll.get();
   scroll_view_->SetVerticalScrollBar(std::move(vertical_scroll));
 
   auto scroll_contents = std::make_unique<views::View>();
@@ -255,6 +256,10 @@
 void AppListBubbleAppsPage::AnimateShowLauncher(bool is_side_shelf) {
   DCHECK(GetVisible());
 
+  // Don't show the scroll bar due to thumb bounds changes. There's enough
+  // visual movement going on during the animation.
+  scroll_bar_->SetShowOnThumbBoundsChanged(false);
+
   // The animation relies on the correct positions of views, so force layout.
   if (needs_layout())
     Layout();
@@ -676,6 +681,9 @@
   // the gradient mask layer.
   gradient_helper_ = std::make_unique<ScrollViewGradientHelper>(scroll_view_);
   gradient_helper_->UpdateGradientZone();
+
+  // Show the scroll bar for keyboard-driven scroll position changes.
+  scroll_bar_->SetShowOnThumbBoundsChanged(true);
 }
 
 void AppListBubbleAppsPage::HandleFocusAfterSort() {
diff --git a/ash/app_list/views/app_list_bubble_apps_page.h b/ash/app_list/views/app_list_bubble_apps_page.h
index e9078d84..d1f0d4d6 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.h
+++ b/ash/app_list/views/app_list_bubble_apps_page.h
@@ -42,6 +42,7 @@
 class ContinueSectionView;
 class PillButton;
 class RecentAppsView;
+class RoundedScrollBar;
 class SearchResultPageDialogController;
 class SearchBoxView;
 class ScrollableAppsGridView;
@@ -211,6 +212,7 @@
 
   AppListViewDelegate* view_delegate_ = nullptr;
   views::ScrollView* scroll_view_ = nullptr;
+  RoundedScrollBar* scroll_bar_ = nullptr;
   PillButton* show_continue_section_button_ = nullptr;
   ContinueSectionView* continue_section_ = nullptr;
   RecentAppsView* recent_apps_ = nullptr;
diff --git a/ash/assistant/assistant_ui_controller_impl.cc b/ash/assistant/assistant_ui_controller_impl.cc
index bda54b12..32dfb6d 100644
--- a/ash/assistant/assistant_ui_controller_impl.cc
+++ b/ash/assistant/assistant_ui_controller_impl.cc
@@ -237,12 +237,6 @@
 }
 
 void AssistantUiControllerImpl::OnOnboardingShown() {
-  using chromeos::assistant::prefs::AssistantOnboardingMode;
-  base::UmaHistogramEnumeration(
-      "Assistant.BetterOnboarding.Shown",
-      AssistantState::Get()->onboarding_mode().value_or(
-          AssistantOnboardingMode::kDefault));
-
   if (has_shown_onboarding_)
     return;
 
diff --git a/ash/components/drivefs/drivefs_host.cc b/ash/components/drivefs/drivefs_host.cc
index 74841993..8a8f785 100644
--- a/ash/components/drivefs/drivefs_host.cc
+++ b/ash/components/drivefs/drivefs_host.cc
@@ -78,7 +78,7 @@
       DriveFsHost::Delegate* delegate) {
     auto access_token = auth_delegate->GetCachedAccessToken();
     mojom::DriveFsConfigurationPtr config = {
-        base::in_place,
+        absl::in_place,
         auth_delegate->GetAccountId().GetUserEmail(),
         std::move(access_token),
         auth_delegate->IsMetricsCollectionEnabled(),
@@ -184,7 +184,7 @@
     std::vector<mojom::FetchChangeLogOptionsPtr> options;
     options.reserve(invalidations.size());
     for (const auto& invalidation : invalidations) {
-      options.emplace_back(base::in_place, invalidation.second,
+      options.emplace_back(absl::in_place, invalidation.second,
                            invalidation.first);
     }
     drivefs_interface()->FetchChangeLog(std::move(options));
diff --git a/ash/components/drivefs/drivefs_host_unittest.cc b/ash/components/drivefs/drivefs_host_unittest.cc
index 9dcfe055..fd310da16 100644
--- a/ash/components/drivefs/drivefs_host_unittest.cc
+++ b/ash/components/drivefs/drivefs_host_unittest.cc
@@ -42,6 +42,7 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/test/test_network_connection_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace drivefs {
 namespace {
@@ -488,7 +489,7 @@
       &observer);
   observation_scoper.Observe(host_.get());
   auto status = mojom::SyncingStatus::New();
-  status->item_events.emplace_back(base::in_place, 12, 34, "filename.txt",
+  status->item_events.emplace_back(absl::in_place, 12, 34, "filename.txt",
                                    mojom::ItemEvent::State::kInProgress, 123,
                                    456, mojom::ItemEventReason::kPin);
   mojom::SyncingStatusPtr observed_status;
@@ -514,11 +515,11 @@
       &observer);
   observation_scoper.Observe(host_.get());
   std::vector<mojom::FileChangePtr> changes;
-  changes.emplace_back(base::in_place, base::FilePath("/create"),
+  changes.emplace_back(absl::in_place, base::FilePath("/create"),
                        mojom::FileChange::Type::kCreate);
-  changes.emplace_back(base::in_place, base::FilePath("/delete"),
+  changes.emplace_back(absl::in_place, base::FilePath("/delete"),
                        mojom::FileChange::Type::kDelete);
-  changes.emplace_back(base::in_place, base::FilePath("/modify"),
+  changes.emplace_back(absl::in_place, base::FilePath("/modify"),
                        mojom::FileChange::Type::kModify);
   std::vector<mojom::FileChangePtr> observed_changes;
   EXPECT_CALL(observer, OnFilesChanged(_))
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 247d088..6cdc22f 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1436,6 +1436,11 @@
 const base::Feature kWallpaperWebUI{"WallpaperWebUI",
                                     base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Enable "daily" refresh wallpaper to refresh every ten seconds for testing.
+// Requires |kWallpaperWebUI| to also be enabled.
+const base::Feature kWallpaperFastRefresh{"WallpaperFastRefresh",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Enable full screen wallpaper preview in new wallpaper experience. Requires
 // |kWallpaperWebUI| to also be enabled.
 const base::Feature kWallpaperFullScreenPreview{
@@ -2163,6 +2168,11 @@
   return base::FeatureList::IsEnabled(kWallpaperWebUI);
 }
 
+bool IsWallpaperFastRefreshEnabled() {
+  return IsWallpaperWebUIEnabled() &&
+         base::FeatureList::IsEnabled(kWallpaperFastRefresh);
+}
+
 bool IsWallpaperFullScreenPreviewEnabled() {
   return IsWallpaperWebUIEnabled() &&
          base::FeatureList::IsEnabled(kWallpaperFullScreenPreview);
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index af1e734..75f1d0f 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -558,6 +558,8 @@
 extern const base::Feature kWakeOnWifiAllowed;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kWallpaperWebUI;
 COMPONENT_EXPORT(ASH_CONSTANTS)
+extern const base::Feature kWallpaperFastRefresh;
+COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kWallpaperFullScreenPreview;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kWallpaperGooglePhotosIntegration;
@@ -750,6 +752,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTrilinearFilteringEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsUseStorkSmdsServerAddressEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperWebUIEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFastRefreshEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsWallpaperFullScreenPreviewEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsWallpaperGooglePhotosIntegrationEnabled();
diff --git a/ash/controls/rounded_scroll_bar.cc b/ash/controls/rounded_scroll_bar.cc
index 7322b17..fd95809 100644
--- a/ash/controls/rounded_scroll_bar.cc
+++ b/ash/controls/rounded_scroll_bar.cc
@@ -68,6 +68,10 @@
     canvas->DrawRoundRect(GetLocalBounds(), kScrollThumbRadiusDp, fill_flags);
   }
 
+  void OnBoundsChanged(const gfx::Rect& previous_bounds) override {
+    scroll_bar_->OnThumbBoundsChanged();
+  }
+
   void OnStateChanged() override { scroll_bar_->OnThumbStateChanged(); }
 
  private:
@@ -102,6 +106,10 @@
   thumb_->SetSnapBackOnDragOutside(snap);
 }
 
+void RoundedScrollBar::SetShowOnThumbBoundsChanged(bool show) {
+  show_on_thumb_bounds_changed_ = show;
+}
+
 gfx::Rect RoundedScrollBar::GetTrackBounds() const {
   gfx::Rect bounds = GetLocalBounds();
   bounds.Inset(insets_);
@@ -180,6 +188,13 @@
     ShowScrollbar();
 }
 
+void RoundedScrollBar::OnThumbBoundsChanged() {
+  // Optionally show the scroll bar on thumb bounds changes (e.g. keyboard
+  // driven scroll position changes).
+  if (show_on_thumb_bounds_changed_)
+    ShowScrollbar();
+}
+
 BEGIN_METADATA(RoundedScrollBar, ScrollBar)
 END_METADATA
 
diff --git a/ash/controls/rounded_scroll_bar.h b/ash/controls/rounded_scroll_bar.h
index 652f4e6..6e231af4 100644
--- a/ash/controls/rounded_scroll_bar.h
+++ b/ash/controls/rounded_scroll_bar.h
@@ -39,6 +39,11 @@
   // outside the thumb should "snap back" to the original scroll position.
   void SetSnapBackOnDragOutside(bool snap);
 
+  // Sets whether the scroll bar should show itself when the scroll thumb
+  // bounds are changed (i.e. when the scroll position changes or the content
+  // size changes).
+  void SetShowOnThumbBoundsChanged(bool show);
+
   // views::ScrollBar:
   gfx::Rect GetTrackBounds() const override;
   bool OverlapsContent() const override;
@@ -62,6 +67,9 @@
   // Called when the thumb hover/pressed state changed.
   void OnThumbStateChanged();
 
+  // Called when the thumb bounds (position or size) changed.
+  void OnThumbBoundsChanged();
+
   // Equivalent to GetThumb() but typed as the inner class `Thumb`.
   Thumb* const thumb_;
 
@@ -70,6 +78,9 @@
 
   // Timer that will start the scrollbar's hiding animation when it reaches 0.
   base::RetainingOneShotTimer hide_scrollbar_timer_;
+
+  // Whether to temporarily show the scroll bar when the thumb bounds change.
+  bool show_on_thumb_bounds_changed_ = false;
 };
 
 }  // namespace ash
diff --git a/ash/controls/rounded_scroll_bar_unittest.cc b/ash/controls/rounded_scroll_bar_unittest.cc
index cd919439..391102e 100644
--- a/ash/controls/rounded_scroll_bar_unittest.cc
+++ b/ash/controls/rounded_scroll_bar_unittest.cc
@@ -18,7 +18,10 @@
 namespace ash {
 namespace {
 
+// Scroll bar configuration.
 constexpr int kScrollBarWidth = 10;
+constexpr int kViewportHeight = 200;
+constexpr int kContentHeight = 1000;
 
 // Thumb opacity values.
 constexpr float kDefaultOpacity = 0.38f;
@@ -61,8 +64,8 @@
     scroll_bar_ = contents->AddChildView(
         std::make_unique<RoundedScrollBar>(/*horizontal=*/false));
     scroll_bar_->set_controller(&controller_);
-    scroll_bar_->SetBounds(90, 0, kScrollBarWidth, 200);
-    scroll_bar_->Update(/*viewport_size=*/200, /*content_size=*/1000,
+    scroll_bar_->SetBounds(90, 0, kScrollBarWidth, kViewportHeight);
+    scroll_bar_->Update(kViewportHeight, kContentHeight,
                         /*contents_scroll_offset=*/0);
     thumb_ = scroll_bar_->GetThumbForTest();
     generator_ = std::make_unique<ui::test::EventGenerator>(
@@ -86,6 +89,20 @@
   EXPECT_EQ(thumb_->layer()->GetTargetOpacity(), 0.f);
 }
 
+TEST_F(RoundedScrollBarTest, ShowOnThumbBoundsChanged) {
+  // Programmatically scroll the view, which changes the thumb bounds.
+  // By default this does not show the thumb.
+  scroll_bar_->Update(kViewportHeight, kContentHeight,
+                      /*contents_scroll_offset=*/100);
+  EXPECT_EQ(thumb_->layer()->GetTargetOpacity(), 0.f);
+
+  // With the setting enabled, changing the thumb bounds shows the thumb.
+  scroll_bar_->SetShowOnThumbBoundsChanged(true);
+  scroll_bar_->Update(kViewportHeight, kContentHeight,
+                      /*contents_scroll_offset=*/200);
+  EXPECT_EQ(thumb_->layer()->GetTargetOpacity(), kDefaultOpacity);
+}
+
 TEST_F(RoundedScrollBarTest, ScrollingShowsDefaultOpacity) {
   scroll_bar_->ScrollByAmount(views::ScrollBar::ScrollAmount::kNextLine);
   EXPECT_EQ(thumb_->layer()->GetTargetOpacity(), kDefaultOpacity);
diff --git a/ash/public/cpp/app_list/app_list_types.cc b/ash/public/cpp/app_list/app_list_types.cc
index 5eb88abf..482b873 100644
--- a/ash/public/cpp/app_list/app_list_types.cc
+++ b/ash/public/cpp/app_list/app_list_types.cc
@@ -47,6 +47,39 @@
   }
 }
 
+bool IsContinueSectionResultType(AppListSearchResultType result_type) {
+  switch (result_type) {
+    case AppListSearchResultType::kZeroStateFile:
+    case AppListSearchResultType::kZeroStateDrive:
+    case AppListSearchResultType::kZeroStateHelpApp:
+      return true;
+    case AppListSearchResultType::kUnknown:
+    case AppListSearchResultType::kInstalledApp:
+    case AppListSearchResultType::kPlayStoreApp:
+    case AppListSearchResultType::kInstantApp:
+    case AppListSearchResultType::kInternalApp:
+    case AppListSearchResultType::kOmnibox:
+    case AppListSearchResultType::kLauncher:
+    case AppListSearchResultType::kAnswerCard:
+    case AppListSearchResultType::kPlayStoreReinstallApp:
+    case AppListSearchResultType::kArcAppShortcut:
+    case AppListSearchResultType::kFileChip:
+    case AppListSearchResultType::kDriveChip:
+    case AppListSearchResultType::kAssistantChip:
+    case AppListSearchResultType::kOsSettings:
+    case AppListSearchResultType::kInternalPrivacyInfo:
+    case AppListSearchResultType::kAssistantText:
+    case AppListSearchResultType::kHelpApp:
+    case AppListSearchResultType::kFileSearch:
+    case AppListSearchResultType::kDriveSearch:
+    case AppListSearchResultType::kKeyboardShortcut:
+    case AppListSearchResultType::kOpenTab:
+    case AppListSearchResultType::kGames:
+    case AppListSearchResultType::kPersonalization:
+      return false;
+  }
+}
+
 // IconColor -------------------------------------------------------------------
 
 // static
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h
index 4632755..7aba40e 100644
--- a/ash/public/cpp/app_list/app_list_types.h
+++ b/ash/public/cpp/app_list/app_list_types.h
@@ -383,6 +383,11 @@
 ASH_PUBLIC_EXPORT bool IsAppListSearchResultAnApp(
     AppListSearchResultType result_type);
 
+// Returns whether the result type is a type of result shown in launcher
+// continue section when productivity launcher is enabled.
+ASH_PUBLIC_EXPORT bool IsContinueSectionResultType(
+    AppListSearchResultType result_type);
+
 // The different categories a search result can be part of. Every search result
 // to be displayed in the search box should be associated with one category. It
 // is an error for results displayed in the search box to have a kUnknown
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager.cc b/ash/rgb_keyboard/rgb_keyboard_manager.cc
index eabbce4..88974c3e 100644
--- a/ash/rgb_keyboard/rgb_keyboard_manager.cc
+++ b/ash/rgb_keyboard/rgb_keyboard_manager.cc
@@ -22,18 +22,18 @@
 }  // namespace
 
 RgbKeyboardManager::RgbKeyboardManager(ImeControllerImpl* ime_controller)
-    : ime_controller_raw_ptr_(ime_controller) {
-  DCHECK(ime_controller_raw_ptr_);
+    : ime_controller_ptr_(ime_controller) {
+  DCHECK(ime_controller_ptr_);
   DCHECK(!g_instance);
   g_instance = this;
 
-  ime_controller_raw_ptr_->AddObserver(this);
+  ime_controller_ptr_->AddObserver(this);
 
   FetchRgbKeyboardSupport();
 }
 
 RgbKeyboardManager::~RgbKeyboardManager() {
-  ime_controller_raw_ptr_->RemoveObserver(this);
+  ime_controller_ptr_->RemoveObserver(this);
 
   DCHECK_EQ(g_instance, this);
   g_instance = nullptr;
@@ -87,7 +87,7 @@
   // Upon login, CapsLock may already be enabled.
   if (IsRgbKeyboardSupported()) {
     RgbkbdClient::Get()->SetCapsLockState(
-        ime_controller_raw_ptr_->IsCapsLockEnabled());
+        ime_controller_ptr_->IsCapsLockEnabled());
   }
 }
 
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager.h b/ash/rgb_keyboard/rgb_keyboard_manager.h
index ebe0b11..025a558 100644
--- a/ash/rgb_keyboard/rgb_keyboard_manager.h
+++ b/ash/rgb_keyboard/rgb_keyboard_manager.h
@@ -9,6 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/ime/ime_controller_impl.h"
+#include "base/memory/raw_ptr.h"
 #include "chromeos/ash/components/dbus/rgbkbd/rgbkbd_client.h"
 #include "third_party/cros_system_api/dbus/rgbkbd/dbus-constants.h"
 
@@ -50,7 +51,7 @@
   rgbkbd::RgbKeyboardCapabilities capabilities_ =
       rgbkbd::RgbKeyboardCapabilities::kNone;
 
-  ImeControllerImpl* ime_controller_raw_ptr_;
+  raw_ptr<ImeControllerImpl> ime_controller_ptr_;
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc b/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc
index 3304ca9..f98971c 100644
--- a/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc
+++ b/ash/rgb_keyboard/rgb_keyboard_manager_unittest.cc
@@ -9,6 +9,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/ime/ime_controller_impl.h"
+#include "base/memory/raw_ptr.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/ash/components/dbus/rgbkbd/fake_rgbkbd_client.h"
 #include "chromeos/ash/components/dbus/rgbkbd/rgbkbd_client.h"
@@ -43,7 +44,7 @@
   // ImeControllerImpl must be destroyed after RgbKeyboardManager.
   std::unique_ptr<ImeControllerImpl> ime_controller_;
   std::unique_ptr<RgbKeyboardManager> manager_;
-  FakeRgbkbdClient* client_;
+  raw_ptr<FakeRgbkbdClient> client_;
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -134,4 +135,4 @@
   manager_ = std::make_unique<RgbKeyboardManager>(ime_controller_.get());
   EXPECT_TRUE(client_->get_caps_lock_state());
 }
-}  // namespace ash
\ No newline at end of file
+}  // namespace ash
diff --git a/ash/services/secure_channel/connection_attempt_base.h b/ash/services/secure_channel/connection_attempt_base.h
index b5e6e28..d49de7d 100644
--- a/ash/services/secure_channel/connection_attempt_base.h
+++ b/ash/services/secure_channel/connection_attempt_base.h
@@ -153,8 +153,14 @@
   }
 
   void OnConnectToDeviceOperationFailure(FailureDetailType failure_detail) {
-    for (auto& map_entry : id_to_request_map_)
-      map_entry.second->HandleConnectionFailure(failure_detail);
+    // The call to HandleConnectionFailure() will generally remove the item from
+    // the map, so we use a std::map instead of base::flat_map and an idiom that
+    // allows us to safely remove items while iterating.
+    for (auto it = id_to_request_map_.begin();
+         it != id_to_request_map_.end();) {
+      auto it_copy = it++;
+      it_copy->second->HandleConnectionFailure(failure_detail);
+    }
   }
 
   ConnectionPriority GetHighestRemainingConnectionPriority() {
@@ -167,8 +173,8 @@
   }
 
   std::unique_ptr<ConnectToDeviceOperation<FailureDetailType>> operation_;
-  base::flat_map<base::UnguessableToken,
-                 std::unique_ptr<PendingConnectionRequest<FailureDetailType>>>
+  std::map<base::UnguessableToken,
+           std::unique_ptr<PendingConnectionRequest<FailureDetailType>>>
       id_to_request_map_;
 
   base::WeakPtrFactory<ConnectionAttemptBase<FailureDetailType>>
diff --git a/ash/services/secure_channel/connection_attempt_base_unittest.cc b/ash/services/secure_channel/connection_attempt_base_unittest.cc
index 73ce7ec4..0250657 100644
--- a/ash/services/secure_channel/connection_attempt_base_unittest.cc
+++ b/ash/services/secure_channel/connection_attempt_base_unittest.cc
@@ -128,10 +128,11 @@
   }
 
   FakePendingConnectionRequest<BleInitiatorFailureType>* AddNewRequest(
-      ConnectionPriority connection_priority) {
+      ConnectionPriority connection_priority,
+      bool notify_on_failure = false) {
     auto request =
         std::make_unique<FakePendingConnectionRequest<BleInitiatorFailureType>>(
-            connection_attempt_.get(), connection_priority);
+            connection_attempt_.get(), connection_priority, notify_on_failure);
     FakePendingConnectionRequest<BleInitiatorFailureType>* request_raw =
         request.get();
     active_requests_.insert(request_raw);
@@ -361,6 +362,16 @@
   FinishOperationSuccessfully();
 }
 
+TEST_F(SecureChannelConnectionAttemptBaseTest, TwoRequests_FailAndNotify) {
+  // By setting these to "notify on failure" we make sure that we can safely
+  // remove multiple items while iterating in
+  // OnConnectToDeviceOperationFailure().
+  AddNewRequest(ConnectionPriority::kLow, /*notify_on_failure=*/true);
+  AddNewRequest(ConnectionPriority::kLow, /*notify_on_failure=*/true);
+  fake_operation()->OnFailedConnectionAttempt(
+      BleInitiatorFailureType::kAuthenticationError);
+}
+
 TEST_F(SecureChannelConnectionAttemptBaseTest, ManyRequests_UpdatePriority) {
   AddNewRequest(ConnectionPriority::kLow);
   EXPECT_EQ(ConnectionPriority::kLow, fake_operation()->connection_priority());
diff --git a/ash/services/secure_channel/fake_pending_connection_request.h b/ash/services/secure_channel/fake_pending_connection_request.h
index db32ae9..0c5798ce 100644
--- a/ash/services/secure_channel/fake_pending_connection_request.h
+++ b/ash/services/secure_channel/fake_pending_connection_request.h
@@ -22,10 +22,12 @@
     : public PendingConnectionRequest<FailureDetailType> {
  public:
   FakePendingConnectionRequest(PendingConnectionRequestDelegate* delegate,
-                               ConnectionPriority connection_priority)
+                               ConnectionPriority connection_priority,
+                               bool notify_on_failure = false)
       : PendingConnectionRequest<FailureDetailType>(delegate,
                                                     connection_priority),
-        id_(base::UnguessableToken::Create()) {}
+        id_(base::UnguessableToken::Create()),
+        notify_on_failure_(notify_on_failure) {}
 
   FakePendingConnectionRequest(const FakePendingConnectionRequest&) = delete;
   FakePendingConnectionRequest& operator=(const FakePendingConnectionRequest&) =
@@ -53,6 +55,11 @@
   // PendingConnectionRequest<FailureDetailType>:
   void HandleConnectionFailure(FailureDetailType failure_detail) override {
     handled_failure_details_.push_back(failure_detail);
+    if (notify_on_failure_) {
+      NotifyRequestFinishedWithoutConnection(
+          PendingConnectionRequestDelegate::FailedConnectionReason::
+              kRequestFailed);
+    }
   }
 
   std::unique_ptr<ClientConnectionParameters>
@@ -66,6 +73,8 @@
   std::vector<FailureDetailType> handled_failure_details_;
 
   std::unique_ptr<ClientConnectionParameters> client_data_for_extraction_;
+
+  bool notify_on_failure_ = false;
 };
 
 }  // namespace ash::secure_channel
diff --git a/ash/system/network/fake_network_detailed_network_view.cc b/ash/system/network/fake_network_detailed_network_view.cc
index 4cc8cc77..fd4cf99 100644
--- a/ash/system/network/fake_network_detailed_network_view.cc
+++ b/ash/system/network/fake_network_detailed_network_view.cc
@@ -4,14 +4,18 @@
 
 #include "ash/system/network/fake_network_detailed_network_view.h"
 
+#include "ash/system/network/fake_network_list_mobile_header_view.h"
+#include "ash/system/network/fake_network_list_wifi_header_view.h"
 #include "ash/system/network/network_detailed_network_view.h"
 #include "ash/system/network/network_list_item_view.h"
+#include "ash/system/network/network_list_network_item_view.h"
 
 namespace ash {
 
 FakeNetworkDetailedNetworkView::FakeNetworkDetailedNetworkView(
     Delegate* delegate)
-    : NetworkDetailedNetworkView(delegate) {}
+    : NetworkDetailedNetworkView(delegate),
+      network_list_(std::make_unique<views::View>()) {}
 
 FakeNetworkDetailedNetworkView::~FakeNetworkDetailedNetworkView() = default;
 
@@ -23,4 +27,22 @@
   last_clicked_network_list_item_ = static_cast<NetworkListItemView*>(view);
 }
 
+NetworkListNetworkItemView*
+FakeNetworkDetailedNetworkView::AddNetworkListItem() {
+  return network_list_->AddChildView(
+      new NetworkListNetworkItemView(/*listener=*/nullptr));
+};
+
+NetworkListNetworkHeaderView*
+FakeNetworkDetailedNetworkView::AddWifiSectionHeader() {
+  return network_list_->AddChildView(
+      new FakeNetworkListWifiHeaderView(/*delegate=*/nullptr));
+};
+
+NetworkListNetworkHeaderView*
+FakeNetworkDetailedNetworkView::AddMobileSectionHeader() {
+  return network_list_->AddChildView(
+      new FakeNetworkListMobileHeaderView(/*delegate=*/nullptr));
+};
+
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/system/network/fake_network_detailed_network_view.h b/ash/system/network/fake_network_detailed_network_view.h
index b732e3a3..4fbae39 100644
--- a/ash/system/network/fake_network_detailed_network_view.h
+++ b/ash/system/network/fake_network_detailed_network_view.h
@@ -8,6 +8,7 @@
 #include "ash/ash_export.h"
 #include "ash/system/network/network_detailed_network_view.h"
 #include "ash/system/network/network_list_item_view.h"
+#include "ash/system/network/network_list_network_item_view.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -32,10 +33,14 @@
  private:
   // NetworkDetailedNetworkView:
   views::View* GetAsView() override;
+  NetworkListNetworkItemView* AddNetworkListItem() override;
+  NetworkListNetworkHeaderView* AddWifiSectionHeader() override;
+  NetworkListNetworkHeaderView* AddMobileSectionHeader() override;
 
   // ViewClickListener:
   void OnViewClicked(views::View* view) override;
 
+  std::unique_ptr<views::View> network_list_;
   NetworkListItemView* last_clicked_network_list_item_ = nullptr;
 };
 
diff --git a/ash/system/network/network_detailed_network_view.h b/ash/system/network/network_detailed_network_view.h
index f1deff6a..119ebff 100644
--- a/ash/system/network/network_detailed_network_view.h
+++ b/ash/system/network/network_detailed_network_view.h
@@ -7,6 +7,8 @@
 
 #include "ash/ash_export.h"
 #include "ash/system/network/network_detailed_view.h"
+#include "ash/system/network/network_list_network_header_view.h"
+#include "ash/system/network/network_list_network_item_view.h"
 
 namespace ash {
 
@@ -56,10 +58,20 @@
   // when testing, where the implementation might not inherit from views::View.
   virtual views::View* GetAsView() = 0;
 
-  // TODO(b/207089013): Add AddNetworkListItem() when NetworkListNetworkItemView
-  // is available, return NetworkListNetworkItemView*, and also add a function
-  // that creates NetworkListNetworkHeaderView and returns view when
-  // NetworkListNetworkHeaderView is available.
+  // Creates, adds and returns a new network list item. The client is
+  // expected to use the returned pointer for removing and rearranging
+  // the list item.
+  virtual NetworkListNetworkItemView* AddNetworkListItem() = 0;
+
+  // Creates, adds and returns a Wifi sticky sub-header to the end of the
+  // network list. The client is expected to use the returned pointer for
+  // removing and rearranging the sub-header.
+  virtual NetworkListNetworkHeaderView* AddWifiSectionHeader() = 0;
+
+  // Creates, adds and returns a Mobile sticky sub-header to the end of the
+  // network list. The client is expected to use the returned pointer for
+  // removing and rearranging the sub-header.
+  virtual NetworkListNetworkHeaderView* AddMobileSectionHeader() = 0;
 
  protected:
   explicit NetworkDetailedNetworkView(Delegate* delegate);
diff --git a/ash/system/network/network_detailed_network_view_impl.cc b/ash/system/network/network_detailed_network_view_impl.cc
index 118b221..171cff85 100644
--- a/ash/system/network/network_detailed_network_view_impl.cc
+++ b/ash/system/network/network_detailed_network_view_impl.cc
@@ -6,6 +6,9 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/system/network/network_detailed_view.h"
+#include "ash/system/network/network_list_mobile_header_view_impl.h"
+#include "ash/system/network/network_list_network_item_view.h"
+#include "ash/system/network/network_list_wifi_header_view_impl.h"
 #include "ash/system/tray/detailed_view_delegate.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 
@@ -27,6 +30,32 @@
   return this;
 }
 
+NetworkListNetworkItemView*
+NetworkDetailedNetworkViewImpl::AddNetworkListItem() {
+  return scroll_content()->AddChildView(
+      new NetworkListNetworkItemView(/*listener=*/this));
+}
+
+NetworkListNetworkHeaderView*
+NetworkDetailedNetworkViewImpl::AddWifiSectionHeader() {
+  return scroll_content()->AddChildView(
+      new NetworkListWifiHeaderViewImpl(/*delegate=*/this));
+}
+
+NetworkListNetworkHeaderView*
+NetworkDetailedNetworkViewImpl::AddMobileSectionHeader() {
+  return scroll_content()->AddChildView(
+      new NetworkListMobileHeaderViewImpl(/*delegate=*/this));
+}
+
+void NetworkDetailedNetworkViewImpl::OnMobileToggleClicked(bool new_state) {
+  NetworkDetailedNetworkView::delegate()->OnMobileToggleClicked(new_state);
+}
+
+void NetworkDetailedNetworkViewImpl::OnWifiToggleClicked(bool new_state) {
+  NetworkDetailedNetworkView::delegate()->OnWifiToggleClicked(new_state);
+}
+
 BEGIN_METADATA(NetworkDetailedNetworkViewImpl, views::View)
 END_METADATA
 
diff --git a/ash/system/network/network_detailed_network_view_impl.h b/ash/system/network/network_detailed_network_view_impl.h
index d73f3c1..cd40e9ef 100644
--- a/ash/system/network/network_detailed_network_view_impl.h
+++ b/ash/system/network/network_detailed_network_view_impl.h
@@ -8,6 +8,8 @@
 #include "ash/ash_export.h"
 
 #include "ash/system/network/network_detailed_network_view.h"
+#include "ash/system/network/network_list_network_header_view.h"
+#include "ash/system/network/network_list_network_item_view.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 
 namespace ash {
@@ -15,11 +17,10 @@
 class DetailedViewDelegate;
 
 // This class is an implementation for NetworkDetailedNetworkView.
-// TODO(b/207089013): extend and implement
-// NetworkListNetworkHeaderView::Delegate when available.
 class ASH_EXPORT NetworkDetailedNetworkViewImpl
     : public NetworkDetailedView,
-      public NetworkDetailedNetworkView {
+      public NetworkDetailedNetworkView,
+      public NetworkListNetworkHeaderView::Delegate {
  public:
   METADATA_HEADER(NetworkDetailedNetworkViewImpl);
 
@@ -33,8 +34,17 @@
   ~NetworkDetailedNetworkViewImpl() override;
 
  private:
+  friend class NetworkDetailedNetworkViewTest;
+
   // NetworkDetailedNetworkView:
   views::View* GetAsView() override;
+  NetworkListNetworkItemView* AddNetworkListItem() override;
+  NetworkListNetworkHeaderView* AddMobileSectionHeader() override;
+  NetworkListNetworkHeaderView* AddWifiSectionHeader() override;
+
+  // NetworkListNetworkHeaderView::Delegate:
+  void OnMobileToggleClicked(bool new_state) override;
+  void OnWifiToggleClicked(bool new_state) override;
 };
 
 }  // namespace ash
diff --git a/ash/system/network/network_detailed_network_view_unittest.cc b/ash/system/network/network_detailed_network_view_unittest.cc
index f217410..2a9649be 100644
--- a/ash/system/network/network_detailed_network_view_unittest.cc
+++ b/ash/system/network/network_detailed_network_view_unittest.cc
@@ -7,12 +7,90 @@
 #include <memory>
 
 #include "ash/constants/ash_features.h"
+#include "ash/system/network/network_detailed_network_view.h"
+#include "ash/system/network/network_detailed_view.h"
+#include "ash/system/network/network_list_network_header_view.h"
+#include "ash/system/network/network_list_network_item_view.h"
 #include "ash/system/tray/detailed_view_delegate.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/events/event_utils.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 
+namespace {
+
+using chromeos::network_config::CrosNetworkConfigTestHelper;
+
+using chromeos::network_config::mojom::ConnectionStateType;
+using chromeos::network_config::mojom::NetworkStatePropertiesPtr;
+using chromeos::network_config::mojom::NetworkType;
+
+const char kStubCellularDevicePath[] = "/device/stub_cellular_device";
+const char kStubCellularDeviceName[] = "stub_cellular_device";
+
+class FakeNetworkDetailedNetworkViewDelegate
+    : public NetworkDetailedNetworkView::Delegate {
+ public:
+  FakeNetworkDetailedNetworkViewDelegate() = default;
+  ~FakeNetworkDetailedNetworkViewDelegate() override = default;
+
+  bool last_mobile_toggle_state() { return last_mobile_toggle_state_; }
+
+  size_t on_mobile_toggle_clicked_count() {
+    return on_mobile_toggle_clicked_count_;
+  }
+
+  bool last_wifi_toggle_state() { return last_wifi_toggle_state_; }
+
+  size_t on_wifi_toggle_clicked_count() {
+    return on_wifi_toggle_clicked_count_;
+  }
+
+  size_t network_list_item_selected_count() const {
+    return network_list_item_selected_count_;
+  }
+
+ private:
+  // NetworkDetailedView::Delegate:
+  void OnNetworkListItemSelected(
+      const NetworkStatePropertiesPtr& network) override {
+    network_list_item_selected_count_++;
+    last_network_list_item_selected_ = mojo::Clone(network);
+  };
+
+  // NetworkDetailedNetworkView::Delegate:
+  void OnWifiToggleClicked(bool new_state) override {
+    on_wifi_toggle_clicked_count_++;
+    last_wifi_toggle_state_ = new_state;
+  };
+
+  void OnMobileToggleClicked(bool new_state) override {
+    on_mobile_toggle_clicked_count_++;
+    last_mobile_toggle_state_ = new_state;
+  };
+
+  const NetworkStatePropertiesPtr& last_network_list_item_selected() const {
+    return last_network_list_item_selected_;
+  }
+
+  bool last_mobile_toggle_state_ = false;
+  size_t on_mobile_toggle_clicked_count_ = 0;
+
+  bool last_wifi_toggle_state_ = false;
+  size_t on_wifi_toggle_clicked_count_ = 0;
+
+  size_t network_list_item_selected_count_ = 0;
+  NetworkStatePropertiesPtr last_network_list_item_selected_;
+};
+}  // namespace
+
 class NetworkDetailedNetworkViewTest : public AshTestBase {
  public:
   void SetUp() override {
@@ -20,24 +98,125 @@
 
     feature_list_.InitAndEnableFeature(features::kQuickSettingsNetworkRevamp);
 
+    network_state_helper()->ClearDevices();
+
+    network_state_helper()->manager_test()->AddTechnology(shill::kTypeCellular,
+                                                          /*enabled=*/true);
+
+    network_state_helper()->device_test()->AddDevice(
+        kStubCellularDevicePath, shill::kTypeCellular, kStubCellularDeviceName);
+
+    // Wait for network state and device change events to be handled.
+    base::RunLoop().RunUntilIdle();
+
     detailed_view_delegate_ =
         std::make_unique<DetailedViewDelegate>(/*tray_controller=*/nullptr);
+
+    std::unique_ptr<NetworkDetailedNetworkViewImpl>
+        network_detailed_network_view =
+            std::make_unique<NetworkDetailedNetworkViewImpl>(
+                detailed_view_delegate_.get(),
+                &fake_network_detailed_network_delagte_);
+
+    widget_ = CreateFramelessTestWidget();
+    widget_->SetFullscreen(true);
     network_detailed_network_view_ =
-        std::make_unique<NetworkDetailedNetworkViewImpl>(
-            detailed_view_delegate_.get(),
-            /*delegate=*/nullptr);
+        widget_->SetContentsView(std::move(network_detailed_network_view));
   }
 
-  void TearDown() override { AshTestBase::TearDown(); }
+  void TearDown() override {
+    widget_.reset();
+
+    AshTestBase::TearDown();
+  }
+
+  NetworkListNetworkItemView* AddNetworkListItem() {
+    return network_detailed_network_view()->AddNetworkListItem();
+  }
+
+  void NotifyNetworkListChanged() {
+    network_detailed_network_view()->NotifyNetworkListChanged();
+  }
+
+  NetworkListNetworkHeaderView* AddWifiSectionHeader() {
+    return network_detailed_network_view()->AddWifiSectionHeader();
+  }
+
+  NetworkListNetworkHeaderView* AddMobileSectionHeader() {
+    return network_detailed_network_view()->AddMobileSectionHeader();
+  }
+
+  FakeNetworkDetailedNetworkViewDelegate* delegate() {
+    return &fake_network_detailed_network_delagte_;
+  }
+
+  void SimulateMobileToggleClicked(bool new_state) {
+    network_detailed_network_view()->OnMobileToggleClicked(new_state);
+  }
+
+  void SimulateWifiToggleClicked(bool new_state) {
+    network_detailed_network_view()->OnWifiToggleClicked(new_state);
+  }
 
  private:
+  NetworkDetailedNetworkViewImpl* network_detailed_network_view() {
+    return network_detailed_network_view_;
+  }
+
+  chromeos::NetworkStateTestHelper* network_state_helper() {
+    return &network_config_helper_.network_state_helper();
+  }
+
   base::test::ScopedFeatureList feature_list_;
+  std::unique_ptr<views::Widget> widget_;
+  CrosNetworkConfigTestHelper network_config_helper_;
+  FakeNetworkDetailedNetworkViewDelegate fake_network_detailed_network_delagte_;
   std::unique_ptr<DetailedViewDelegate> detailed_view_delegate_;
-  std::unique_ptr<NetworkDetailedNetworkView> network_detailed_network_view_;
+  NetworkDetailedNetworkViewImpl* network_detailed_network_view_;
 };
 
-TEST_F(NetworkDetailedNetworkViewTest, CanConstruct) {
-  EXPECT_TRUE(true);
+TEST_F(NetworkDetailedNetworkViewTest, ViewsAreCreated) {
+  NetworkListNetworkItemView* network_list_item = AddNetworkListItem();
+  ASSERT_NE(nullptr, network_list_item);
+  EXPECT_STREQ("NetworkListNetworkItemView", network_list_item->GetClassName());
+
+  NetworkListNetworkHeaderView* wifi_section = AddWifiSectionHeader();
+  ASSERT_NE(nullptr, wifi_section);
+  EXPECT_STREQ("NetworkListWifiHeaderView", wifi_section->GetClassName());
+
+  NetworkListNetworkHeaderView* mobile_section = AddMobileSectionHeader();
+  ASSERT_NE(nullptr, mobile_section);
+  EXPECT_STREQ("NetworkListMobileHeaderView", mobile_section->GetClassName());
+}
+
+TEST_F(NetworkDetailedNetworkViewTest, ToggleInteractions) {
+  EXPECT_EQ(0u, delegate()->on_mobile_toggle_clicked_count());
+  EXPECT_FALSE(delegate()->last_mobile_toggle_state());
+
+  SimulateMobileToggleClicked(/*new_state=*/true);
+  EXPECT_EQ(1u, delegate()->on_mobile_toggle_clicked_count());
+  EXPECT_TRUE(delegate()->last_mobile_toggle_state());
+
+  EXPECT_EQ(0u, delegate()->on_wifi_toggle_clicked_count());
+  EXPECT_FALSE(delegate()->last_wifi_toggle_state());
+
+  SimulateWifiToggleClicked(/*new_state=*/true);
+  EXPECT_EQ(1u, delegate()->on_wifi_toggle_clicked_count());
+  EXPECT_TRUE(delegate()->last_wifi_toggle_state());
+}
+
+TEST_F(NetworkDetailedNetworkViewTest, ListItemClicked) {
+  EXPECT_EQ(0u, delegate()->network_list_item_selected_count());
+  NetworkListNetworkItemView* network_list_item = AddNetworkListItem();
+  ASSERT_NE(nullptr, network_list_item);
+  NotifyNetworkListChanged();
+  LeftClickOn(network_list_item);
+  EXPECT_EQ(1u, delegate()->network_list_item_selected_count());
+
+  GetSessionControllerClient()->SetSessionState(
+      session_manager::SessionState::LOCKED);
+  LeftClickOn(network_list_item);
+  EXPECT_EQ(1u, delegate()->network_list_item_selected_count());
 }
 
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/system/network/network_detailed_view.cc b/ash/system/network/network_detailed_view.cc
index 46d19cc..181fd8e 100644
--- a/ash/system/network/network_detailed_view.cc
+++ b/ash/system/network/network_detailed_view.cc
@@ -9,6 +9,7 @@
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/model/system_tray_model.h"
+#include "ash/system/network/network_list_item_view.h"
 #include "ash/system/network/tray_network_state_model.h"
 #include "ash/system/tray/detailed_view_delegate.h"
 #include "ash/system/tray/tri_view.h"
@@ -49,9 +50,8 @@
 void NetworkDetailedView::HandleViewClicked(views::View* view) {
   if (login_ == LoginStatus::LOCKED)
     return;
-  // TODO(b/207089013): Call OnNetworkListItemSelected() on delegate() and pass
-  // in a cast of either NetworkListNetworkItemView or NetworkListVPNItemView
-  // when available, also add test for this.
+  delegate()->OnNetworkListItemSelected(
+      static_cast<NetworkListItemView*>(view)->network_properties());
 }
 
 views::View* NetworkDetailedView::network_list() {
diff --git a/ash/system/network/network_list_mobile_header_view.cc b/ash/system/network/network_list_mobile_header_view.cc
index 75e497ac..c2233fd2 100644
--- a/ash/system/network/network_list_mobile_header_view.cc
+++ b/ash/system/network/network_list_mobile_header_view.cc
@@ -6,6 +6,7 @@
 
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/network/network_list_network_header_view.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 
 namespace ash {
 
@@ -16,4 +17,7 @@
 
 NetworkListMobileHeaderView::~NetworkListMobileHeaderView() = default;
 
+BEGIN_METADATA(NetworkListMobileHeaderView, NetworkListNetworkHeaderView)
+END_METADATA
+
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/system/network/network_list_mobile_header_view.h b/ash/system/network/network_list_mobile_header_view.h
index d782704d..62dd6c853 100644
--- a/ash/system/network/network_list_mobile_header_view.h
+++ b/ash/system/network/network_list_mobile_header_view.h
@@ -7,6 +7,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/system/network/network_list_network_header_view.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 
 namespace ash {
 
@@ -15,6 +16,8 @@
 class ASH_EXPORT NetworkListMobileHeaderView
     : public NetworkListNetworkHeaderView {
  public:
+  METADATA_HEADER(NetworkListMobileHeaderView);
+
   explicit NetworkListMobileHeaderView(
       NetworkListNetworkHeaderView::Delegate* delegate);
   NetworkListMobileHeaderView(const NetworkListMobileHeaderView&) = delete;
diff --git a/ash/system/network/network_list_wifi_header_view.cc b/ash/system/network/network_list_wifi_header_view.cc
index da9f4a52..cc51989 100644
--- a/ash/system/network/network_list_wifi_header_view.cc
+++ b/ash/system/network/network_list_wifi_header_view.cc
@@ -6,6 +6,7 @@
 
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/network/network_list_network_header_view.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 
 namespace ash {
 
@@ -16,4 +17,7 @@
 
 NetworkListWifiHeaderView::~NetworkListWifiHeaderView() = default;
 
+BEGIN_METADATA(NetworkListWifiHeaderView, NetworkListNetworkHeaderView)
+END_METADATA
+
 }  // namespace ash
\ No newline at end of file
diff --git a/ash/system/network/network_list_wifi_header_view.h b/ash/system/network/network_list_wifi_header_view.h
index 1443721..40684b1 100644
--- a/ash/system/network/network_list_wifi_header_view.h
+++ b/ash/system/network/network_list_wifi_header_view.h
@@ -7,6 +7,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/system/network/network_list_network_header_view.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
 
 namespace ash {
 
@@ -15,6 +16,8 @@
 class ASH_EXPORT NetworkListWifiHeaderView
     : public NetworkListNetworkHeaderView {
  public:
+  METADATA_HEADER(NetworkListWifiHeaderView);
+
   explicit NetworkListWifiHeaderView(
       NetworkListNetworkHeaderView::Delegate* delegate);
   NetworkListWifiHeaderView(const NetworkListWifiHeaderView&) = delete;
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 76bdf203..bea36c87 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -3283,7 +3283,9 @@
 
 void WallpaperControllerImpl::StartDailyRefreshTimer() {
   base::TimeDelta timer_delay =
-      FuzzTimeDelta(GetTimeToNextDailyRefreshUpdate());
+      features::IsWallpaperFastRefreshEnabled()
+          ? base::Seconds(10)
+          : FuzzTimeDelta(GetTimeToNextDailyRefreshUpdate());
   StartUpdateWallpaperTimer(timer_delay);
 }
 
diff --git a/ash/webui/shimless_rma/resources/base_page.html b/ash/webui/shimless_rma/resources/base_page.html
index b7b78dd6..38dc6121 100644
--- a/ash/webui/shimless_rma/resources/base_page.html
+++ b/ash/webui/shimless_rma/resources/base_page.html
@@ -3,7 +3,8 @@
     align-items: stretch;
     display: flex;
     flex-direction: row;
-    height: 100%;
+    height: calc(var(--window-height) - var(--footer-height)
+        - var(--header-height));
     width: 100%;
   }
 
diff --git a/ash/webui/shimless_rma/resources/base_page.js b/ash/webui/shimless_rma/resources/base_page.js
index f5b011c1..9cf9e9cb 100644
--- a/ash/webui/shimless_rma/resources/base_page.js
+++ b/ash/webui/shimless_rma/resources/base_page.js
@@ -20,6 +20,21 @@
   }
 
   /** @override */
+  constructor() {
+    super();
+
+    /**
+     * This property is used by the CSS to set the height of the right pane.
+     * The height of the right pane needs to be set to a fixed number to make
+     * scrollable regions display properly. This has to be done in javascript
+     * because there is no way to get screen height in CSS.
+     * @type {number}
+     * */
+    const windowHeight = window.innerHeight;
+    this.style.setProperty('--window-height', windowHeight.toString() + 'px');
+  }
+
+  /** @override */
   ready() {
     super.ready();
   }
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.html b/ash/webui/shimless_rma/resources/shimless_rma.html
index e02cf3cad..bc8427a9 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma.html
+++ b/ash/webui/shimless_rma/resources/shimless_rma.html
@@ -12,8 +12,6 @@
 
   #contentContainer {
     flex-grow: 1;
-    /* TODO(longbowei): Update max-height later with specs. */
-    max-height: 600px;
   }
 
   .shimless-content {
@@ -27,7 +25,7 @@
   }
 
   .shimless-header {
-    height: 80px;
+    height: var(--header-height);
   }
 
   #back {
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js
index 23b7f36..1366e7ce 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma.js
+++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -188,8 +188,8 @@
   [State.kWaitForManualWPEnable]: {
     componentIs: 'wrapup-wait-for-manual-wp-enable-page',
     requiresReloadWhenShown: true,
-    buttonNext: ButtonState.DISABLED,
-    buttonCancel: ButtonState.VISIBLE,
+    buttonNext: ButtonState.HIDDEN,
+    buttonCancel: ButtonState.HIDDEN,
     buttonBack: ButtonState.VISIBLE,
   },
   [State.kRestock]: {
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 e3d4b623..d439e2c 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html
+++ b/ash/webui/shimless_rma/resources/shimless_rma_shared_css.html
@@ -4,6 +4,7 @@
       --cr-dialog-width: 320px;
       --cr-dialog-button-container-padding-horizontal: 24px;
       --footer-height: 80px;
+      --header-height: 80px;
       --page-left-margin: 40px;
       --radio-button-top-padding: 20px;
       --title-bottom-margin: 16px;
@@ -175,8 +176,7 @@
     }
 
     .scroll-container {
-      /* TODO(longbowei): Update max-height later with specs. */
-      max-height: 600px;
+      height: 100%;
       overflow: auto;
     }
 
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 3dbe986..4949985 100644
--- a/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html
+++ b/ash/webui/shimless_rma/resources/wrapup_repair_complete_page.html
@@ -3,15 +3,24 @@
     width: 512px;
   }
 
-  #logsDialog [slot=body] {
+  #logsDialog::part(wrapper) {
     height: 480px;
   }
 
-  #logsDialog [slot=footer] {
+  #logsDialog [slot=button-container] {
     padding-bottom: 24px;
     padding-top: 24px;
   }
 
+  #logsDialog [slot=title] {
+    align-items: center;
+    display: flex;
+    font-size: 15px;
+    height: 32px;
+    justify-content: center;
+    padding: 0 24px 0 24px;
+  }
+
   #buttonContainer {
     box-sizing: border-box;
     display: flex;
@@ -217,8 +226,7 @@
     <cr-button id="closeLogDialogButton" on-click="onCancelClick_">
       [[i18n('rmaLogsCancelButtonText')]]
     </cr-button>
-    <cr-button id="rmaLogButton" class="text-button action-button"
-        on-click="onRmaLogButtonClick_">
+    <cr-button id="saveLogDialogButton" class="text-button action-button">
       [[i18n('rmaLogsSaveToUsbButtonText')]]
     </cr-button>
   </div>
diff --git a/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.html b/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.html
index 4047b7b..ad2623a 100644
--- a/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.html
+++ b/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.html
@@ -5,7 +5,7 @@
   <div slot="left-pane">
     <h1>[[i18n('manuallyEnableWpTitleText')]]</h1>
     <div id="manuallyEnableHwwpInstructions" class="instructions">
-      [[getBodyText_(hwwpEnabled_)]]
+      [[i18n('manuallyEnableWpInstructionsText')]]
     </div>
   </div>
 </base-page>
diff --git a/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.js b/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.js
index 127343cd..56cca3e 100644
--- a/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.js
+++ b/ash/webui/shimless_rma/resources/wrapup_wait_for_manual_wp_enable_page.js
@@ -10,7 +10,7 @@
 
 import {getShimlessRmaService} from './mojo_interface_provider.js';
 import {HardwareWriteProtectionStateObserverInterface, HardwareWriteProtectionStateObserverReceiver, ShimlessRmaServiceInterface, StateResult} from './shimless_rma_types.js';
-import {disableNextButton, enableNextButton} from './shimless_rma_util.js';
+import {disableNextButton, enableNextButton, executeThenTransitionState} from './shimless_rma_util.js';
 
 /**
  * @fileoverview
@@ -37,16 +37,6 @@
     return html`{__html_template__}`;
   }
 
-  static get properties() {
-    return {
-      /** @protected */
-      hwwpEnabled_: {
-        type: Boolean,
-        value: false,
-      },
-    };
-  }
-
   constructor() {
     super();
     /** @private {ShimlessRmaServiceInterface} */
@@ -69,36 +59,12 @@
   }
 
   /**
-   * @param {boolean} hwwpEnabled
-   * @return {string}
-   * @protected
-   */
-  getBodyText_(hwwpEnabled) {
-    return this.hwwpEnabled_ ? this.i18n('manuallyEnabledWpMessageText') :
-                               this.i18n('manuallyEnableWpInstructionsText');
-  }
-
-  /**
    * @param {boolean} enabled
    */
   onHardwareWriteProtectionStateChanged(enabled) {
-    this.hwwpEnabled_ = enabled;
-    // TODO(gavindodd): enable/disable next button. Or should it automatically
-    // progress to the next state?
-    if (this.hwwpEnabled_) {
-      enableNextButton(this);
-    } else {
-      disableNextButton(this);
-    }
-  }
-
-  /** @return {!Promise<!StateResult>} */
-  onNextButtonClick() {
-    if (this.hwwpEnabled_) {
-      return this.shimlessRmaService_.writeProtectManuallyEnabled();
-    } else {
-      return Promise.reject(
-          new Error('Hardware Write Protection is not enabled.'));
+    if (enabled) {
+      executeThenTransitionState(
+          this, () => this.shimlessRmaService_.writeProtectManuallyEnabled());
     }
   }
 }
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc
index c6606e1..6c3bc9b 100644
--- a/ash/webui/shimless_rma/shimless_rma.cc
+++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -126,6 +126,8 @@
       // Choose WP disable method page
       {"chooseWpDisableMethodPageTitleText",
        IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE},
+      {"manualWpDisableMethodDescriptionText",
+       IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION},
       {"manualWpDisableMethodOptionText",
        IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION},
       {"rsuWpDisableMethodOptionText",
@@ -250,8 +252,6 @@
       {"manuallyEnableWpTitleText", IDS_SHIMLESS_RMA_MANUALLY_ENABLE_WP_TITLE},
       {"manuallyEnableWpInstructionsText",
        IDS_SHIMLESS_RMA_MANUALLY_ENABLE_WP_INSTRUCTIONS},
-      {"manuallyEnabledWpMessageText",
-       IDS_SHIMLESS_RMA_MANUALLY_ENABLED_WP_MESSAGE},
       // Confirm device information page
       {"confirmDeviceInfoTitle", IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_TITLE},
       {"confirmDeviceInfoInstructions",
@@ -330,10 +330,6 @@
       "welcomeTitleText",
       ui::SubstituteChromeOSDeviceType(IDS_SHIMLESS_RMA_LANDING_PAGE_TITLE));
   html_source->AddString(
-      "manualWpDisableMethodDescriptionText",
-      ui::SubstituteChromeOSDeviceType(
-          IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION));
-  html_source->AddString(
       "criticalErrorTitleText",
       ui::SubstituteChromeOSDeviceType(IDS_SHIMLESS_RMA_CRITICAL_ERROR_TITLE));
   html_source->AddString(
diff --git a/ash/wm/desks/desk.cc b/ash/wm/desks/desk.cc
index d647c5f..3c0e79e 100644
--- a/ash/wm/desks/desk.cc
+++ b/ash/wm/desks/desk.cc
@@ -358,6 +358,14 @@
   return base::AutoReset<bool>(&should_notify_content_changed_, false);
 }
 
+bool Desk::ContainsAppWindows() const {
+  return std::find_if(windows_.begin(), windows_.end(),
+                      [](aura::Window* window) {
+                        return window->GetProperty(aura::client::kAppType) !=
+                               static_cast<int>(AppType::NON_APP);
+                      }) != windows_.end();
+}
+
 void Desk::SetName(std::u16string new_name, bool set_by_user) {
   // Even if the user focuses the DeskNameView for the first time and hits enter
   // without changing the desk's name (i.e. |new_name| is the same,
diff --git a/ash/wm/desks/desk.h b/ash/wm/desks/desk.h
index 6fd4135..77d149a5 100644
--- a/ash/wm/desks/desk.h
+++ b/ash/wm/desks/desk.h
@@ -109,6 +109,8 @@
 
   base::AutoReset<bool> GetScopedNotifyContentChangedDisabler();
 
+  bool ContainsAppWindows() const;
+
   // Sets the desk's name to |new_name| and updates the observers.
   // |set_by_user| should be true if this name was given to the desk by the user
   // from its mini view in overview mode.
diff --git a/ash/wm/desks/desk_action_context_menu.cc b/ash/wm/desks/desk_action_context_menu.cc
index 2e3c983..81fffa45 100644
--- a/ash/wm/desks/desk_action_context_menu.cc
+++ b/ash/wm/desks/desk_action_context_menu.cc
@@ -46,6 +46,10 @@
                                  new_combine_desks_target_name));
 }
 
+void DeskActionContextMenu::SetCombineDesksMenuItemVisibility(bool visible) {
+  context_menu_model_.SetVisibleAt(CommandId::kCombineDesks, visible);
+}
+
 void DeskActionContextMenu::ExecuteCommand(int command_id, int event_flags) {
   switch (command_id) {
     case CommandId::kCombineDesks:
diff --git a/ash/wm/desks/desk_action_context_menu.h b/ash/wm/desks/desk_action_context_menu.h
index 5db089b..cd1703b 100644
--- a/ash/wm/desks/desk_action_context_menu.h
+++ b/ash/wm/desks/desk_action_context_menu.h
@@ -44,11 +44,17 @@
   void UpdateCombineDesksTargetName(
       const std::u16string& new_combine_desks_target_name);
 
+  // Changes the visibility of the combine desks context menu item so that it
+  // can reflect whether there are windows on the desk.
+  void SetCombineDesksMenuItemVisibility(bool visible);
+
   // ui::SimpleMenuModel::Delegate:
   void ExecuteCommand(int command_id, int event_flags) override;
   void MenuClosed(ui::SimpleMenuModel* menu) override;
 
  private:
+  friend class DesksTestApi;
+
   // views::ContextMenuController:
   void ShowContextMenuForViewImpl(views::View* source,
                                   const gfx::Point& point,
diff --git a/ash/wm/desks/desk_action_view.cc b/ash/wm/desks/desk_action_view.cc
index f7fbe17..f67a45f2 100644
--- a/ash/wm/desks/desk_action_view.cc
+++ b/ash/wm/desks/desk_action_view.cc
@@ -56,6 +56,10 @@
       IDS_ASH_DESKS_COMBINE_DESKS_DESCRIPTION, new_combine_desks_target_name));
 }
 
+void DeskActionView::SetCombineDesksButtonVisibility(bool visible) {
+  combine_desks_button_->SetVisible(visible);
+}
+
 BEGIN_METADATA(DeskActionView, views::BoxLayoutView)
 END_METADATA
 
diff --git a/ash/wm/desks/desk_action_view.h b/ash/wm/desks/desk_action_view.h
index 5522f23..07fad1d 100644
--- a/ash/wm/desks/desk_action_view.h
+++ b/ash/wm/desks/desk_action_view.h
@@ -32,6 +32,10 @@
   void UpdateCombineDesksTooltip(
       const std::u16string& new_combine_desks_target_name);
 
+  // Changes the visibility of the combine desks button so that it can reflect
+  // whether there are windows on the desk.
+  void SetCombineDesksButtonVisibility(bool visible);
+
  private:
   CloseButton* combine_desks_button_;
   CloseButton* close_all_button_;
diff --git a/ash/wm/desks/desk_mini_view.cc b/ash/wm/desks/desk_mini_view.cc
index d19af3a..4a72e5d3 100644
--- a/ash/wm/desks/desk_mini_view.cc
+++ b/ash/wm/desks/desk_mini_view.cc
@@ -52,6 +52,15 @@
   return gfx::Rect(origin, screen_rect.size());
 }
 
+// Tells whether `desk` contains an app window itself or if the desk is active
+// and at least one visible on all desk window exists.
+bool ContainsAppWindows(Desk* desk) {
+  if (desk->ContainsAppWindows())
+    return true;
+  return desk->is_active() &&
+         !DesksController::Get()->visible_on_all_desks_windows().empty();
+}
+
 }  // namespace
 
 // -----------------------------------------------------------------------------
@@ -159,20 +168,28 @@
 }
 
 void DeskMiniView::UpdateDeskButtonVisibility() {
+  auto* controller = DesksController::Get();
+
   // Don't show desk buttons when hovered while the dragged window is on
   // the DesksBarView.
   // For switch access, setting desk buttons to visible allows users to
   // navigate to it.
   const bool visible =
-      DesksController::Get()->CanRemoveDesks() &&
-      !owner_bar_->dragged_item_over_bar() && !owner_bar_->IsDraggingDesk() &&
+      controller->CanRemoveDesks() && !owner_bar_->dragged_item_over_bar() &&
+      !owner_bar_->IsDraggingDesk() &&
       (IsMouseHovered() || force_show_desk_buttons_ ||
        Shell::Get()->accessibility_controller()->IsSwitchAccessRunning());
 
-  if (features::IsDesksCloseAllEnabled())
+  if (features::IsDesksCloseAllEnabled()) {
+    // Only show the combine desks button if there are app windows in the desk,
+    // or if the desk is active and there are windows that should be visible on
+    // all desks.
+    desk_action_view_->SetCombineDesksButtonVisibility(
+        ContainsAppWindows(desk_));
     desk_action_view_->SetVisible(visible && !is_context_menu_open_);
-  else
+  } else {
     close_desk_button_->SetVisible(visible);
+  }
 }
 
 void DeskMiniView::OnWidgetGestureTap(const gfx::Rect& screen_rect,
@@ -236,6 +253,11 @@
   // context menu item label for combining desks here to tell the user where the
   // windows will go.
 
+  // Only show the combine desks context menu option if there are app windows in
+  // the desk, or if the desk is active and there are windows that should be
+  // visible on all desks.
+  context_menu_->SetCombineDesksMenuItemVisibility(ContainsAppWindows(desk_));
+
   // TODO(crbug.com/1308780): Source will need to be different when opening with
   // long press and possibly keyboard.
   context_menu_->ShowContextMenuForView(
diff --git a/ash/wm/desks/desks_test_api.cc b/ash/wm/desks/desks_test_api.cc
index 3916068c..b1a9e65 100644
--- a/ash/wm/desks/desks_test_api.cc
+++ b/ash/wm/desks/desks_test_api.cc
@@ -8,6 +8,7 @@
 #include "ash/shell.h"
 #include "ash/system/toast/toast_manager_impl.h"
 #include "ash/wm/desks/desk.h"
+#include "ash/wm/desks/desk_action_context_menu.h"
 #include "ash/wm/desks/desk_mini_view.h"
 #include "ash/wm/desks/desks_bar_view.h"
 #include "ash/wm/desks/desks_restore_util.h"
@@ -100,6 +101,11 @@
 }
 
 // static
+const ui::SimpleMenuModel& DesksTestApi::GetContextMenuModelForDesk(int index) {
+  return GetContextMenuForDesk(index)->context_menu_model_;
+}
+
+// static
 bool DesksTestApi::HasVerticalDotsButton() {
   return GetDesksBarView()->vertical_dots_button_;
 }
diff --git a/ash/wm/desks/desks_test_api.h b/ash/wm/desks/desks_test_api.h
index 75eb8ca..1c90b55b 100644
--- a/ash/wm/desks/desks_test_api.h
+++ b/ash/wm/desks/desks_test_api.h
@@ -15,6 +15,10 @@
 class ScrollView;
 }  // namespace views
 
+namespace ui {
+class SimpleMenuModel;
+}  // namespace ui
+
 namespace ash {
 
 class Desk;
@@ -41,6 +45,7 @@
   GetPersistentDesksBarDeskButtons();
   static DeskActionContextMenu* GetContextMenuForDesk(int index);
   static views::LabelButton* GetCloseAllUndoToastDismissButton();
+  static const ui::SimpleMenuModel& GetContextMenuModelForDesk(int index);
   static bool HasVerticalDotsButton();
   static bool DesksControllerHasDesk(Desk* desk);
   static bool DesksControllerCanUndoDeskRemoval();
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc
index 6410f05..01d5dae 100644
--- a/ash/wm/desks/desks_unittests.cc
+++ b/ash/wm/desks/desks_unittests.cc
@@ -7075,6 +7075,19 @@
         /*event_flags=*/0);
   }
 
+  // Opens the context menu for the mini view at `index`.
+  void OpenContextMenuForMiniView(int index) {
+    ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
+    const DeskPreviewView* desk_preview_view =
+        GetPrimaryRootDesksBarView()->mini_views()[index]->desk_preview();
+    const gfx::Point desk_preview_view_center =
+        desk_preview_view->GetBoundsInScreen().CenterPoint();
+    auto* event_generator = GetEventGenerator();
+    event_generator->MoveMouseTo(desk_preview_view_center);
+    event_generator->ClickRightButton();
+    ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
+  }
+
   // DesksTest:
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(features::kDesksCloseAll);
@@ -7347,6 +7360,50 @@
   }
 }
 
+// Checks that the combine desks button and context menu option are not visible
+// when there are no windows on a desk, and that they are visible on desks with
+// windows.
+TEST_F(DesksCloseAllTest, HideCombineDesksOptionWhenNoWindowsOnDesk) {
+  // Create a new desk with no windows to have an expanded desks bar view with
+  // mini views.
+  NewDesk();
+  EnterOverview();
+  ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
+  CloseButton* combine_desks_button = GetPrimaryRootDesksBarView()
+                                          ->mini_views()[0]
+                                          ->desk_action_view()
+                                          ->combine_desks_button();
+
+  // We need to hover over the desk preview to properly check the combine desks
+  // button's visibility.
+  const DeskPreviewView* desk_preview_view =
+      GetPrimaryRootDesksBarView()->mini_views()[0]->desk_preview();
+  const gfx::Point desk_preview_view_center =
+      desk_preview_view->GetBoundsInScreen().CenterPoint();
+  auto* event_generator = GetEventGenerator();
+  event_generator->MoveMouseTo(desk_preview_view_center);
+  EXPECT_FALSE(combine_desks_button->GetVisible());
+
+  // We need to open the context menu to trigger state change for the combine
+  // desks option in the context menu.
+  OpenContextMenuForMiniView(0);
+  EXPECT_FALSE(DesksTestApi::GetContextMenuModelForDesk(0).IsVisibleAt(
+      DeskActionContextMenu::CommandId::kCombineDesks));
+  GetEventGenerator()->ClickLeftButton();
+
+  // Add a window and check to see if that makes the context option visible for
+  // the desk's action view.
+  auto window = CreateAppWindow();
+  DesksController::Get()->SendToDeskAtIndex(window.get(), 0);
+  EnterOverview();
+  ASSERT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
+  event_generator->MoveMouseTo(desk_preview_view_center);
+  EXPECT_TRUE(combine_desks_button->GetVisible());
+  OpenContextMenuForMiniView(0);
+  EXPECT_TRUE(DesksTestApi::GetContextMenuModelForDesk(0).IsVisibleAt(
+      DeskActionContextMenu::CommandId::kCombineDesks));
+}
+
 // TODO(crbug.com/1308429): Should have tests for opening and closing the
 // DeskActionContextMenu (which should also add and remove the highlight
 // overview on the desk preview).
diff --git a/ash/wm/desks/templates/README.md b/ash/wm/desks/templates/README.md
new file mode 100644
index 0000000..6789214
--- /dev/null
+++ b/ash/wm/desks/templates/README.md
@@ -0,0 +1,76 @@
+# Saved Desks
+
+Saved Desks refers to any features which involve saving the active desk with all
+its applications and then launching the saved desk via a UI in overview mode
+with all its applications in their saved states. There are two such features;
+Desk Templates and Save and Recall. They have a few differences but both involve
+saving a desk and launching it at a later time. Save and Recall is available for
+all users while Desk Templates has to be turned on via policy or a flag: "enable-desks-templates".
+
+[TOC]
+
+## User Journey
+
+#### Overview Mode
+
+The user starts off in overview mode - `ash/wm/overview/`. There are two buttons
+named "Save desk as a template" and "Save desk for later". Both buttons will
+save the active desk and its applications; "Save desk for later", which is Save
+and Recall will additionally close the active desk and all its windows. The
+button will be disabled or hidden if the active desk cannot be saved.
+
+#### Desk Storage Model
+
+Saving a desk triggers a call to the model which serializes and stores the desk.
+The model logic is in `components/desks_storage/`. There are two ways to store
+the desk:
+
+1. Using `DeskSyncBridge` which stores it in the cloud via Chrome Sync.
+2. Using `LocalDeskDataManager` which writes it to a file.
+
+Both models support the same functionalities and are interchangeable from code
+in `ash/` standpoint.
+
+#### Library Page
+
+This is the main UI the user interacts with. It is a page within overview mode
+accessed by pressing the "Library" button on the desks bar. It contains grids
+of items with each item representing one saved desk. The item gives information
+such as time, name and a visual representation of what applications and tabs
+are saved in the form of application icons and tab favicons. Additionally, users
+can use buttons and a textfield on the item to launch, delete or update the
+corresponding saved desks. There are also dialogs and toasts to assist users
+with using the features.
+
+#### Launching Applications
+
+Launching applications is done via `ChromeDesksTemplatesDelegate`, which lives
+in `chrome/`. Launching applications requires dependencies which are forbidden
+in `ash/`, such as app service, profiles and browser code. The delegate is also
+used to communicate to LaCros to launch LaCros browsers if LaCros is enabled.
+
+Launching applications code is shared with the full restore feature. There are
+a couple differences, including:
+
+1. Support to move applications which only support a single instance and are
+   already open.
+2. Browser windows are created from scratch; full restore uses session restore
+   to relaunch browser windows.
+
+Launched templates have an associated `SavedDesk` object, which contains the
+info necessary to launch the associated applications. The info is parsed by the
+model into a `app_restore::RestoreData` object, which is part of the
+`components/app_restore` library. This library is also used by full restore and
+contains the logic to create the application widgets with the correct bounds.
+Just like full restore, additional `ash/` logic like MRU order and window states
+will be handled in `WindowRestoreController`.
+
+## Differences
+
+Though the two features are closely related and share a lot of code, they have a
+couple differences. Desk templates is aimed towards reducing manual setup for
+repetitive tasks, and templates created by an admin. Desks and templates are not
+automatically deleted when using this feature. Save and recall is aimed towards
+picking up where a user left off. Desks are deleted once saved, and templates
+are deleted once launched. This reduces the number of user interactions when
+dealing with the virtual desks limit and the saved desks limit.
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.cc b/ash/wm/desks/templates/desks_templates_grid_view.cc
index 9f0cde65..f0a409c 100644
--- a/ash/wm/desks/templates/desks_templates_grid_view.cc
+++ b/ash/wm/desks/templates/desks_templates_grid_view.cc
@@ -27,6 +27,7 @@
 #include "third_party/icu/source/i18n/unicode/coll.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/aura/window.h"
+#include "ui/aura/window_targeter.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/layer.h"
@@ -89,6 +90,43 @@
 }  // namespace
 
 // -----------------------------------------------------------------------------
+// CustomWindowTargeter:
+
+// A custom targeter that only allows us to handle events which are located on
+// the children of the grid. The grid takes up all the available space in
+// overview, but we still want some events to fall through to the
+// `OverviewGridEventHandler`, if they are not handled by the grid's children.
+class CustomWindowTargeter : public aura::WindowTargeter {
+ public:
+  explicit CustomWindowTargeter(DesksTemplatesGridView* owner)
+      : owner_(owner) {}
+  CustomWindowTargeter(const CustomWindowTargeter&) = delete;
+  CustomWindowTargeter& operator=(const CustomWindowTargeter&) = delete;
+  ~CustomWindowTargeter() override = default;
+
+  // aura::WindowTargeter:
+  bool SubtreeShouldBeExploredForEvent(aura::Window* window,
+                                       const ui::LocatedEvent& event) override {
+    // TODO(dandersson|yongshun): For desk templates this is sufficient, but for
+    // save and recall we may have children that are not buttons, offscreen
+    // children or invisible children.
+    for (views::View* child : owner_->children()) {
+      if (child->GetBoundsInScreen().Contains(event.location())) {
+        return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(window,
+                                                                     event);
+      }
+    }
+
+    // None of the grids' children will handle the event, so `window` won't
+    // handle the event and it will fall through to the wallpaper.
+    return false;
+  }
+
+ private:
+  DesksTemplatesGridView* const owner_;
+};
+
+// -----------------------------------------------------------------------------
 // DesksTemplatesEventHandler:
 
 // This class is owned by DesksTemplatesGridView for the purpose of handling
@@ -317,15 +355,15 @@
   NotifyAccessibilityEvent(ax::mojom::Event::kTreeChanged, true);
 }
 
-DesksTemplatesItemView* DesksTemplatesGridView::GridItemBeingModified() {
+bool DesksTemplatesGridView::IsTemplateNameBeingModified() const {
   if (!GetWidget()->IsActive())
-    return nullptr;
+    return false;
 
   for (auto* grid_item : grid_items_) {
     if (grid_item->IsTemplateNameBeingModified())
-      return grid_item;
+      return true;
   }
-  return nullptr;
+  return false;
 }
 
 void DesksTemplatesGridView::Layout() {
@@ -353,6 +391,8 @@
   widget_window_ = GetWidget()->GetNativeWindow();
   widget_window_->AddObserver(this);
   widget_window_->AddPreTargetHandler(event_handler_.get());
+  widget_window_->SetEventTargeter(
+      std::make_unique<CustomWindowTargeter>(this));
 }
 
 void DesksTemplatesGridView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
@@ -382,21 +422,6 @@
   widget_window_ = nullptr;
 }
 
-bool DesksTemplatesGridView::IntersectsWithFeedbackButton(
-    const gfx::Point& point_in_screen) {
-  return feedback_button_ &&
-         feedback_button_->bounds().Contains(point_in_screen);
-}
-
-bool DesksTemplatesGridView::IntersectsWithGridItem(
-    const gfx::Point& point_in_screen) {
-  for (DesksTemplatesItemView* grid_item : grid_items_) {
-    if (grid_item->bounds().Contains(point_in_screen))
-      return true;
-  }
-  return false;
-}
-
 DesksTemplatesItemView* DesksTemplatesGridView::GetItemForUUID(
     const base::GUID& uuid) {
   if (!uuid.is_valid())
@@ -443,35 +468,6 @@
     default:
       break;
   }
-
-  // If the event is `ui::ET_MOUSE_RELEASED` or `ui::ET_GESTURE_TAP`, it might
-  // be a click/tap outside grid item and feedback button to exit overview or
-  // to commit name changes.
-  if (event->type() == ui::ET_MOUSE_RELEASED ||
-      event->type() == ui::ET_GESTURE_TAP) {
-    DesksTemplatesItemView* grid_item_being_modified = GridItemBeingModified();
-    if (grid_item_being_modified &&
-        !grid_item_being_modified->bounds().Contains(event->location())) {
-      // When there is a desk grid template name being modified, and the
-      // location is outside of the current grid item, commit the name change.
-      DesksTemplatesNameView::CommitChanges(GetWidget());
-      event->StopPropagation();
-      event->SetHandled();
-      return;
-    }
-    if (!grid_item_being_modified &&
-        !IntersectsWithGridItem(event->location()) &&
-        !IntersectsWithFeedbackButton(event->location())) {
-      // When there is no desk grid template name being modified, and the
-      // location does not intersect with any grid item or the feedback button,
-      // exit overview.
-      Shell::Get()->overview_controller()->EndOverview(
-          OverviewEndAction::kClickingOutsideWindowsInOverview);
-      event->StopPropagation();
-      event->SetHandled();
-      return;
-    }
-  }
 }
 
 std::vector<gfx::Rect> DesksTemplatesGridView::CalculateGridItemPositions()
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.h b/ash/wm/desks/templates/desks_templates_grid_view.h
index ecac2ed4..1ac9a60 100644
--- a/ash/wm/desks/templates/desks_templates_grid_view.h
+++ b/ash/wm/desks/templates/desks_templates_grid_view.h
@@ -61,16 +61,9 @@
   // shuffle `grid_items_` to their final positions.
   void DeleteTemplates(const std::vector<std::string>& uuids);
 
-  // Returns the grid item view if there is a template name is being modified,
-  // otherwise returns `nullptr`.
-  DesksTemplatesItemView* GridItemBeingModified();
-
-  // Returns whether the given `point_in_screen` intersects with the feedback
-  // button.
-  bool IntersectsWithFeedbackButton(const gfx::Point& point_in_screen);
-
-  // Returns whether the given `point_in_screen` intersect with any grid item.
-  bool IntersectsWithGridItem(const gfx::Point& point_in_screen);
+  // Returns true if a template name is being modified using an item view's
+  // `DesksTemplatesNameView` in this grid.
+  bool IsTemplateNameBeingModified() const;
 
   // Returns the item view associated with `uuid`.
   DesksTemplatesItemView* GetItemForUUID(const base::GUID& uuid);
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc
index 3a360c25..cae1d1eb 100644
--- a/ash/wm/desks/templates/desks_templates_unittest.cc
+++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -3377,6 +3377,39 @@
   }
 }
 
+// Tests that right clicking on the wallpaper while showing the saved desks grid
+// does not exit overview.
+TEST_F(DesksTemplatesTest, RightClickOnWallpaperStaysInOverview) {
+  AddEntry(base::GUID::GenerateRandomV4(), "template", base::Time::Now(),
+           DeskTemplateType::kTemplate);
+
+  OpenOverviewAndShowTemplatesGrid();
+
+  // Find a point that doesn't touch the item view, but is still in the grid
+  // widget's window bounds. Right clicking this point should not close
+  // overview, as it should open the wallpaper context menu.
+  DesksTemplatesItemView* item_view =
+      GetItemViewFromTemplatesGrid(/*grid_item_index=*/0);
+  DCHECK(item_view);
+  gfx::Rect item_view_expanded_bounds = item_view->GetBoundsInScreen();
+  item_view_expanded_bounds.Outset(40);
+  const gfx::Rect grid_widget_bounds = GetOverviewGridList()[0]
+                                           ->desks_templates_grid_widget()
+                                           ->GetWindowBoundsInScreen();
+  ASSERT_TRUE(grid_widget_bounds.Contains(item_view_expanded_bounds));
+
+  auto* event_generator = GetEventGenerator();
+  event_generator->MoveMouseTo(item_view_expanded_bounds.bottom_right());
+  event_generator->ClickRightButton();
+  ASSERT_TRUE(InOverviewSession());
+
+  // Left click twice to exit overview, once to close the context menu and once
+  // to do the actual exiting.
+  event_generator->ClickLeftButton();
+  event_generator->ClickLeftButton();
+  EXPECT_FALSE(InOverviewSession());
+}
+
 // Tests that if there is an existing visible on all desks window, after
 // launching a new desk the window is part of the new desk and is in an overview
 // item.
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index cdb3f38..4397b76 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -1803,7 +1803,7 @@
 
 bool OverviewGrid::IsTemplateNameBeingModified() const {
   return desks_templates_grid_view_ &&
-         desks_templates_grid_view_->GridItemBeingModified();
+         desks_templates_grid_view_->IsTemplateNameBeingModified();
 }
 
 void OverviewGrid::UpdateNoWindowsWidget(bool no_items) {
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 0131bc1a..194828a 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -303,7 +303,6 @@
     "debug/stack_trace.h",
     "debug/task_trace.cc",
     "debug/task_trace.h",
-    "enterprise_util.h",
     "environment.cc",
     "environment.h",
     "export_template.h",
@@ -1020,6 +1019,8 @@
       "debug/invalid_access_win.cc",
       "debug/invalid_access_win.h",
       "debug/stack_trace_win.cc",
+      "enterprise_util.cc",
+      "enterprise_util.h",
       "enterprise_util_win.cc",
       "file_version_info_win.cc",
       "file_version_info_win.h",
@@ -1189,6 +1190,8 @@
       "allocator/allocator_interception_mac.mm",
       "allocator/malloc_zone_functions_mac.cc",
       "allocator/malloc_zone_functions_mac.h",
+      "enterprise_util.cc",
+      "enterprise_util.h",
       "enterprise_util_mac.mm",
       "file_version_info_mac.h",
       "file_version_info_mac.mm",
@@ -3565,7 +3568,6 @@
       "test/launcher/test_results_tracker_unittest.cc",
     ]
     deps += [
-      ":base_java",
       ":base_java_unittest_support",
       "//base/test:test_support_java",
     ]
@@ -4457,7 +4459,6 @@
     annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
     ]
diff --git a/base/allocator/partition_allocator/BUILD.gn b/base/allocator/partition_allocator/BUILD.gn
index 96eeb47..ad6bcf1 100644
--- a/base/allocator/partition_allocator/BUILD.gn
+++ b/base/allocator/partition_allocator/BUILD.gn
@@ -224,7 +224,10 @@
     "//build:chromeos_buildflags",
     "//build/config/compiler:compiler_buildflags",
   ]
-  deps = []
+
+  # TODO(https://crbug.com/1151236): Remove this dependency on Abseil once PA
+  # no longer includes any headers directly from base/.
+  deps = [ "//third_party/abseil-cpp:absl" ]
   configs += [
     ":partition_alloc_implementation",
     ":memory_tagging",
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index f8e5adcc..24d9d98 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -246,13 +246,13 @@
         int target = ContextUtils.getApplicationContext().getApplicationInfo().targetSdkVersion;
 
         // Logic for pre-API-finalization:
-        return BuildCompat.isAtLeastT() && target == Build.VERSION_CODES.CUR_DEVELOPMENT;
+        // return BuildCompat.isAtLeastT() && target == Build.VERSION_CODES.CUR_DEVELOPMENT;
 
         // Logic for smooth transition period so that both pre-finalization and final SDKs
         // will return true, assuming T will be API 33.
         // Keeping this until we upstream the public SDK is a reasonable transition period.
-        // return target >= 33 ||
-        //         (BuildCompat.isAtLeastT() && target == Build.VERSION_CODES.CUR_DEVELOPMENT);
+        return target >= 33 ||
+                (BuildCompat.isAtLeastT() && target == Build.VERSION_CODES.CUR_DEVELOPMENT);
 
         // Logic for public SDK release:
         // return target >= Build.VERSION_CODES.TIRAMISU;
diff --git a/base/android/java/src/org/chromium/base/FeatureList.java b/base/android/java/src/org/chromium/base/FeatureList.java
index 925896c..9039f07 100644
--- a/base/android/java/src/org/chromium/base/FeatureList.java
+++ b/base/android/java/src/org/chromium/base/FeatureList.java
@@ -164,7 +164,10 @@
                 return override;
             }
             if (!sTestCanUseDefaults) {
-                throw new IllegalArgumentException("No test value configured for " + featureName);
+                throw new IllegalArgumentException("No test value configured for " + featureName
+                        + " and native is not available to provide a default value. Use"
+                        + " @EnableFeatures or @DisableFeatures to provide test values for the"
+                        + " flag.");
             }
         }
         return null;
diff --git a/base/android/jni_generator/BUILD.gn b/base/android/jni_generator/BUILD.gn
index 0e9e9a83..06f32dfa 100644
--- a/base/android/jni_generator/BUILD.gn
+++ b/base/android/jni_generator/BUILD.gn
@@ -21,7 +21,6 @@
   ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
@@ -33,7 +32,6 @@
   sources = [ "java/src/org/chromium/example/jni_generator/SampleForAnnotationProcessor.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
@@ -70,7 +68,6 @@
   android_manifest = "AndroidManifest.xml"
   deps = [
     ":jni_sample_java",
-    "//base:base_java",
     "//build/android:build_java",
   ]
   shared_libraries = [ ":jni_sample_lib" ]
diff --git a/base/debug/stack_trace.cc b/base/debug/stack_trace.cc
index 6a5bb4b..730fada 100644
--- a/base/debug/stack_trace.cc
+++ b/base/debug/stack_trace.cc
@@ -307,64 +307,27 @@
   return address >= range.start && address <= range.end;
 }
 
-size_t TraceStackFramePointersInternal(
-    absl::optional<uintptr_t> fp,
+// We force this function to be inlined into its callers (e.g.
+// TraceStackFramePointers()) in all build modes so we don't have to worry about
+// conditionally skipping a frame based on potential inlining or tail calls.
+__attribute__((always_inline)) size_t TraceStackFramePointersInternal(
+    uintptr_t fp,
     uintptr_t stack_end,
     size_t max_depth,
     size_t skip_initial,
     bool enable_scanning,
-    absl::optional<AddressRange> caller_function_range,
     const void** out_trace) {
-  // If |fp| is not provided then try to unwind the current stack. In this case
-  // the caller function cannot pass in it's own frame pointer to unwind
-  // because the frame pointer may not be valid here. The compiler can optimize
-  // the tail function call from the caller to skip to the previous frame of the
-  // caller directly, making it's frame pointer invalid when we reach this
-  // function.
-  if (!fp) {
-    // Usage of __builtin_frame_address() enables frame pointers in this
-    // function even if they are not enabled globally. So 'fp' will always
-    // be valid.
-    fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) -
-         kStackFrameAdjustment;
-  }
-
   size_t depth = 0;
   while (depth < max_depth) {
-    uintptr_t pc = GetStackFramePC(*fp);
-    // Case 1: If we are unwinding on a copied stack, then
-    // |caller_function_range| will not exist.
-    //
-    // Case 2: If we are unwinding the current stack from this function's frame,
-    // the next frame could be either the caller (TraceStackFramePointers()) or
-    // the function that called TraceStackFramePointers() (say Fn()).
-    //
-    // 2a. If the current function (depending on optimization of the build) is
-    // inlined, or the tail call to this function from TraceStackFramePointers()
-    // causes the frame pointer to skip directly to Fn(), the stack will look
-    // like this:
-    //    1st Frame: TraceStackFramePointersInternal()
-    //               TraceStackFramePointers() has no frame
-    //    2nd Frame: Fn()
-    //    ...
-    //  In this case we do not want to skip the caller from the output.
-    //
-    //  2b. Otherwise the stack will look like this:
-    //    1st Frame: TraceStackFramePointersInternal()
-    //    2nd Frame: <stack space of TraceStackFramePointers()>   <- Skip
-    //    3rd Frame: Fn()
-    //  In this case, the next pc will be within the caller function's
-    //  addresses, so skip the frame.
-    if (!caller_function_range || !IsWithinRange(pc, *caller_function_range)) {
-      if (skip_initial != 0) {
-        skip_initial--;
-      } else {
-        out_trace[depth++] = reinterpret_cast<const void*>(pc);
-      }
+    uintptr_t pc = GetStackFramePC(fp);
+    if (skip_initial != 0) {
+      skip_initial--;
+    } else {
+      out_trace[depth++] = reinterpret_cast<const void*>(pc);
     }
 
-    uintptr_t next_fp = GetNextStackFrame(*fp);
-    if (IsStackFrameValid(next_fp, *fp, stack_end)) {
+    uintptr_t next_fp = GetNextStackFrame(fp);
+    if (IsStackFrameValid(next_fp, fp, stack_end)) {
       fp = next_fp;
       continue;
     }
@@ -372,7 +335,7 @@
     if (!enable_scanning)
       break;
 
-    next_fp = ScanStackForNextFrame(*fp, stack_end);
+    next_fp = ScanStackForNextFrame(fp, stack_end);
     if (next_fp) {
       fp = next_fp;
     } else {
@@ -383,35 +346,24 @@
   return depth;
 }
 
-size_t TraceStackFramePointers(const void** out_trace,
-                               size_t max_depth,
-                               size_t skip_initial,
-                               bool enable_scanning) {
-  // This function's frame can be skipped by the compiler since the callee
-  // function can jump to caller of this function directly while execution.
-  // Since there is no way to guarantee that the first frame the trace stack
-  // function finds will be this function or the previous function, skip the
-  // current function if it is found.
-TraceStackFramePointers_start:
-  AddressRange current_fn_range = {
-      reinterpret_cast<uintptr_t>(&&TraceStackFramePointers_start),
-      reinterpret_cast<uintptr_t>(&&TraceStackFramePointers_end)};
-  size_t depth = TraceStackFramePointersInternal(
-      /*fp=*/absl::nullopt, GetStackEnd(), max_depth, skip_initial,
-      enable_scanning, current_fn_range, out_trace);
-TraceStackFramePointers_end:
-  return depth;
+NOINLINE size_t TraceStackFramePointers(const void** out_trace,
+                                        size_t max_depth,
+                                        size_t skip_initial,
+                                        bool enable_scanning) {
+  return TraceStackFramePointersInternal(
+      reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) -
+          kStackFrameAdjustment,
+      GetStackEnd(), max_depth, skip_initial, enable_scanning, out_trace);
 }
 
-size_t TraceStackFramePointersFromBuffer(uintptr_t fp,
-                                         uintptr_t stack_end,
-                                         const void** out_trace,
-                                         size_t max_depth,
-                                         size_t skip_initial,
-                                         bool enable_scanning) {
+NOINLINE size_t TraceStackFramePointersFromBuffer(uintptr_t fp,
+                                                  uintptr_t stack_end,
+                                                  const void** out_trace,
+                                                  size_t max_depth,
+                                                  size_t skip_initial,
+                                                  bool enable_scanning) {
   return TraceStackFramePointersInternal(fp, stack_end, max_depth, skip_initial,
-                                         enable_scanning, absl::nullopt,
-                                         out_trace);
+                                         enable_scanning, out_trace);
 }
 
 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp)
diff --git a/base/enterprise_util.cc b/base/enterprise_util.cc
new file mode 100644
index 0000000..cf2f8d4
--- /dev/null
+++ b/base/enterprise_util.cc
@@ -0,0 +1,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.
+
+#include "base/enterprise_util.h"
+
+namespace base {
+
+bool IsManagedOrEnterpriseDevice() {
+  return IsManagedDevice() || IsEnterpriseDevice();
+}
+
+}  // namespace base
diff --git a/base/enterprise_util.h b/base/enterprise_util.h
index 47d3d7c..8952695 100644
--- a/base/enterprise_util.h
+++ b/base/enterprise_util.h
@@ -10,11 +10,27 @@
 
 namespace base {
 
-// Returns true if an outside entity manages the current machine. This includes
-// but is not limited to the presence of user accounts from a centralized
-// directory or the presence of dynamically updatable machine policies from an
-// outside administrator.
-BASE_EXPORT bool IsMachineExternallyManaged();
+// Returns true if an outside entity manages the current machine. To be
+// "managed" means that an entity such as a company or school is applying
+// policies to this device. This is primarily checking the device for MDM
+// management.
+// Not all managed devices are enterprise devices, as BYOD (bring your own
+// device) is becoming more common in connection with workplace joining of
+// personal computers.
+BASE_EXPORT bool IsManagedDevice();
+
+// Returns true if the device should be considered an enterprise device. To be
+// an enterprise device means that the enterprise actually owns or has complete
+// control over a device. This is primarily checking if the device is joined to
+// a domain.
+// Not all enterprise devices are managed devices because not all enterprises
+// actually apply policies to all devices.
+BASE_EXPORT bool IsEnterpriseDevice();
+
+// Returns true if the device is either managed or enterprise. In general, it is
+// recommended to use the PlatformManagementService to obtain this information,
+// if possible.
+BASE_EXPORT bool IsManagedOrEnterpriseDevice();
 
 #if BUILDFLAG(IS_APPLE)
 
diff --git a/base/enterprise_util_mac.mm b/base/enterprise_util_mac.mm
index bbb851e1..dd14c8cf 100644
--- a/base/enterprise_util_mac.mm
+++ b/base/enterprise_util_mac.mm
@@ -18,7 +18,28 @@
 
 namespace base {
 
-bool IsMachineExternallyManaged() {
+bool IsManagedDevice() {
+  // MDM enrollment indicates the device is actively being managed. Simply being
+  // joined to a domain, however, does not.
+
+  // IsDeviceRegisteredWithManagementNew is only available after 10.13.4.
+  // Eventually switch to it when that is the minimum OS required by Chromium.
+  if (@available(macOS 10.13.4, *)) {
+    base::MacDeviceManagementStateNew mdm_state =
+        base::IsDeviceRegisteredWithManagementNew();
+    return mdm_state ==
+               base::MacDeviceManagementStateNew::kLimitedMDMEnrollment ||
+           mdm_state == base::MacDeviceManagementStateNew::kFullMDMEnrollment ||
+           mdm_state == base::MacDeviceManagementStateNew::kDEPMDMEnrollment;
+  }
+
+  base::MacDeviceManagementStateOld mdm_state =
+      base::IsDeviceRegisteredWithManagementOld();
+  return mdm_state == base::MacDeviceManagementStateOld::kMDMEnrollment;
+}
+
+bool IsEnterpriseDevice() {
+  // Domain join is a basic indicator of being an enterprise device.
   DeviceUserDomainJoinState join_state = AreDeviceAndUserJoinedToDomain();
   return join_state.device_joined || join_state.user_joined;
 }
diff --git a/base/enterprise_util_win.cc b/base/enterprise_util_win.cc
index be378bf..96979ac 100644
--- a/base/enterprise_util_win.cc
+++ b/base/enterprise_util_win.cc
@@ -5,17 +5,30 @@
 #include "base/enterprise_util.h"
 
 #include "base/win/win_util.h"
+#include "base/win/windows_version.h"
 
 namespace base {
 
-bool IsMachineExternallyManaged() {
-  // TODO(rogerta): this function should really be:
-  //
-  //    return IsEnrolledToDomain() || IsDeviceRegisteredWithManagement();
-  //
-  // However, for now it is decided to collect some UMA metrics about
-  // IsDeviceRegisteredWithMdm() before changing chrome's behavior.
-  return base::win::IsEnrolledToDomain();
+bool IsManagedDevice() {
+  // Legacy domain join does not actually guarantee that the device is managed,
+  // however there is no API that can be used to determine if any group policies
+  // are actually being applied. As such, for these devices we need to assume
+  // they are managed.
+  // IsDeviceRegisteredWithManagement() can be true for devices running the Home
+  // sku, however the Home sku does not allow for management of the web browser.
+  // As such, we only include devices running a non-Home sku.
+  // In addition, simply being joined to AAD does not mean the device is being
+  // managed by the AAD tenant, so checking for AAD join is not included here.
+  return base::win::IsEnrolledToDomain() ||
+         (base::win::IsDeviceRegisteredWithManagement() &&
+          (base::win::OSInfo::GetInstance()->version_type() !=
+           base::win::SUITE_HOME));
+}
+
+bool IsEnterpriseDevice() {
+  // Both legacy domain join and AAD join represent machine-wide enterprise
+  // join.
+  return base::win::IsEnrolledToDomain() || base::win::IsJoinedToAzureAD();
 }
 
 }  // namespace base
diff --git a/base/memory/ref_counted.h b/base/memory/ref_counted.h
index 45a9d4d8..3b89240 100644
--- a/base/memory/ref_counted.h
+++ b/base/memory/ref_counted.h
@@ -21,6 +21,7 @@
 #include "base/template_util.h"
 #include "base/threading/thread_collision_warner.h"
 #include "build/build_config.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace base {
 namespace subtle {
@@ -441,7 +442,7 @@
   RefCountedData(const T& in_value) : data(in_value) {}
   RefCountedData(T&& in_value) : data(std::move(in_value)) {}
   template <typename... Args>
-  explicit RefCountedData(in_place_t, Args&&... args)
+  explicit RefCountedData(absl::in_place_t, Args&&... args)
       : data(std::forward<Args>(args)...) {}
 
   T data;
diff --git a/base/optional_unittest.cc b/base/optional_unittest.cc
index 1511465..2c4d9cd 100644
--- a/base/optional_unittest.cc
+++ b/base/optional_unittest.cc
@@ -13,6 +13,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using ::testing::ElementsAre;
 
@@ -535,7 +536,7 @@
       Test(const Test& param) : param_type(ParamType::COPY_CONSTRUCTED) {}
       Test(Test&& param) : param_type(ParamType::MOVE_CONSTRUCTED) {}
       explicit Test(int param) : param_type(ParamType::INT) {}
-      explicit Test(in_place_t param) : param_type(ParamType::IN_PLACE) {}
+      explicit Test(absl::in_place_t param) : param_type(ParamType::IN_PLACE) {}
       explicit Test(absl::optional<int> param)
           : param_type(ParamType::OPTIONAL_INT) {}
 
diff --git a/base/template_util.h b/base/template_util.h
index 2c4793c..5bde37c 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -59,35 +59,6 @@
 
 }  // namespace internal
 
-// base::in_place_t is an implementation of std::in_place_t from
-// C++17. A tag type used to request in-place construction in template vararg
-// constructors.
-
-// Specification:
-// https://en.cppreference.com/w/cpp/utility/in_place
-struct in_place_t {};
-constexpr in_place_t in_place = {};
-
-// base::in_place_type_t is an implementation of std::in_place_type_t from
-// C++17. A tag type used for in-place construction when the type to construct
-// needs to be specified, such as with base::unique_any, designed to be a
-// drop-in replacement.
-
-// Specification:
-// http://en.cppreference.com/w/cpp/utility/in_place
-template <typename T>
-struct in_place_type_t {};
-
-template <typename T>
-struct is_in_place_type_t {
-  static constexpr bool value = false;
-};
-
-template <typename... Ts>
-struct is_in_place_type_t<in_place_type_t<Ts...>> {
-  static constexpr bool value = true;
-};
-
 namespace internal {
 
 // The indirection with std::is_enum<T> is required, because instantiating
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 454fe05..e2cf909 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -3998,7 +3998,6 @@
 
       if (!defined(use_default_launcher) || use_default_launcher) {
         deps += [
-          "//base:base_java",
           "//build/android:build_java",
           "//build/android/gtest_apk:native_test_instrumentation_test_runner_java",
           "//testing/android/native_test:native_test_java",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 6036aca..694ad07 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8.20220503.1.1
+8.20220503.2.1
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 6036aca..694ad07 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-8.20220503.1.1
+8.20220503.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 6036aca..694ad07 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8.20220503.1.1
+8.20220503.2.1
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 091ec28..f3f6fa79 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -993,9 +993,6 @@
     # Right now, this only includes the Java switches. But if we need more Java
     # files, they should be added here as necessary.
     srcjar_deps = [ ":cc_android_java_enums_srcjar" ]
-    deps = [
-      "//base:base_java",
-      "//third_party/androidx:androidx_annotation_annotation_java",
-    ]
+    deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
   }
 }
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc
index 0a83b75..7fdce72 100644
--- a/cc/paint/image_transfer_cache_entry.cc
+++ b/cc/paint/image_transfer_cache_entry.cc
@@ -296,7 +296,8 @@
   // 4-byte boundary.
   safe_size += 4;
   safe_size += pixmap_->computeByteSize();
-  size_ = safe_size.ValueOrDefault(0);
+  size_ = base::bits::AlignUp(safe_size.ValueOrDefault(0),
+                              PaintOpWriter::Alignment());
 }
 
 ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
@@ -345,7 +346,8 @@
   safe_size += decoded_color_space_size + align;  // SkColorSpace for YUVA image
   for (size_t i = 0; i < num_yuva_pixmaps; ++i)
     safe_size += SafeSizeForPixmap(*yuv_pixmaps_->at(i));
-  size_ = safe_size.ValueOrDefault(0);
+  size_ = base::bits::AlignUp(safe_size.ValueOrDefault(0),
+                              PaintOpWriter::Alignment());
 }
 
 ClientImageTransferCacheEntry::~ClientImageTransferCacheEntry() = default;
diff --git a/cc/paint/paint_filter.cc b/cc/paint/paint_filter.cc
index 5012490..705aa95 100644
--- a/cc/paint/paint_filter.cc
+++ b/cc/paint/paint_filter.cc
@@ -671,7 +671,8 @@
 size_t AlphaThresholdPaintFilter::SerializedSize() const {
   size_t region_size = region_.writeToMemory(nullptr);
   base::CheckedNumeric<size_t> total_size;
-  total_size = BaseSerializedSize() + sizeof(uint64_t) + region_size +
+  total_size = BaseSerializedSize() + sizeof(uint64_t) +
+               base::bits::AlignUp(region_size, PaintOpWriter::Alignment()) +
                sizeof(inner_min_) + sizeof(outer_max_);
   total_size += GetFilterSize(input_.get());
   return total_size.ValueOrDefault(0u);
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 9583522..577424a 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -571,7 +571,7 @@
   helper.Write(
       CreateDrawImage(op->image, flags_to_serialize, op->sampling, current_ctm),
       &scale_adjustment);
-  helper.AlignMemory(alignof(SkScalar));
+  helper.AssertAlignment(alignof(SkScalar));
   helper.Write(scale_adjustment.width());
   helper.Write(scale_adjustment.height());
 
@@ -602,7 +602,7 @@
   helper.Write(
       CreateDrawImage(op->image, flags_to_serialize, op->sampling, matrix),
       &scale_adjustment);
-  helper.AlignMemory(alignof(SkScalar));
+  helper.AssertAlignment(alignof(SkScalar));
   helper.Write(scale_adjustment.width());
   helper.Write(scale_adjustment.height());
 
@@ -641,7 +641,7 @@
   if (!flags_to_serialize)
     flags_to_serialize = &op->flags;
   helper.Write(*flags_to_serialize, current_ctm);
-  helper.AlignMemory(alignof(SkScalar));
+  helper.AssertAlignment(alignof(SkScalar));
   helper.Write(op->x0);
   helper.Write(op->y0);
   helper.Write(op->x1);
@@ -1017,7 +1017,7 @@
 
   void ReadSize(size_t* size) { reader_.ReadSize(size); }
 
-  void AlignMemory(size_t alignment) { reader_.AlignMemory(alignment); }
+  void AssertAlignment(size_t alignment) { reader_.AssertAlignment(alignment); }
 
  private:
   PaintOpReader reader_;
@@ -1144,7 +1144,7 @@
   deserializer.Read(&deserializer->flags);
 
   deserializer.Read(&deserializer->image);
-  deserializer.AlignMemory(alignof(SkScalar));
+  deserializer.AssertAlignment(alignof(SkScalar));
   deserializer.Read(&deserializer->scale_adjustment.fWidth);
   deserializer.Read(&deserializer->scale_adjustment.fHeight);
 
@@ -1165,7 +1165,7 @@
   deserializer.Read(&deserializer->flags);
 
   deserializer.Read(&deserializer->image);
-  deserializer.AlignMemory(alignof(SkScalar));
+  deserializer.AssertAlignment(alignof(SkScalar));
   deserializer.Read(&deserializer->scale_adjustment.fWidth);
   deserializer.Read(&deserializer->scale_adjustment.fHeight);
 
@@ -1198,7 +1198,7 @@
   PaintOpDeserializer<DrawLineOp> deserializer(input, input_size, options,
                                                new (output) DrawLineOp);
   deserializer.Read(&deserializer->flags);
-  deserializer.AlignMemory(alignof(SkScalar));
+  deserializer.AssertAlignment(alignof(SkScalar));
   deserializer.Read(&deserializer->x0);
   deserializer.Read(&deserializer->y0);
   deserializer.Read(&deserializer->x1);
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc
index dc0597d..b80958f7 100644
--- a/cc/paint/paint_op_buffer_unittest.cc
+++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -1961,6 +1961,8 @@
         "%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), op_idx));
     size_t expected_bytes = bytes_written[op_idx];
     EXPECT_GT(expected_bytes, 0u);
+    EXPECT_EQ(expected_bytes,
+              base::bits::AlignUp(expected_bytes, PaintOpWriter::Alignment()));
 
     // Attempt to write op into a buffer of size |i|, and only expect
     // it to succeed if the buffer is large enough.
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc
index 5da7a30..223d78e0 100644
--- a/cc/paint/paint_op_reader.cc
+++ b/cc/paint/paint_op_reader.cc
@@ -88,14 +88,15 @@
 void PaintOpReader::ReadSimple(T* val) {
   static_assert(std::is_trivially_copyable_v<T>);
 
+  DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
   // Align everything to 4 bytes, as the writer does.
-  static constexpr size_t kAlign = 4;
-  size_t size = base::bits::AlignUp(sizeof(T), kAlign);
+  static constexpr size_t size =
+      base::bits::AlignUp(sizeof(T), PaintOpWriter::Alignment());
 
-  if (remaining_bytes_ < size)
+  if (remaining_bytes_ < size) {
     SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadSimple);
-  if (!valid_)
     return;
+  }
 
   // Most of the time this is used for primitives, but this function is also
   // used for SkRect/SkIRect/SkMatrix whose implicit operator= can't use a
@@ -124,34 +125,37 @@
     DeserializationError error_on_factory_failure) {
   size_t bytes = 0;
   ReadSize(&bytes);
-  if (remaining_bytes_ < bytes)
+  if (remaining_bytes_ < bytes) {
     SetInvalid(
         DeserializationError::kInsufficientRemainingBytes_ReadFlattenable);
-  if (!valid_)
     return;
+  }
+
   if (bytes == 0)
     return;
 
   auto* scratch = CopyScratchSpace(bytes);
   val->reset(factory(scratch, bytes, nullptr).release());
-  if (!val)
+  if (!val) {
     SetInvalid(error_on_factory_failure);
+    return;
+  }
 
-  memory_ += bytes;
-  remaining_bytes_ -= bytes;
+  DidRead(bytes);
 }
 
 void PaintOpReader::ReadData(size_t bytes, void* data) {
-  if (remaining_bytes_ < bytes)
-    SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadData);
-  if (!valid_)
-    return;
+  DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
   if (bytes == 0)
     return;
 
+  if (remaining_bytes_ < bytes) {
+    SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadData);
+    return;
+  }
+
   memcpy(data, const_cast<const char*>(memory_), bytes);
-  memory_ += bytes;
-  remaining_bytes_ -= bytes;
+  DidRead(bytes);
 }
 
 void PaintOpReader::ReadSize(size_t* size) {
@@ -241,8 +245,7 @@
         // do any caching either.
         path->setIsVolatile(true);
       }
-      memory_ += path_bytes;
-      remaining_bytes_ -= path_bytes;
+      DidRead(path_bytes);
       return;
     }
   }
@@ -435,9 +438,7 @@
 
   // This is safe to cast away the volatile as it is just a memcpy internally.
   *data = SkData::MakeWithCopy(const_cast<const char*>(memory_), bytes);
-
-  memory_ += bytes;
-  remaining_bytes_ -= bytes;
+  DidRead(bytes);
 }
 
 void PaintOpReader::Read(sk_sp<SkColorSpace>* color_space) {
@@ -454,16 +455,14 @@
   if (!color_space)
     SetInvalid(DeserializationError::kSkColorSpaceDeserializeFailure);
 
-  memory_ += size;
-  remaining_bytes_ -= size;
+  DidRead(size);
 }
 
 void PaintOpReader::Read(sk_sp<GrSlug>* slug) {
-  AlignMemory(4);
+  AssertAlignment(PaintOpWriter::Alignment());
 
   size_t data_bytes = 0u;
   ReadSize(&data_bytes);
-
   if (data_bytes == 0) {
     *slug = nullptr;
     return;
@@ -476,8 +475,7 @@
 
   *slug = GrSlug::Deserialize(const_cast<const char*>(memory_), data_bytes,
                               options_.strike_client);
-  memory_ += data_bytes;
-  remaining_bytes_ -= data_bytes;
+  DidRead(data_bytes);
 
   if (!*slug) {
     SetInvalid(DeserializationError::kGrSlugDeserializeFailure);
@@ -715,8 +713,7 @@
     valid_ = false;
     return;
   }
-  memory_ += bytes_to_skip;
-  remaining_bytes_ -= bytes_to_skip;
+  DidRead(bytes_to_skip);
 }
 
 void PaintOpReader::AlignMemory(size_t alignment) {
@@ -753,8 +750,7 @@
     return nullptr;
 
   const volatile void* extracted_memory = memory_;
-  memory_ += bytes;
-  remaining_bytes_ -= bytes;
+  DidRead(bytes);
   return extracted_memory;
 }
 
@@ -778,7 +774,7 @@
     crop_rect.emplace(rect);
   }
 
-  AlignMemory(4);
+  AssertAlignment(PaintOpWriter::Alignment());
   switch (type) {
     case PaintFilter::Type::kNullFilter:
       NOTREACHED();
@@ -1400,8 +1396,7 @@
     SetInvalid(DeserializationError::kPaintOpBufferMakeFromMemoryFailure);
     return 0;
   }
-  memory_ += size_bytes;
-  remaining_bytes_ -= size_bytes;
+  DidRead(size_bytes);
   return size_bytes;
 }
 
@@ -1423,4 +1418,13 @@
     SetInvalid(DeserializationError::kSkRegionReadFromMemoryFailure);
 }
 
+inline void PaintOpReader::DidRead(size_t bytes_read) {
+  // All data are aligned with PaintOpWriter::Alignment() at least.
+  size_t aligned_bytes =
+      base::bits::AlignUp(bytes_read, PaintOpWriter::Alignment());
+  memory_ += aligned_bytes;
+  DCHECK_LE(aligned_bytes, remaining_bytes_);
+  remaining_bytes_ -= aligned_bytes;
+}
+
 }  // namespace cc
diff --git a/cc/paint/paint_op_reader.h b/cc/paint/paint_op_reader.h
index 2f95902..b325b5f 100644
--- a/cc/paint/paint_op_reader.h
+++ b/cc/paint/paint_op_reader.h
@@ -35,11 +35,17 @@
                 bool enable_security_constraints = false)
       : memory_(static_cast<const volatile char*>(memory) +
                 PaintOpWriter::HeaderBytes()),
-        remaining_bytes_(size - PaintOpWriter::HeaderBytes()),
+        remaining_bytes_(
+            base::bits::AlignDown(size, PaintOpWriter::Alignment())),
         options_(options),
         enable_security_constraints_(enable_security_constraints) {
-    if (size < PaintOpWriter::HeaderBytes())
+    DCHECK_EQ(memory_,
+              base::bits::AlignUp(memory_, PaintOpWriter::Alignment()));
+    if (remaining_bytes_ < PaintOpWriter::HeaderBytes()) {
       valid_ = false;
+      return;
+    }
+    remaining_bytes_ -= PaintOpWriter::HeaderBytes();
   }
 
   static void FixupMatrixPostSerialization(SkMatrix* matrix);
@@ -125,6 +131,13 @@
   // Aligns the memory to the given alignment.
   void AlignMemory(size_t alignment);
 
+  void AssertAlignment(size_t alignment) {
+#if DCHECK_IS_ON()
+    uintptr_t memory = reinterpret_cast<uintptr_t>(memory_);
+    DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory);
+#endif
+  }
+
  private:
   enum class DeserializationError {
     // Enum values must remain synchronized with PaintOpDeserializationError
@@ -291,6 +304,7 @@
 
   void Read(SkRegion* region);
   uint8_t* CopyScratchSpace(size_t bytes);
+  void DidRead(size_t bytes_read);
 
   const volatile char* memory_ = nullptr;
   size_t remaining_bytes_ = 0u;
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc
index e39cc2f..9e654a3 100644
--- a/cc/paint/paint_op_writer.cc
+++ b/cc/paint/paint_op_writer.cc
@@ -42,7 +42,6 @@
 
 namespace cc {
 namespace {
-constexpr size_t kSkiaAlignment = 4u;
 
 SkIRect MakeSrcRect(const PaintImage& image) {
   if (!image)
@@ -97,12 +96,13 @@
                              const PaintOp::SerializeOptions& options,
                              bool enable_security_constraints)
     : memory_(static_cast<char*>(memory) + HeaderBytes()),
-      size_(size),
-      remaining_bytes_(size - HeaderBytes()),
+      size_(base::bits::AlignDown(size, Alignment())),
+      remaining_bytes_(size_ - HeaderBytes()),
       options_(options),
       enable_security_constraints_(enable_security_constraints) {
   // Leave space for header of type/skip.
   DCHECK_GE(size, HeaderBytes());
+  DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment()));
 }
 
 PaintOpWriter::~PaintOpWriter() = default;
@@ -114,9 +114,8 @@
   // Round up each write to 4 bytes.  This is not technically perfect alignment,
   // but it is about 30% faster to post-align each write to 4 bytes than it is
   // to pre-align memory to the correct alignment.
-  // TODO(enne): maybe we should do this correctly and DCHECK alignment.
-  static constexpr size_t kAlign = 4;
-  size_t size = base::bits::AlignUp(sizeof(T), kAlign);
+  DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment()));
+  static constexpr size_t size = base::bits::AlignUp(sizeof(T), Alignment());
   EnsureBytes(size);
   if (!valid_)
     return;
@@ -137,14 +136,13 @@
     return;
 
   size_t bytes_written = val->serialize(
-      memory_, base::bits::AlignDown(remaining_bytes_, kSkiaAlignment));
+      memory_, base::bits::AlignDown(remaining_bytes_, Alignment()));
   if (bytes_written == 0u) {
     valid_ = false;
     return;
   }
   *size_memory = bytes_written;
-  memory_ += bytes_written;
-  remaining_bytes_ -= bytes_written;
+  DidWrite(bytes_written);
 }
 
 uint64_t* PaintOpWriter::WriteSize(size_t size) {
@@ -225,8 +223,7 @@
     options_.paint_cache->Put(PaintCacheDataType::kPath, id, bytes_written);
   }
   *bytes_to_skip = bytes_written;
-  memory_ += bytes_written;
-  remaining_bytes_ -= bytes_written;
+  DidWrite(bytes_written);
 }
 
 void PaintOpWriter::Write(const PaintFlags& flags, const SkM44& current_ctm) {
@@ -316,8 +313,7 @@
 
   DCHECK_LE(bytes_written, remaining_bytes_);
   *bytes_to_skip = bytes_written;
-  memory_ += bytes_written;
-  remaining_bytes_ -= bytes_written;
+  DidWrite(bytes_written);
 }
 
 void PaintOpWriter::WriteImage(const DecodedDrawImage& decoded_draw_image) {
@@ -355,8 +351,7 @@
     return;
 
   memcpy(memory_, mailbox.name, sizeof(mailbox.name));
-  memory_ += sizeof(mailbox.name);
-  remaining_bytes_ -= sizeof(mailbox.name);
+  DidWrite(sizeof(mailbox.name));
 }
 
 void PaintOpWriter::Write(const sk_sp<SkData>& data) {
@@ -396,16 +391,14 @@
 
   size_t written = color_space->writeToMemory(memory_);
   CHECK_EQ(written, size);
-
-  memory_ += written;
-  remaining_bytes_ -= written;
+  DidWrite(written);
 }
 
 void PaintOpWriter::Write(const sk_sp<GrSlug>& slug) {
   if (!valid_)
     return;
 
-  AlignMemory(4);
+  AssertAlignment(Alignment());
   uint64_t* size_memory = WriteSize(0u);
   if (!valid_)
     return;
@@ -415,15 +408,15 @@
     // TODO(penghuang): should we use a unique id to avoid sending the same
     // slug?
     bytes_written = slug->serialize(
-        memory_, base::bits::AlignDown(remaining_bytes_, kSkiaAlignment));
+        memory_, base::bits::AlignDown(remaining_bytes_, Alignment()));
     if (bytes_written == 0u) {
       valid_ = false;
       return;
     }
   }
+
   *size_memory = bytes_written;
-  memory_ += bytes_written;
-  remaining_bytes_ -= bytes_written;
+  DidWrite(bytes_written);
 }
 
 sk_sp<PaintShader> PaintOpWriter::TransformShaderIfNecessary(
@@ -569,15 +562,18 @@
 }
 
 void PaintOpWriter::WriteData(size_t bytes, const void* input) {
-  EnsureBytes(bytes);
-  if (!valid_)
-    return;
+  DCHECK_EQ(memory_.get(),
+            base::bits::AlignUp(memory_.get(), PaintOpWriter::Alignment()));
   if (bytes == 0)
     return;
 
+  EnsureBytes(bytes);
+
+  if (!valid_)
+    return;
+
   memcpy(memory_, input, bytes);
-  memory_ += bytes;
-  remaining_bytes_ -= bytes;
+  DidWrite(bytes);
 }
 
 void PaintOpWriter::AlignMemory(size_t alignment) {
@@ -614,7 +610,7 @@
   if (!valid_)
     return;
 
-  AlignMemory(kSkiaAlignment);
+  AssertAlignment(Alignment());
   switch (filter->type()) {
     case PaintFilter::Type::kNullFilter:
       NOTREACHED();
@@ -968,8 +964,7 @@
   // The serializer should have failed if it ran out of space. DCHECK to verify
   // that it wrote at most as many bytes as we had left.
   DCHECK_LE(serializer.written(), remaining_bytes_);
-  memory_ += serializer.written();
-  remaining_bytes_ -= serializer.written();
+  DidWrite(serializer.written());
 }
 
 void PaintOpWriter::Write(const SkRegion& region) {
@@ -982,6 +977,14 @@
   WriteData(bytes_written, data.get());
 }
 
+inline void PaintOpWriter::DidWrite(size_t bytes_written) {
+  // All data are aligned with PaintOpWriter::Alignment() at least.
+  size_t aligned_bytes = base::bits::AlignUp(bytes_written, Alignment());
+  memory_ += aligned_bytes;
+  DCHECK_LE(aligned_bytes, remaining_bytes_);
+  remaining_bytes_ -= aligned_bytes;
+}
+
 inline void PaintOpWriter::EnsureBytes(size_t required_bytes) {
   if (remaining_bytes_ < required_bytes)
     valid_ = false;
diff --git a/cc/paint/paint_op_writer.h b/cc/paint/paint_op_writer.h
index 5516340..570e3b2b 100644
--- a/cc/paint/paint_op_writer.h
+++ b/cc/paint/paint_op_writer.h
@@ -97,6 +97,13 @@
   // Aligns the memory to the given alignment.
   void AlignMemory(size_t alignment);
 
+  void AssertAlignment(size_t alignment) {
+#if DCHECK_IS_ON()
+    uintptr_t memory = reinterpret_cast<uintptr_t>(memory_.get());
+    DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory);
+#endif
+  }
+
   // sk_sp is implicitly convertible to uint8_t (likely via implicit bool
   // conversion). In order to avoid accidentally calling that overload instead
   // of a specific function (such as would be the case if one forgets to call
@@ -170,7 +177,7 @@
   void WriteImage(const DecodedDrawImage& decoded_draw_image);
   void WriteImage(uint32_t transfer_cache_entry_id, bool needs_mips);
   void WriteImage(const gpu::Mailbox& mailbox);
-
+  void DidWrite(size_t bytes_written);
   void EnsureBytes(size_t required_bytes);
   sk_sp<PaintShader> TransformShaderIfNecessary(
       const PaintShader* original,
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index eb6bb70..0f846e66 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -25,8 +25,6 @@
 
 const char* LayerTreeHostPixelResourceTest::GetRendererSuffix() const {
   switch (renderer_type_) {
-    case viz::RendererType::kGL:
-      return "gl";
     case viz::RendererType::kSkiaGL:
       return "skia_gl";
     case viz::RendererType::kSkiaVk:
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 0d742be..37a2d2cc 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -159,26 +159,9 @@
 std::unique_ptr<viz::OutputSurface>
 LayerTreePixelTest::CreateDisplayOutputSurfaceOnThread(
     scoped_refptr<viz::ContextProvider> compositor_context_provider) {
-  std::unique_ptr<PixelTestOutputSurface> display_output_surface;
-  if (renderer_type_ == viz::RendererType::kGL) {
-    // Pixel tests use a separate context for the Display to more closely
-    // mimic texture transport from the renderer process to the Display
-    // compositor.
-    auto display_context_provider =
-        base::MakeRefCounted<viz::TestInProcessContextProvider>(
-            viz::TestContextType::kGLES2, /*support_locking=*/false);
-    gpu::ContextResult result = display_context_provider->BindToCurrentThread();
-    DCHECK_EQ(result, gpu::ContextResult::kSuccess);
-
-    gfx::SurfaceOrigin surface_origin = gfx::SurfaceOrigin::kBottomLeft;
-    display_output_surface = std::make_unique<PixelTestOutputSurface>(
-        std::move(display_context_provider), surface_origin);
-  } else {
-    EXPECT_EQ(viz::RendererType::kSoftware, renderer_type_);
-    display_output_surface = std::make_unique<PixelTestOutputSurface>(
-        std::make_unique<viz::SoftwareOutputDevice>());
-  }
-  return std::move(display_output_surface);
+  EXPECT_EQ(viz::RendererType::kSoftware, renderer_type_);
+  return std::make_unique<PixelTestOutputSurface>(
+      std::make_unique<viz::SoftwareOutputDevice>());
 }
 
 std::unique_ptr<viz::CopyOutputRequest>
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index a58e35e..2f30022 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -74,8 +74,6 @@
 
   std::string TestTypeToString() {
     switch (renderer_type_) {
-      case viz::RendererType::kGL:
-        return "GL";
       case viz::RendererType::kSkiaGL:
         return "Skia GL";
       case viz::RendererType::kSkiaVk:
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 47089afa..6e4f6ec 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -32,7 +32,6 @@
 #include "components/viz/service/display/display_resource_provider_gl.h"
 #include "components/viz/service/display/display_resource_provider_skia.h"
 #include "components/viz/service/display/display_resource_provider_software.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/software_output_device.h"
 #include "components/viz/service/display/software_renderer.h"
@@ -259,39 +258,6 @@
       base::DoNothing());
 }
 
-void PixelTest::SetUpGLWithoutRenderer(
-    gfx::SurfaceOrigin output_surface_origin) {
-  enable_pixel_output_ = std::make_unique<gl::DisableNullDrawGLBindings>();
-
-  auto context_provider =
-      base::MakeRefCounted<viz::TestInProcessContextProvider>(
-          viz::TestContextType::kGLES2, /*support_locking=*/false);
-  gpu::ContextResult result = context_provider->BindToCurrentThread();
-  DCHECK_EQ(result, gpu::ContextResult::kSuccess);
-  output_surface_ = std::make_unique<PixelTestOutputSurface>(
-      std::move(context_provider), output_surface_origin);
-  output_surface_->BindToClient(output_surface_client_.get());
-
-  child_context_provider_ =
-      base::MakeRefCounted<viz::TestInProcessContextProvider>(
-          viz::TestContextType::kGLES2, /*support_locking=*/false);
-  result = child_context_provider_->BindToCurrentThread();
-  DCHECK_EQ(result, gpu::ContextResult::kSuccess);
-  child_resource_provider_ = std::make_unique<viz::ClientResourceProvider>();
-}
-
-void PixelTest::SetUpGLRenderer(gfx::SurfaceOrigin output_surface_origin) {
-  SetUpGLWithoutRenderer(output_surface_origin);
-  auto resource_provider = std::make_unique<viz::DisplayResourceProviderGL>(
-      output_surface_->context_provider());
-  renderer_ = std::make_unique<viz::GLRenderer>(
-      &renderer_settings_, &debug_settings_, output_surface_.get(),
-      resource_provider.get(), nullptr, base::ThreadTaskRunnerHandle::Get());
-  resource_provider_ = std::move(resource_provider);
-  renderer_->Initialize();
-  renderer_->SetVisible(true);
-}
-
 void PixelTest::SetUpSkiaRenderer(gfx::SurfaceOrigin output_surface_origin) {
   enable_pixel_output_ = std::make_unique<gl::DisableNullDrawGLBindings>();
   // Set up the GPU service.
@@ -337,11 +303,6 @@
   output_surface_.reset();
 }
 
-void PixelTest::EnableExternalStencilTest() {
-  static_cast<PixelTestOutputSurface*>(output_surface_.get())
-      ->set_has_external_stencil_test(true);
-}
-
 void PixelTest::SetUpSoftwareRenderer() {
   output_surface_ = std::make_unique<PixelTestOutputSurface>(
       std::make_unique<viz::SoftwareOutputDevice>());
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index 5ea92b81..8155572e 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -21,7 +21,6 @@
 #include "components/viz/common/quads/compositor_render_pass.h"
 #include "components/viz/common/resources/shared_bitmap.h"
 #include "components/viz/service/display/aggregated_frame.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/skia_renderer.h"
 #include "components/viz/service/display/software_renderer.h"
@@ -129,15 +128,11 @@
   raw_ptr<viz::SoftwareRenderer> software_renderer_ = nullptr;
   std::unique_ptr<SkBitmap> result_bitmap_;
 
-  void SetUpGLWithoutRenderer(gfx::SurfaceOrigin output_surface_origin);
-  void SetUpGLRenderer(gfx::SurfaceOrigin output_surface_origin);
   void SetUpSkiaRenderer(gfx::SurfaceOrigin output_surface_origin);
   void SetUpSoftwareRenderer();
 
   void TearDown() override;
 
-  void EnableExternalStencilTest();
-
  private:
   void ReadbackResult(base::OnceClosure quit_run_loop,
                       std::unique_ptr<viz::CopyOutputResult> result);
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc
index 78a201e..6b62cea 100644
--- a/cc/test/pixel_test_output_surface.cc
+++ b/cc/test/pixel_test_output_surface.cc
@@ -20,14 +20,6 @@
 namespace cc {
 
 PixelTestOutputSurface::PixelTestOutputSurface(
-    scoped_refptr<viz::ContextProvider> context_provider,
-    gfx::SurfaceOrigin origin)
-    : OutputSurface(std::move(context_provider)) {
-  capabilities_.output_surface_origin = origin;
-  capabilities_.supports_stencil = true;
-}
-
-PixelTestOutputSurface::PixelTestOutputSurface(
     std::unique_ptr<viz::SoftwareOutputDevice> software_device)
     : OutputSurface(std::move(software_device)) {
   capabilities_.supports_stencil = true;
@@ -43,29 +35,18 @@
 
 void PixelTestOutputSurface::DiscardBackbuffer() {}
 
-void PixelTestOutputSurface::BindFramebuffer() {
-  context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
-}
+void PixelTestOutputSurface::BindFramebuffer() {}
 
 void PixelTestOutputSurface::Reshape(const gfx::Size& size,
                                      float device_scale_factor,
                                      const gfx::ColorSpace& color_space,
                                      gfx::BufferFormat format,
                                      bool use_stencil) {
-  // External stencil test cannot be tested at the same time as |use_stencil|.
-  DCHECK(!use_stencil || !external_stencil_test_);
-  if (context_provider()) {
-    const bool has_alpha = gfx::AlphaBitsForBufferFormat(format);
-    context_provider()->ContextGL()->ResizeCHROMIUM(
-        size.width(), size.height(), device_scale_factor,
-        color_space.AsGLColorSpace(), has_alpha);
-  } else {
-    software_device()->Resize(size, device_scale_factor);
-  }
+  software_device()->Resize(size, device_scale_factor);
 }
 
 bool PixelTestOutputSurface::HasExternalStencilTest() const {
-  return external_stencil_test_;
+  return false;
 }
 
 void PixelTestOutputSurface::ApplyExternalStencil() {}
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h
index b05ebb5..5a72f2a 100644
--- a/cc/test/pixel_test_output_surface.h
+++ b/cc/test/pixel_test_output_surface.h
@@ -13,12 +13,10 @@
 
 namespace cc {
 
+// Software output surface for pixel tests.
 class PixelTestOutputSurface : public viz::OutputSurface {
  public:
   explicit PixelTestOutputSurface(
-      scoped_refptr<viz::ContextProvider> context_provider,
-      gfx::SurfaceOrigin origin);
-  explicit PixelTestOutputSurface(
       std::unique_ptr<viz::SoftwareOutputDevice> software_device);
   ~PixelTestOutputSurface() override;
 
@@ -44,14 +42,9 @@
   void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
   gfx::OverlayTransform GetDisplayTransform() override;
 
-  void set_has_external_stencil_test(bool has_test) {
-    external_stencil_test_ = has_test;
-  }
-
  private:
   void SwapBuffersCallback();
 
-  bool external_stencil_test_ = false;
   raw_ptr<viz::OutputSurfaceClient> client_ = nullptr;
   base::WeakPtrFactory<PixelTestOutputSurface> weak_ptr_factory_{this};
 };
diff --git a/cc/test/render_pass_test_utils.h b/cc/test/render_pass_test_utils.h
index 3388c41..1118d76 100644
--- a/cc/test/render_pass_test_utils.h
+++ b/cc/test/render_pass_test_utils.h
@@ -12,6 +12,7 @@
 #include "cc/paint/filter_operations.h"
 #include "components/viz/common/quads/aggregated_render_pass.h"
 #include "components/viz/common/quads/compositor_render_pass.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace gfx {
@@ -28,7 +29,6 @@
 class ContextProvider;
 class DisplayResourceProvider;
 class CompositorRenderPass;
-class SolidColorDrawQuad;
 }  // namespace viz
 
 namespace cc {
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index df603e6..5608e35 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -83,7 +83,6 @@
 #include "components/viz/common/quads/tile_draw_quad.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/common/surfaces/region_capture_bounds.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/skia_output_surface.h"
 #include "components/viz/test/begin_frame_args_test.h"
 #include "components/viz/test/fake_output_surface.h"
@@ -11284,11 +11283,6 @@
   DrawFrameAndTestDamage(no_damage, child);
 }
 
-class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer {
- public:
-  using viz::GLRenderer::ShouldAntialiasQuad;
-};
-
 TEST_P(ScrollUnifiedLayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
   // Due to precision issues (especially on Android), sometimes far
   // away quads can end up thinking they need AA.
@@ -11340,16 +11334,12 @@
   ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
   const viz::DrawQuad* quad = frame.render_passes[0]->quad_list.front();
 
-  bool clipped = false, force_aa = false;
-  gfx::QuadF device_layer_quad = MathUtil::MapQuad(
+  bool clipped = false;
+  MathUtil::MapQuad(
       quad->shared_quad_state->quad_to_target_transform,
       gfx::QuadF(gfx::RectF(quad->shared_quad_state->visible_quad_layer_rect)),
       &clipped);
   EXPECT_FALSE(clipped);
-  bool antialiased =
-      GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
-          device_layer_quad, clipped, force_aa);
-  EXPECT_FALSE(antialiased);
 
   host_impl_->DrawLayers(&frame);
   host_impl_->DidDrawAllLayers(frame);
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index f8b31c67..fc3d5a9 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -63,7 +63,6 @@
 const uint32_t kUseMasks = 1 << 0;
 const uint32_t kUseAntialiasing = 1 << 1;
 const uint32_t kUseColorMatrix = 1 << 2;
-const uint32_t kForceShaders = 1 << 3;
 
 class LayerTreeHostBlendingPixelTest
     : public LayerTreeHostPixelResourceTest,
@@ -72,8 +71,7 @@
  public:
   LayerTreeHostBlendingPixelTest()
       : LayerTreeHostPixelResourceTest(resource_type()),
-        force_antialiasing_(false),
-        force_blending_with_shaders_(false) {
+        force_antialiasing_(false) {
     pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);
   }
 
@@ -93,8 +91,6 @@
       override {
     viz::RendererSettings modified_renderer_settings = renderer_settings;
     modified_renderer_settings.force_antialiasing = force_antialiasing_;
-    modified_renderer_settings.force_blending_with_shaders =
-        force_blending_with_shaders_;
     return LayerTreeHostPixelResourceTest::CreateLayerTreeFrameSink(
         modified_renderer_settings, refresh_rate, compositor_context_provider,
         worker_context_provider);
@@ -211,10 +207,6 @@
     const int kRootWidth = 2;
     const int kRootHeight = kRootWidth * kCSSTestColorsCount;
 
-    // Force shaders only applies to gl renderer.
-    if (renderer_type_ != viz::RendererType::kGL && flags & kForceShaders)
-      return;
-
     SCOPED_TRACE(TestTypeToString());
     SCOPED_TRACE(SkBlendMode_Name(current_blend_mode()));
 
@@ -229,10 +221,8 @@
     CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags);
 
     force_antialiasing_ = (flags & kUseAntialiasing);
-    force_blending_with_shaders_ = (flags & kForceShaders);
 
-    if ((renderer_type_ == viz::RendererType::kGL && force_antialiasing_) ||
-        renderer_type_ == viz::RendererType::kSkiaVk) {
+    if (renderer_type_ == viz::RendererType::kSkiaVk) {
       // Blending results might differ with one pixel.
       float percentage_pixels_error = 35.f;
       float percentage_pixels_small_error = 0.f;
@@ -252,7 +242,6 @@
   }
 
   bool force_antialiasing_;
-  bool force_blending_with_shaders_;
   FakeContentLayerClient mask_client_;
   FakeContentLayerClient backdrop_client_;
   SkColor misc_opaque_color_ = 0xffc86464;
@@ -261,9 +250,6 @@
 std::vector<RasterTestConfig> const kTestCases = {
     {viz::RendererType::kSoftware, TestRasterType::kBitmap},
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    {viz::RendererType::kGL, TestRasterType::kZeroCopy},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     {viz::RendererType::kSkiaGL, TestRasterType::kGpu},
 #endif  // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
 #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS)
@@ -423,44 +409,6 @@
   RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix);
 }
 
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders) {
-  RunBlendingWithRenderPass(kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA) {
-  RunBlendingWithRenderPass(kUseAntialiasing | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersWithMask) {
-  RunBlendingWithRenderPass(kUseMasks | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
-       BlendingWithRenderPassShadersWithMaskAA) {
-  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
-       BlendingWithRenderPassShadersColorMatrix) {
-  RunBlendingWithRenderPass(kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
-       BlendingWithRenderPassShadersColorMatrixAA) {
-  RunBlendingWithRenderPass(kUseAntialiasing | kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
-       BlendingWithRenderPassShadersWithMaskColorMatrix) {
-  RunBlendingWithRenderPass(kUseMasks | kUseColorMatrix | kForceShaders);
-}
-
-TEST_P(LayerTreeHostBlendingPixelTest,
-       BlendingWithRenderPassShadersWithMaskColorMatrixAA) {
-  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix |
-                            kForceShaders);
-}
-
 }  // namespace
 }  // namespace cc
 
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index 40114681..a4b25ed 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -32,8 +32,6 @@
   // generating separate base line file paths.
   const char* GetRendererSuffix() {
     switch (renderer_type_) {
-      case viz::RendererType::kGL:
-        return "gl";
       case viz::RendererType::kSkiaGL:
         return "skia_gl";
       case viz::RendererType::kSkiaVk:
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index 6666f03..38205753 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -31,11 +31,6 @@
 std::vector<RasterTestConfig> const kTestCases = {
     {viz::RendererType::kSoftware, TestRasterType::kBitmap},
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    {viz::RendererType::kGL, TestRasterType::kGpu},
-    {viz::RendererType::kGL, TestRasterType::kOneCopy},
-    {viz::RendererType::kGL, TestRasterType::kZeroCopy},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     {viz::RendererType::kSkiaGL, TestRasterType::kGpu},
     {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
     {viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy},
@@ -873,15 +868,6 @@
 MaskTestConfig const kTestConfigs[] = {
     MaskTestConfig{{viz::RendererType::kSoftware, TestRasterType::kBitmap}, 0},
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, 0},
-    MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
-                   kUseAntialiasing},
-    MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
-                   kForceShaders},
-    MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy},
-                   kUseAntialiasing | kForceShaders},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, 0},
     MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy},
                    kUseAntialiasing},
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc
index 873f646..12d2043 100644
--- a/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -441,10 +441,6 @@
 ReadbackTestConfig const kTestConfigs[] = {
     ReadbackTestConfig{viz::RendererType::kSoftware, TestReadBackType::kBitmap},
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kTexture},
-    ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kBitmap},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kTexture},
     ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kBitmap},
 #endif  // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 76fc847..0d7b464 100644
--- a/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -222,10 +222,6 @@
 std::vector<RasterTestConfig> const kTestCases = {
     {viz::RendererType::kSoftware, TestRasterType::kBitmap},
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    {viz::RendererType::kGL, TestRasterType::kOneCopy},
-    {viz::RendererType::kGL, TestRasterType::kGpu},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
     {viz::RendererType::kSkiaGL, TestRasterType::kGpu},
 #endif  // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
@@ -265,9 +261,6 @@
 
 std::vector<RasterTestConfig> const kTestCasesMultiThread = {
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-    {viz::RendererType::kGL, TestRasterType::kOneCopy},
-#endif  // BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
     {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy},
 #endif  // BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
 #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS)
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 8d13272..1fa38826 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -338,7 +338,6 @@
     "$google_play_services_package:google_play_services_tasks_java",
     "$google_play_services_package:google_play_services_vision_common_java",
     "$google_play_services_package:google_play_services_vision_java",
-    "//base:base_java",
     "//cc:cc_java",
     "//chrome/android/features/keyboard_accessory:public_java",
     "//chrome/android/features/start_surface:public_java",
@@ -936,7 +935,6 @@
     "$google_play_services_package:google_play_services_basement_java",
     "$google_play_services_package:google_play_services_cast_framework_java",
     "$google_play_services_package:google_play_services_cast_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
@@ -1209,9 +1207,11 @@
 
   sources = [
     "javatests/src/org/chromium/chrome/browser/homepage/HomepageTestRule.java",
+    "javatests/src/org/chromium/chrome/browser/tabmodel/TestTabModelDirectory.java",
   ]
 
   deps = [
+    "//base:base_java",
     "//chrome/browser/preferences:java",
     "//components/policy/android:policy_java",
     "//components/policy/android:policy_java_test_support",
@@ -1277,7 +1277,12 @@
   resources_package = "org.chromium.chrome.test"
   sources = [
     "javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java",
+    "javatests/src/org/chromium/chrome/browser/tab/WebContentsStateBridgeTest.java",
+    "javatests/src/org/chromium/chrome/browser/tabmodel/AsyncTabCreationParamsManagerTest.java",
+    "javatests/src/org/chromium/chrome/browser/tabmodel/RestoreMigrateTest.java",
+    "javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java",
     "javatests/src/org/chromium/chrome/browser/toolbar/HomeButtonTest.java",
+    "javatests/src/org/chromium/chrome/browser/toolbar/ToolbarSecurityIconTest.java",
   ]
   deps = [
     ":chrome_unit_test_util_java",
@@ -1289,12 +1294,23 @@
     "//chrome/browser/first_run/android:java",
     "//chrome/browser/flags:java",
     "//chrome/browser/lens:java",
+    "//chrome/browser/preferences:java",
+    "//chrome/browser/profiles/android:java",
+    "//chrome/browser/tab:java",
+    "//chrome/browser/tabmodel:java",
+    "//chrome/browser/tabpersistence:java",
+    "//chrome/browser/ui/android/omnibox:java",
     "//chrome/browser/ui/android/toolbar:java",
     "//chrome/test/android:chrome_java_test_support",
     "//components/browser_ui/settings/android:java",
     "//components/embedder_support/android:context_menu_java",
+    "//components/embedder_support/android:util_java",
     "//components/externalauth/android:java",
+    "//components/prefs/android:java",
     "//components/search_engines/android:java",
+    "//components/security_state/content/android:java",
+    "//components/security_state/core:security_state_enums_java",
+    "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
     "//third_party/android_deps:espresso_java",
     "//third_party/android_support_test_runner:runner_java",
@@ -1330,7 +1346,6 @@
     "$google_play_services_package:google_play_services_gcm_java",
     "$google_play_services_package:google_play_services_iid_java",
     "$google_play_services_package:google_play_services_tasks_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base/test:test_support_java",
     "//build/android:build_java",
@@ -3287,7 +3302,6 @@
   # the parent target is never_incremental.
   never_incremental = true
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/test/android:chrome_java_test_pagecontroller",
     "//content/public/test/android:content_java_test_support",
@@ -3858,7 +3872,6 @@
     "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java",
     "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java",
     "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTabHelper.java",
-    "java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java",
     "java/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceImpl.java",
     "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java",
     "java/src/org/chromium/chrome/browser/datareduction/DataSaverOSSetting.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index d16c0f7..765bd82d 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -317,7 +317,6 @@
   "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabCoordinator.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabMediator.java",
   "java/src/org/chromium/chrome/browser/compositor/bottombar/ephemeraltab/EphemeralTabSheetContent.java",
-  "java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java",
@@ -327,7 +326,6 @@
   "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutProvider.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutRenderHost.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/LayoutUpdateHost.java",
-  "java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeBehavior.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/SceneChangeObserver.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java",
@@ -406,7 +404,6 @@
   "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslation.java",
   "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslationImpl.java",
   "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java",
-  "java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java",
   "java/src/org/chromium/chrome/browser/contextualsearch/DisableablePromoTapCounter.java",
   "java/src/org/chromium/chrome/browser/contextualsearch/EngagementSuppression.java",
   "java/src/org/chromium/chrome/browser/contextualsearch/NearTopTapSuppression.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index fdc4fa1e..48bc880 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -216,6 +216,7 @@
   "junit/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaverImplUnitTest.java",
   "junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java",
   "junit/src/org/chromium/chrome/browser/tabmodel/PendingTabClosureManagerTest.java",
+  "junit/src/org/chromium/chrome/browser/tabmodel/TabModelImplUnitTest.java",
   "junit/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImplTest.java",
   "junit/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorProfileSupplierTest.java",
   "junit/src/org/chromium/chrome/browser/tabmodel/UndoTabModelUnitTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index 21812eb..09885af 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -595,7 +595,6 @@
   "javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java",
   "javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java",
   "javatests/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicyTest.java",
-  "javatests/src/org/chromium/chrome/browser/tabmodel/TestTabModelDirectory.java",
   "javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java",
   "javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilTest.java",
   "javatests/src/org/chromium/chrome/browser/test/CommandLineInitRule.java",
@@ -638,6 +637,7 @@
   "javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcherTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationTest.java",
+  "javatests/src/org/chromium/chrome/browser/webapps/WebappDefaultOfflineTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappDisplayModeTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetricsTest.java",
   "javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java",
diff --git a/chrome/android/features/dev_ui/BUILD.gn b/chrome/android/features/dev_ui/BUILD.gn
index 672f457..e52029b 100644
--- a/chrome/android/features/dev_ui/BUILD.gn
+++ b/chrome/android/features/dev_ui/BUILD.gn
@@ -15,7 +15,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//build/android:build_java",
     "//chrome/android/features/dev_ui/public:java",
   ]
diff --git a/chrome/android/features/dev_ui/public/BUILD.gn b/chrome/android/features/dev_ui/public/BUILD.gn
index 779293e..ff498f1 100644
--- a/chrome/android/features/dev_ui/public/BUILD.gn
+++ b/chrome/android/features/dev_ui/public/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//components/module_installer/android:module_installer_java",
     "//components/module_installer/android:module_interface_java",
   ]
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartNewTabFromLauncherTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartNewTabFromLauncherTest.java
index 68ae091..210e6858 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartNewTabFromLauncherTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartNewTabFromLauncherTest.java
@@ -36,6 +36,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.homepage.HomepageManager;
+import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
@@ -184,7 +185,7 @@
         StartSurfaceTestUtils.waitForTabModel(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 1);
 
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { Assert.assertTrue(UrlUtilities.isNTPUrl(cta.getActivityTab().getUrl())); });
     }
@@ -204,7 +205,7 @@
         StartSurfaceTestUtils.waitForTabModel(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0);
 
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { Assert.assertTrue(UrlUtilities.isNTPUrl(cta.getActivityTab().getUrl())); });
     }
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 1d86177..da8aedca 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
@@ -60,6 +60,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.homepage.HomepageManager;
+import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.suggestions.SiteSuggestion;
@@ -543,7 +544,7 @@
         StartSurfaceTestUtils.waitForTabModel(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
 
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         StartSurfaceCoordinator startSurfaceCoordinator =
                 StartSurfaceTestUtils.getStartSurfaceFromUIThread(cta);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java
index 3fc39f1..2c8e73a 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java
@@ -178,7 +178,7 @@
         StartSurfaceTestUtils.launchFirstMVTile(cta, /* currentTabCount = */ 1);
         StartSurfaceTestUtils.pressBack(mActivityTestRule);
 
-        CriteriaHelper.pollUiThread(() -> cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER);
         // Verifies the new Tab is deleted.
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
 
@@ -194,7 +194,7 @@
         StartSurfaceTestUtils.clickTabInCarousel(/* position = */ 1);
         Assert.assertEquals(TabLaunchType.FROM_START_SURFACE,
                 cta.getTabModelSelector().getCurrentTab().getLaunchType());
-        CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
         StartSurfaceTestUtils.pressBack(mActivityTestRule);
         onViewWaiting(withId(R.id.primary_tasks_surface_view));
         // Verifies the tab isn't auto deleted from the TabModel.
@@ -255,7 +255,7 @@
         onView(allOf(withParent(withId(R.id.tasks_surface_body)),
                        withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))
                 .perform(RecyclerViewActions.actionOnItemAtPosition(1, click()));
-        CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
         Assert.assertEquals(TabLaunchType.FROM_START_SURFACE,
                 cta.getTabModelSelector().getCurrentTab().getLaunchType());
         TestThreadUtils.runOnUiThreadBlocking(
@@ -312,7 +312,7 @@
 
         TabUiTestHelper.mergeAllNormalTabsToAGroup(cta);
         StartSurfaceTestUtils.pressHomePageButton(cta);
-        CriteriaHelper.pollUiThread(() -> cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER);
 
         StartSurfaceTestUtils.clickFirstTabInCarousel();
         onViewWaiting(allOf(
@@ -601,7 +601,7 @@
         Assert.assertTrue(InstrumentationRegistry.getInstrumentation().invokeContextMenuAction(
                 mActivityTestRule.getActivity(),
                 ContextMenuManager.ContextMenuItemId.OPEN_IN_INCOGNITO_TAB, 0));
-        CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
         // Verifies a new incognito tab is created.
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, incognitoTabs);
     }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
index ef9e6c0..607c7ec9 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
@@ -305,7 +305,8 @@
                                                              -> frameRates.size() == expectedSize,
                     "Have not got PerfListener callback", DEFAULT_MAX_TIME_TO_POLL * 10,
                     DEFAULT_POLLING_INTERVAL);
-            assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
 
             mStartSurfaceLayout.setPerfListenerForTesting(null);
             // Make sure the fading animation is done.
@@ -313,12 +314,8 @@
             TestThreadUtils.runOnUiThreadBlocking(
                     () -> { startSurface.getController().onBackPressed(); });
             Thread.sleep(1000);
-            CriteriaHelper.pollInstrumentationThread(()
-                                                             -> !mActivityTestRule.getActivity()
-                                                                         .getLayoutManager()
-                                                                         .overviewVisible(),
-                    "Overview not hidden yet", DEFAULT_MAX_TIME_TO_POLL * 10,
-                    DEFAULT_POLLING_INTERVAL);
+            LayoutTestUtils.waitForLayout(
+                    mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING);
         }
         assertEquals(mRepeat, frameRates.size());
         Log.i(TAG, "%s: fps = %.2f, maxFrameInterval = %.0f, dirtySpan = %.0f", description,
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 941ff73..a32b83cb 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
@@ -31,8 +31,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL;
-import static org.chromium.base.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.areAnimatorsEnabled;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInTabSwitcher;
 import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabGroup;
@@ -617,7 +615,8 @@
             onView(tabSwitcherViewMatcher()).perform(actionOnItemAtPosition(targetIndex, click()));
             CriteriaHelper.pollUiThread(() -> {
                 boolean doneHiding =
-                        !mActivityTestRule.getActivity().getLayoutManager().overviewVisible();
+                        !mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                                LayoutType.TAB_SWITCHER);
                 if (!doneHiding) {
                     // Before overview hiding animation is done, the tab index should not change.
                     Criteria.checkThat(mActivityTestRule.getActivity().getCurrentTabModel().index(),
@@ -743,8 +742,8 @@
         onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
 
         onView(tabSwitcherViewMatcher()).perform(actionOnItemAtPosition(0, click()));
-        CriteriaHelper.pollUiThread(
-                () -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(
+                mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING);
 
         enterGTSWithThumbnailChecking();
         onView(tabSwitcherViewMatcher()).check(TabCountAssertion.havingTabCount(1));
@@ -2243,17 +2242,16 @@
      * If thumbnail checking is not needed, use {@link TabUiTestHelper#leaveTabSwitcher} instead.
      */
     private void leaveGTSAndVerifyThumbnailsAreReleased() {
-        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                LayoutType.TAB_SWITCHER));
 
         StartSurface startSurface = mStartSurfaceLayout.getStartSurfaceForTesting();
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { startSurface.getController().onBackPressed(); });
         // TODO(wychen): using default timeout or even converting to
         //  OverviewModeBehaviorWatcher shouldn't increase flakiness.
-        CriteriaHelper.pollUiThread(
-                ()
-                        -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible(),
-                "Overview not hidden yet", DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL);
+        LayoutTestUtils.waitForLayout(
+                mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING);
         assertThumbnailsAreReleased();
     }
 
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java
index 8393936..af4aaf4 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceMVTilesTest.java
@@ -281,7 +281,7 @@
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
         invokeContextMenu(tileView, ContextMenuManager.ContextMenuItemId.OPEN_IN_NEW_TAB);
         // This tab should be opened in the background.
-        Assert.assertTrue(cta.getLayoutManager().overviewVisible());
+        Assert.assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         // Verifies a new tab is created.
         TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0);
     }
@@ -307,7 +307,6 @@
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
         invokeContextMenu(tileView, ContextMenuManager.ContextMenuItemId.OPEN_IN_INCOGNITO_TAB);
         LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
-        CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
         // Verifies a new incognito tab is created.
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 1);
     }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
index d91d418..77cf9a1 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceNoTabsTest.java
@@ -45,6 +45,7 @@
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.tasks.ReturnToChromeUtil;
 import org.chromium.chrome.start_surface.R;
 import org.chromium.chrome.test.ChromeActivityTestRule;
@@ -128,7 +129,8 @@
         CriteriaHelper.pollUiThread(
                 ()
                         -> mActivityTestRule.getActivity().getLayoutManager() != null
-                        && mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+                        && mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                                LayoutType.TAB_SWITCHER));
 
         onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
         onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
@@ -160,7 +162,8 @@
         CriteriaHelper.pollUiThread(
                 ()
                         -> mActivityTestRule.getActivity().getLayoutManager() != null
-                        && mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+                        && mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                                LayoutType.TAB_SWITCHER));
 
         onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
         onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java
index 261c080..5d0e2164 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTabSwitcherTest.java
@@ -299,8 +299,9 @@
         }
 
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
-        CriteriaHelper.pollUiThread(
-                () -> cta.getLayoutManager() != null && cta.getLayoutManager().overviewVisible());
+        CriteriaHelper.pollUiThread(()
+                                            -> cta.getLayoutManager() != null
+                        && cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         StartSurfaceTestUtils.waitForTabModel(cta);
         onViewWaiting(withId(R.id.logo));
         Tab tab1 = cta.getCurrentTabModel().getTabAt(0);
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
index 39248c3..3a456c3 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -378,13 +378,14 @@
         }
 
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
-        CriteriaHelper.pollUiThread(
-                () -> cta.getLayoutManager() != null && cta.getLayoutManager().overviewVisible());
+        CriteriaHelper.pollUiThread(()
+                                            -> cta.getLayoutManager() != null
+                        && cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         StartSurfaceTestUtils.waitForTabModel(cta);
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { cta.getTabModelSelector().getModel(false).closeAllTabs(); });
         TabUiTestHelper.verifyTabModelTabCount(cta, 0, 0);
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> cta.getTabCreator(true /*incognito*/).launchNTP());
         TabUiTestHelper.verifyTabModelTabCount(cta, 0, 1);
@@ -490,14 +491,14 @@
             // omnibox.
             return;
         }
-        CriteriaHelper.pollUiThread(() -> !cta.getOverviewModeBehavior().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER);
         TabUiTestHelper.enterTabSwitcher(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0);
 
         // Click plus button from top toolbar should create NTP instead of showing start surface.
         onViewWaiting(withId(R.id.new_tab_button)).perform(click());
         TabUiTestHelper.verifyTabModelTabCount(cta, 3, 0);
-        assertFalse(cta.getOverviewModeBehavior().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
     }
 
     @Test
@@ -529,7 +530,7 @@
         StartSurfaceTestUtils.pressHomePageButton(cta);
         CriteriaHelper.pollUiThread(
                 () -> UrlUtilities.isNTPUrl(cta.getTabModelSelector().getCurrentTab().getUrl()));
-        assertFalse(cta.getOverviewModeBehavior().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
     }
 
     /**
@@ -764,7 +765,7 @@
         StartSurfaceTestUtils.pressHomePageButton(cta);
 
         waitForView(withId(R.id.primary_tasks_surface_view));
-        CriteriaHelper.pollUiThread(() -> cta.getLayoutManager().overviewVisible());
+        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER);
         Assert.assertEquals(TabLaunchType.FROM_START_SURFACE, tab.getLaunchType());
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { Assert.assertTrue(StartSurfaceUserData.getKeepTab(tab)); });
@@ -782,7 +783,7 @@
         StartSurfaceTestUtils.waitForTabModel(cta);
         assertEquals(1, cta.getTabModelSelector().getTotalTabCount());
         mActivityTestRule.waitForActivityNativeInitializationComplete();
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
 
         Assert.assertFalse(ReturnToChromeUtil.isPrimaryAccountSync());
         Assert.assertFalse(ReturnToChromeUtil.shouldShowOverviewPageOnStart(cta, cta.getIntent(),
@@ -815,7 +816,7 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { cta.getTabModelSelector().getModel(false).closeAllTabs(); });
         TabUiTestHelper.verifyTabModelTabCount(cta, 0, 0);
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> cta.getTabCreator(true /*incognito*/).launchNTP());
         TabUiTestHelper.verifyTabModelTabCount(cta, 0, 1);
@@ -823,7 +824,7 @@
         // Simulates pressing the home button. Incognito tab should stay and homepage shouldn't
         // show.
         onView(withId(R.id.home_button)).perform(click());
-        assertFalse(cta.getLayoutManager().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         int container_id = ChromeFeatureList.isEnabled(ChromeFeatureList.INCOGNITO_NTP_REVAMP)
                 ? R.id.revamped_incognito_ntp_container
                 : R.id.new_tab_incognito_container;
@@ -842,7 +843,7 @@
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         StartSurfaceTestUtils.waitForTabModel(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
 
         SharedPreferencesManager manager = SharedPreferencesManager.getInstance();
         // Verifies that the START_NEXT_SHOW_ON_STARTUP_DECISION_MS has been set.
@@ -965,7 +966,7 @@
         ChromeTabbedActivity cta = mActivityTestRule.getActivity();
         StartSurfaceTestUtils.waitForTabModel(cta);
         TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
-        Assert.assertFalse(cta.getLayoutManager().overviewVisible());
+        Assert.assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
 
         SharedPreferencesManager manager = SharedPreferencesManager.getInstance();
         // Verifies that the START_NEXT_SHOW_ON_STARTUP_DECISION_MS has been set.
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
index dc3b267a..7e9c075 100644
--- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
+++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTestUtils.java
@@ -403,7 +403,6 @@
             }
         });
         LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
-        CriteriaHelper.pollUiThread(() -> !cta.getLayoutManager().overviewVisible());
         // Verifies a new Tab is created.
         TabUiTestHelper.verifyTabModelTabCount(cta, currentTabCount + 1, 0);
     }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
index 7658896e..40939b8 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -95,6 +95,7 @@
 import org.chromium.chrome.browser.compositor.layouts.Layout;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
 import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
@@ -197,7 +198,7 @@
         verifyTabSwitcherCardCount(cta, 1);
 
         // Enter first tab page.
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         clickFirstCardFromTabSwitcher(cta);
         clickFirstTabInDialog(cta);
         waitForDialogHidingAnimation(cta);
@@ -232,7 +233,7 @@
         verifyTabSwitcherCardCount(cta, 1);
 
         // Enter first tab page.
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         clickFirstCardFromTabSwitcher(cta);
         clickFirstTabInDialog(cta);
         waitForDialogHidingAnimation(cta);
@@ -1101,7 +1102,7 @@
     }
 
     private void showDialogFromStrip(ChromeTabbedActivity cta) {
-        assertFalse(cta.getLayoutManager().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         onView(allOf(withId(R.id.toolbar_left_button),
                        isDescendantOfA(withId(R.id.bottom_controls))))
                 .perform(click());
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java
index 0c46bd4..9696d38 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java
@@ -61,6 +61,7 @@
 import org.chromium.chrome.browser.compositor.layouts.Layout;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
 import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
 import org.chromium.chrome.tab_ui.R;
@@ -123,7 +124,7 @@
         // Select the 1st tab in group.
         clickFirstCardFromTabSwitcher(cta);
         clickFirstTabInDialog(cta);
-        assertFalse(cta.getLayoutManager().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         onView(withId(R.id.bottom_controls)).check(matches(isDisplayed()));
         verifyTabStripFaviconCount(cta, 2);
     }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java
index e2bba88..74fcb64 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherTabletTest.java
@@ -289,7 +289,8 @@
 
     private void exitGTSAndVerifyThumbnailsAreReleased()
             throws TimeoutException, ExecutionException {
-        assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                LayoutType.TAB_SWITCHER));
 
         final int index = mActivityTestRule.getActivity().getCurrentTabModel().index();
         exitSwitcherWithTabClick(index);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
index 6d8024e0..bc46bdc 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -108,7 +108,7 @@
      * @param cta  The current running activity.
      */
     public static void enterTabSwitcher(ChromeTabbedActivity cta) {
-        assertFalse(cta.getLayoutManager().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         // TODO(crbug.com/1145271): Replace this with clicking tab switcher button via espresso.
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> { cta.findViewById(R.id.tab_switcher_button).performClick(); });
@@ -120,7 +120,7 @@
      * @param cta  The current running activity.
      */
     public static void leaveTabSwitcher(ChromeTabbedActivity cta) {
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         pressBack();
         LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
     }
@@ -146,7 +146,7 @@
 
     private static void clickTabSwitcherCardWithParent(
             ChromeTabbedActivity cta, int index, int parentId) {
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         onView(allOf(withParent(withId(parentId)), withId(R.id.tab_list_view)))
                 .perform(RecyclerViewActions.actionOnItemAtPosition(index, click()));
     }
@@ -363,7 +363,7 @@
      * @param count     The correct number of cards in tab switcher.
      */
     public static void verifyTabSwitcherCardCount(ChromeTabbedActivity cta, int count) {
-        assertTrue(cta.getLayoutManager().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         onView(allOf(withParent(withId(org.chromium.chrome.R.id.compositor_view_holder)),
                        withId(R.id.tab_list_view)))
                 .check(ChildrenCountAssertion.havingTabCount(count));
@@ -375,7 +375,7 @@
      * @param count     The correct number of favicons in tab strip.
      */
     static void verifyTabStripFaviconCount(ChromeTabbedActivity cta, int count) {
-        assertFalse(cta.getLayoutManager().overviewVisible());
+        assertFalse(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
         onView(allOf(withParent(withId(R.id.toolbar_container_view)), withId(R.id.tab_list_view)))
                 .check(ChildrenCountAssertion.havingTabCount(count));
     }
@@ -592,7 +592,7 @@
      */
     public static void switchTabModel(ChromeTabbedActivity cta, boolean isIncognito) {
         assertTrue(isIncognito != cta.getTabModelSelector().isIncognitoSelected());
-        assertTrue(cta.getOverviewModeBehavior().overviewVisible());
+        assertTrue(cta.getLayoutManager().isLayoutVisible(LayoutType.TAB_SWITCHER));
 
         onView(withContentDescription(isIncognito
                                ? R.string.accessibility_tab_switcher_incognito_stack
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni
index e0e665d..620927d 100644
--- a/chrome/android/feed/feed_java_sources.gni
+++ b/chrome/android/feed/feed_java_sources.gni
@@ -5,7 +5,6 @@
 import("//components/feed/features.gni")
 
 feed_deps = [
-  "//base:base_java",
   "//chrome/android/feed:chrome_feed_java_resources",
   "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
   "//third_party/android_deps:javax_inject_javax_inject_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 61da868..e34eca6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -74,7 +74,6 @@
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromeTablet;
-import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
 import org.chromium.chrome.browser.cookies.CookiesFetcher;
 import org.chromium.chrome.browser.crypto.CipherFactory;
 import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
@@ -356,10 +355,6 @@
 
     private final OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderSupplier =
             new OneshotSupplierImpl<>();
-    // TODO(crbug.com/1108496): Removed after all usages has been migrated to LayoutStateProvider.
-    private final OneshotSupplierImpl<OverviewModeBehavior> mOverviewModeBehaviorSupplier =
-            new OneshotSupplierImpl<>();
-    private OverviewModeBehavior mOverviewModeController;
 
     private ObservableSupplierImpl<EphemeralTabCoordinator> mEphemeralTabCoordinatorSupplier =
             new ObservableSupplierImpl<>();
@@ -620,7 +615,8 @@
 
                     boolean gridTabSwitcherEnabled = TabUiFeatureUtilities.isGridTabSwitcherEnabled(
                             ChromeTabbedActivity.this);
-                    boolean overviewVisible = mOverviewModeController.overviewVisible();
+                    boolean overviewVisible =
+                            mLayoutManager.isLayoutVisible(LayoutType.TAB_SWITCHER);
                     boolean hasNextTab = !(getTabModelSelector().getTotalTabCount() == 0
                             || (!getTabModelSelector().isIncognitoSelected()
                                     && getTabModelSelector().getModel(false).getCount() == 0));
@@ -703,11 +699,9 @@
             // clang-format off
             mLayoutManager = new LayoutManagerChromePhone(compositorViewHolder, mContentContainer,
                     mStartSurfaceSupplier.get(), getTabContentManagerSupplier(),
-                    mOverviewModeBehaviorSupplier,
                     mRootUiCoordinator::getTopUiThemeColorProvider, mJankTracker);
             mLayoutStateProviderSupplier.set(mLayoutManager);
             // clang-format on
-            mOverviewModeController = mLayoutManager;
         }
     }
 
@@ -728,13 +722,11 @@
             ViewGroup tabSwitcherViewHolder = findViewById(R.id.grid_tab_switcher_view_holder);
             mLayoutManager = new LayoutManagerChromeTablet(compositorViewHolder, mContentContainer,
                     mStartSurfaceSupplier.get(), getTabContentManagerSupplier(),
-                    mOverviewModeBehaviorSupplier,
                     mRootUiCoordinator::getTopUiThemeColorProvider, mJankTracker,
                     tabSwitcherViewHolder, mRootUiCoordinator.getScrimCoordinator(),
                     getLifecycleDispatcher());
             mLayoutStateProviderSupplier.set(mLayoutManager);
             // clang-format on
-            mOverviewModeController = mLayoutManager;
         }
     }
 
@@ -1104,11 +1096,6 @@
         return (ChromeTabCreator) super.getCurrentTabCreator();
     }
 
-    @Override
-    public OverviewModeBehavior getOverviewModeBehavior() {
-        return mOverviewModeController;
-    }
-
     /**
      * @return The toolbar button in-product help controller for this activity.
      * TODO(pnoland, https://crbug.com/865801): remove this in favor
@@ -1147,7 +1134,7 @@
         if (mHasDeterminedOverviewStateForCurrentSession) return;
 
         mHasDeterminedOverviewStateForCurrentSession = true;
-        boolean isOverviewVisible = mOverviewModeController.overviewVisible();
+        boolean isOverviewVisible = isInOverviewMode();
 
         if (shouldRefreshAndShowOverview(isOverviewVisible)) {
             if (getCurrentTabModel() != null) {
@@ -1176,8 +1163,7 @@
             showOverview(StartSurfaceState.SHOWING_START);
         }
 
-        if (IntentUtils.isMainIntentFromLauncher(getIntent())
-                && mOverviewModeController.overviewVisible()) {
+        if (IntentUtils.isMainIntentFromLauncher(getIntent()) && isInOverviewMode()) {
             RecordUserAction.record("MobileStartup.UserEnteredTabSwitcher");
         }
         mAppLaunchDrawBlocker.onOverviewPageAvailable(
@@ -1383,7 +1369,7 @@
 
         boolean accessibilityTabSwitcherEnabled =
                 DeviceClassManager.enableAccessibilityLayout(this);
-        if (mOverviewModeController != null && mOverviewModeController.overviewVisible()
+        if (isInOverviewMode()
                 && (mIsAccessibilityTabSwitcherEnabled == null
                         || mIsAccessibilityTabSwitcherEnabled
                                 != DeviceClassManager.enableAccessibilityLayout(this))) {
@@ -2137,8 +2123,8 @@
                     /*isIncognito=*/true);
             RecordUserAction.record("MobileMenuCloseAllIncognitoTabs");
         } else if (id == R.id.focus_url_bar) {
-            boolean isUrlBarVisible = !mOverviewModeController.overviewVisible()
-                    && (!isTablet() || getCurrentTabModel().getCount() != 0);
+            boolean isUrlBarVisible =
+                    !isInOverviewMode() && (!isTablet() || getCurrentTabModel().getCount() != 0);
             if (isUrlBarVisible) {
                 getToolbarManager().setUrlBarFocus(
                         true, OmniboxFocusReason.MENU_OR_KEYBOARD_ACTION);
@@ -2210,7 +2196,7 @@
 
         // If we are in the tab switcher mode (not in the Start surface homepage) and not a tablet,
         // then leave tab switcher mode on back.
-        if (mOverviewModeController.overviewVisible() && !isTablet()
+        if (isInOverviewMode() && !isTablet()
                 && (mStartSurfaceSupplier.get() == null
                         || mStartSurfaceSupplier.get().getController().getStartSurfaceState()
                                 == StartSurfaceState.SHOWN_TABSWITCHER)) {
@@ -2239,7 +2225,7 @@
 
         // If we aren't in the overview mode, we handle the Tab with launchType
         // TabLaunchType.FROM_START_SURFACE or has "OpenedFromStart" property.
-        if (!mOverviewModeController.overviewVisible()
+        if (!isInOverviewMode()
                 && (type == TabLaunchType.FROM_START_SURFACE
                         || StartSurfaceUserData.isOpenedFromStart(currentTab))) {
             if (StartSurfaceUserData.getKeepTab(currentTab)
@@ -2345,12 +2331,14 @@
             // If the runnable doesn't run before the Activity dies, Chrome won't crash but the tab
             // won't be closed (crbug.com/587565).
             mHandler.postDelayed(() -> {
-                boolean hasNextTab =
-                        getCurrentTabModel().getNextTabIfClosed(tabToClose.getId()) != null;
-                getCurrentTabModel().closeTab(tabToClose, false, true, false);
+                boolean uponExit = ChromeFeatureList.isEnabled(
+                        ChromeFeatureList.MOST_RECENT_TAB_ON_BACKGROUND_CLOSE_TAB);
+                Tab nextTab = getCurrentTabModel().getNextTabIfClosed(
+                        tabToClose.getId(), /*uponExit=*/uponExit);
+                getCurrentTabModel().closeTab(tabToClose, nextTab, false, true, false);
 
                 // If there is no next tab to open, enter overview mode.
-                if (!hasNextTab) showOverview(StartSurfaceState.SHOWING_START);
+                if (nextTab == null) showOverview(StartSurfaceState.SHOWING_START);
             }, CLOSE_TAB_ON_MINIMIZE_DELAY_MS);
         }
     }
@@ -2442,7 +2430,7 @@
                 || state == StartSurfaceState.SHOWING_PREVIOUS
                 || state == StartSurfaceState.SHOWING_START);
         if (mIsAccessibilityTabSwitcherEnabled != null && mIsAccessibilityTabSwitcherEnabled
-                && mOverviewModeController != null) {
+                && mLayoutManager != null) {
             // TODO(1200727): This is a temporary fix that should be removed once grid tab switcher
             //                is completely launched. The "start surface" is now created regardless
             //                of the state of accessibility, so we check that mode first and try
@@ -2456,9 +2444,9 @@
             mStartSurfaceSupplier.get().getController().setOverviewState(state, launchOrigin);
         }
 
-        if (mOverviewModeController == null) return;
+        if (mLayoutManager == null) return;
 
-        if (mOverviewModeController.overviewVisible()) {
+        if (isInOverviewMode()) {
             if (didFinishNativeInitialization()) {
                 getCompositorViewHolderSupplier().get().hideKeyboard(() -> {});
             }
@@ -2478,7 +2466,7 @@
     }
 
     private void hideOverview() {
-        assert (mOverviewModeController.overviewVisible());
+        assert (isInOverviewMode());
         if (getCurrentTabModel().getCount() != 0) {
             // Don't hide overview if current tab stack is empty()
             mLayoutManager.showLayout(LayoutType.BROWSING, false);
@@ -2637,8 +2625,8 @@
             mHandler.postDelayed(mShowHistoryRunnable, ViewConfiguration.getLongPressTimeout());
             return super.onKeyDown(keyCode, event);
         }
-        boolean isCurrentTabVisible = !mOverviewModeController.overviewVisible()
-                && (!isTablet() || getCurrentTabModel().getCount() != 0);
+        boolean isCurrentTabVisible =
+                !isInOverviewMode() && (!isTablet() || getCurrentTabModel().getCount() != 0);
         return KeyboardShortcuts.onKeyDown(event, isCurrentTabVisible, true, getTabModelSelector(),
                        /* menuOrKeyboardActionController= */ this, getToolbarManager())
                 || super.onKeyDown(keyCode, event);
@@ -2733,7 +2721,7 @@
 
     @Override
     public boolean isInOverviewMode() {
-        return mOverviewModeController != null && mOverviewModeController.overviewVisible();
+        return mLayoutManager != null && mLayoutManager.isLayoutVisible(LayoutType.TAB_SWITCHER);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 6271d0c5..a7f5f2b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -82,6 +82,7 @@
 import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
 import org.chromium.chrome.browser.back_press.BackPressManager;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
 import org.chromium.chrome.browser.bookmarks.PowerBookmarkUtils;
@@ -89,7 +90,6 @@
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
 import org.chromium.chrome.browser.compositor.layouts.Layout;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl;
-import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
 import org.chromium.chrome.browser.compositor.layouts.SceneChangeObserver;
 import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvider;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
@@ -193,7 +193,6 @@
 import org.chromium.chrome.browser.vr.ArDelegateProvider;
 import org.chromium.chrome.browser.vr.VrModuleProvider;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.accessibility.FontSizePrefs;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
@@ -1741,15 +1740,6 @@
     }
 
     /**
-     * @return OverviewModeBehavior if this activity supports an overview mode and the
-     *         OverviewModeBehavior has been initialized, null otherwise.
-     */
-    @VisibleForTesting
-    public @Nullable OverviewModeBehavior getOverviewModeBehavior() {
-        return null;
-    }
-
-    /**
      * @return Whether native initialization has been completed for this activity.
      */
     public boolean didFinishNativeInitialization() {
@@ -2323,8 +2313,10 @@
 
         if (VrModuleProvider.getDelegate().onBackPressed()) return;
 
-        ArDelegate arDelegate = ArDelegateProvider.getDelegate();
-        if (arDelegate != null && arDelegate.onBackPressed()) return;
+        if (!BackPressManager.isEnabled()) {
+            ArDelegate arDelegate = ArDelegateProvider.getDelegate();
+            if (arDelegate != null && arDelegate.onBackPressed()) return;
+        }
 
         if (mCompositorViewHolderSupplier.hasValue()) {
             LayoutManagerImpl layoutManager =
@@ -2357,6 +2349,9 @@
             // TODO(crbug.com/1279941): consider move to RootUiCoordinator.
             mTextBubbleBackPressHandler = new TextBubbleBackPressHandler();
             mBackPressManager.addHandler(mTextBubbleBackPressHandler, Type.TEXT_BUBBLE);
+            if (ArDelegateProvider.getDelegate() != null) {
+                mBackPressManager.addHandler(ArDelegateProvider.getDelegate(), Type.AR_DELEGATE);
+            }
         }
     }
 
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 18e20e1..7eb0788 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
@@ -79,6 +79,7 @@
                 add(ChromeFeatureList.CCT_RESIZABLE_ALLOW_RESIZE_BY_USER_GESTURE);
                 add(ChromeFeatureList.CCT_RESIZABLE_FOR_FIRST_PARTIES);
                 add(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES);
+                add(ChromeFeatureList.CCT_TOOLBAR_CUSTOMIZATIONS);
                 add(ChromeFeatureList.CLOSE_TAB_SUGGESTIONS);
                 add(ChromeFeatureList.CRITICAL_PERSISTED_TAB_DATA);
                 add(ChromeFeatureList.COMMAND_LINE_ON_NON_ROOTED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
index 7a40f3d5..7412777 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
@@ -15,11 +15,11 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.incognito.IncognitoUtils;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.util.ToolbarUtils;
 import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableListAdapter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
index 45d995d2..17325f8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
@@ -20,9 +20,9 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.SynchronousInitializationActivity;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.TintedDrawable;
 
 import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
index dcbeb10..b30c291 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
@@ -34,9 +34,10 @@
 import org.chromium.chrome.browser.subscriptions.SubscriptionsManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.commerce.PriceTracking.ProductPrice;
+import org.chromium.components.url_formatter.SchemeDisplay;
+import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.url.GURL;
 
@@ -200,6 +201,111 @@
     }
 
     /**
+     * Contains data about a bookmark or bookmark folder.
+     */
+    public static class BookmarkItem {
+        private final String mTitle;
+        private final GURL mUrl;
+        private final BookmarkId mId;
+        private final boolean mIsFolder;
+        private final BookmarkId mParentId;
+        private final boolean mIsEditable;
+        private final boolean mIsManaged;
+        private boolean mForceEditableForTesting;
+        private long mDateAdded;
+        private boolean mRead;
+
+        @VisibleForTesting
+        public BookmarkItem(BookmarkId id, String title, GURL url, boolean isFolder,
+                BookmarkId parentId, boolean isEditable, boolean isManaged, long dateAdded,
+                boolean read) {
+            mId = id;
+            mTitle = title;
+            mUrl = url;
+            mIsFolder = isFolder;
+            mParentId = parentId;
+            mIsEditable = isEditable;
+            mIsManaged = isManaged;
+            mDateAdded = dateAdded;
+            mRead = read;
+        }
+
+        /** Returns the title of the bookmark item. */
+        public String getTitle() {
+            return mTitle;
+        }
+
+        /** Returns the url of the bookmark item. */
+        public GURL getUrl() {
+            return mUrl;
+        }
+
+        /** Returns the string to display for the item's url. */
+        public String getUrlForDisplay() {
+            return UrlFormatter.formatUrlForSecurityDisplay(
+                    getUrl(), SchemeDisplay.OMIT_HTTP_AND_HTTPS);
+        }
+
+        /** Returns whether item is a folder or a bookmark. */
+        public boolean isFolder() {
+            return mIsFolder;
+        }
+
+        /** Returns the parent id of the bookmark item. */
+        public BookmarkId getParentId() {
+            return mParentId;
+        }
+
+        /** Returns whether this bookmark can be edited. */
+        public boolean isEditable() {
+            return mForceEditableForTesting || mIsEditable;
+        }
+
+        /** Returns whether this bookmark's URL can be edited */
+        public boolean isUrlEditable() {
+            return isEditable() && mId.getType() == BookmarkType.NORMAL;
+        }
+
+        /** Returns whether this bookmark can be moved */
+        public boolean isMovable() {
+            return ReadingListUtils.isSwappableReadingListItem(mId) || isReorderable();
+        }
+
+        /** Returns whether this bookmark can be moved */
+        public boolean isReorderable() {
+            return isEditable() && mId.getType() == BookmarkType.NORMAL;
+        }
+
+        /** Returns whether this is a managed bookmark. */
+        public boolean isManaged() {
+            return mIsManaged;
+        }
+
+        /** Returns the {@link BookmarkId}. */
+        public BookmarkId getId() {
+            return mId;
+        }
+
+        /** Retuns the timestamp in milliseconds since epoch that the bookmark is added. */
+        public long getDateAdded() {
+            return mDateAdded;
+        }
+
+        /**
+         * Returns whether the bookmark is read. Only valid for {@link BookmarkType#READING_LIST}.
+         * Defaults to "false" for other types.
+         */
+        public boolean isRead() {
+            return mRead;
+        }
+
+        // TODO(https://crbug.com/1019217): Remove when BookmarkModel is stubbed in tests instead.
+        void forceEditableForTesting() {
+            mForceEditableForTesting = true;
+        }
+    }
+
+    /**
      * Handler to fetch the bookmarks, titles, urls and folder hierarchy.
      * @param profile Profile instance corresponding to the active profile.
      */
@@ -364,11 +470,9 @@
         if (id == null) return null;
 
         if (BookmarkId.SHOPPING_FOLDER.equals(id)) {
-            // TODO(crbug.com/1317801): Add better support for synthetic folders.
             return new BookmarkItem(id, /*title=*/null, /*url=*/null,
                     /*isFolder=*/true, /*parentId=*/getRootFolderId(), /*isEditable=*/false,
-                    /*isManaged=*/false, /*dateAdded=*/0L, /*read=*/false,
-                    /*readingListSwappable=*/false);
+                    /*isManaged=*/false, /*dateAdded=*/0L, /*read=*/false);
         }
 
         return BookmarkBridgeJni.get().getBookmarkByID(
@@ -1194,10 +1298,8 @@
     private static BookmarkItem createBookmarkItem(long id, int type, String title, GURL url,
             boolean isFolder, long parentId, int parentIdType, boolean isEditable,
             boolean isManaged, long dateAdded, boolean read) {
-        BookmarkId bookmarkId = new BookmarkId(id, type);
-        return new BookmarkItem(bookmarkId, title, url, isFolder,
-                new BookmarkId(parentId, parentIdType), isEditable, isManaged, dateAdded, read,
-                ReadingListUtils.isSwappableReadingListItem(bookmarkId));
+        return new BookmarkItem(new BookmarkId(id, type), title, url, isFolder,
+                new BookmarkId(parentId, parentIdType), isEditable, isManaged, dateAdded, read);
     }
 
     @CalledByNative
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
index 90e58c1..edf7b6c4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
@@ -17,9 +17,9 @@
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.SynchronousInitializationActivity;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.TintedDrawable;
 import org.chromium.components.url_formatter.UrlFormatter;
 import org.chromium.url.GURL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java
index 44d9d95..eefb808 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java
@@ -11,8 +11,8 @@
 import androidx.appcompat.content.res.AppCompatResources;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 
 /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
index 223d626..679945e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
@@ -28,10 +28,10 @@
 import org.chromium.base.IntentUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.SynchronousInitializationActivity;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.read_later.ReadingListUtils;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectableItemView;
 
 import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java
index 8fa32bd..dce2aaa4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemRow.java
@@ -10,9 +10,9 @@
 import android.util.AttributeSet;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.ui.favicon.FaviconUtils;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
 import org.chromium.components.favicon.IconType;
 import org.chromium.components.favicon.LargeIconBridge.LargeIconCallback;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
index bc3c1c6..fcb19cfd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -20,6 +20,7 @@
 
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
 import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location;
@@ -36,7 +37,6 @@
 import org.chromium.chrome.browser.ui.signin.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.ui.signin.SigninPromoController.SyncPromoState;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.util.GlobalDiscardableReferencePool;
 import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableListAdapter;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
index 6f55965..bc54f93 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkListEntry.java
@@ -9,9 +9,9 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkType;
-import org.chromium.components.bookmarks.BookmarkItem;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
index 65fd0baa..2194b04 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -21,6 +21,7 @@
 import org.chromium.base.ObserverList;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.commerce.shopping_list.ShoppingFeatures;
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
@@ -29,7 +30,6 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.ui.native_page.BasicNativePage;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.util.ConversionUtils;
 import org.chromium.components.browser_ui.widget.dragreorder.DragStateDelegate;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
index 099aa69..5c28a17a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkModel.java
@@ -10,7 +10,6 @@
 import org.chromium.base.ObserverList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 
 import java.util.ArrayList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
index fb28508..20c7b1f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java
@@ -19,8 +19,8 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.widget.listmenu.BasicListMenu;
 import org.chromium.components.browser_ui.widget.listmenu.ListMenu;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
index c7675ac..fb29e54 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
@@ -14,6 +14,7 @@
 import org.chromium.base.CallbackController;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.PowerBookmarkMetrics.PriceTrackingState;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
@@ -23,7 +24,6 @@
 import org.chromium.chrome.browser.subscriptions.CommerceSubscription;
 import org.chromium.chrome.browser.subscriptions.SubscriptionsManager;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.feature_engagement.EventConstants;
 import org.chromium.ui.modelutil.PropertyModel;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java
index cdc98d1..3665ec2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java
@@ -9,11 +9,11 @@
 import org.chromium.base.lifetime.DestroyChecker;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.BookmarkModel.BookmarkDeleteObserver;
 import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.content_public.browser.UiThreadTaskTraits;
 
 import java.util.Locale;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
index a69a638da..1306f75 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -34,6 +34,7 @@
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.IntentHandler.IncognitoCCTCallerId;
 import org.chromium.chrome.browser.LaunchIntentDispatcher;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider.CustomTabsUiType;
 import org.chromium.chrome.browser.commerce.shopping_list.ShoppingFeatures;
 import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
@@ -52,7 +53,6 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager.SnackbarController;
 import org.chromium.chrome.browser.user_education.UserEducationHelper;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.embedder_support.util.UrlConstants;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
index c291ccb..826ee83 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkShoppingItemRow.java
@@ -19,6 +19,7 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Callback;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.PowerBookmarkMetrics.PriceTrackingState;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.chrome.browser.power_bookmarks.ProductPrice;
@@ -26,7 +27,6 @@
 import org.chromium.chrome.browser.subscriptions.SubscriptionsManager;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.RoundedCornerOutlineProvider;
 import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.image_fetcher.ImageFetcher;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java
index 9fe55b4..7670ca0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipList.java
@@ -11,10 +11,10 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.chips.ChipProperties;
 import org.chromium.components.browser_ui.widget.chips.ChipsCoordinator;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java
index 30e4554d..788a4767 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeader.java
@@ -9,7 +9,7 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.R;
-import org.chromium.components.bookmarks.BookmarkItem;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 
 import java.util.Collections;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
index 81f3272..b85c9a81 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarkswidget/BookmarkWidgetServiceImpl.java
@@ -27,6 +27,7 @@
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
@@ -34,7 +35,6 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.ui.favicon.FaviconUtils;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
 import org.chromium.components.favicon.IconType;
 import org.chromium.components.favicon.LargeIconBridge;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java
deleted file mode 100644
index c32c46af..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/EmptyOverviewModeObserver.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 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.compositor.layouts;
-
-import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior.OverviewModeObserver;
-
-/**
- * An empty implementation of {@link OverviewModeObserver}.
- * DEPRECATED, please use {@link
- * org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver} instead.
- */
-@Deprecated
-public class EmptyOverviewModeObserver implements OverviewModeObserver {
-    @Override
-    public void onOverviewModeStartedShowing(boolean showToolbar) {}
-
-    @Override
-    public void onOverviewModeFinishedShowing() {}
-
-    @Override
-    public void onOverviewModeStartedHiding(boolean showToolbar, boolean delayAnimation) {}
-
-    @Override
-    public void onOverviewModeFinishedHiding() {}
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
index 8d6fcb1..379f702 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -12,11 +12,9 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Callback;
-import org.chromium.base.ObserverList;
 import org.chromium.base.jank_tracker.JankTracker;
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout;
 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
@@ -51,8 +49,8 @@
  * A {@link Layout} controller for the more complicated Chrome browser.  This is currently a
  * superset of {@link LayoutManagerImpl}.
  */
-public class LayoutManagerChrome extends LayoutManagerImpl
-        implements OverviewModeBehavior, ChromeAccessibilityUtil.Observer {
+public class LayoutManagerChrome
+        extends LayoutManagerImpl implements ChromeAccessibilityUtil.Observer {
     // Layouts
     /** An {@link Layout} that should be used as the accessibility tab switcher. */
     protected OverviewListLayout mOverviewListLayout;
@@ -67,11 +65,9 @@
     /** Whether or not animations are enabled.  This can disable certain layouts or effects. */
     private boolean mEnableAnimations = true;
     private boolean mCreatingNtp;
-    private final ObserverList<OverviewModeObserver> mOverviewModeObservers;
     private LayoutStateObserver mTabSwitcherFocusLayoutStateObserver;
 
     protected ObservableSupplier<TabContentManager> mTabContentManagerSupplier;
-    private final OneshotSupplierImpl<OverviewModeBehavior> mOverviewModeBehaviorSupplier;
 
     /**
      * Creates the {@link LayoutManagerChrome} instance.
@@ -81,7 +77,6 @@
      * @param startSurface An interface to talk to the Grid Tab Switcher. If it's NULL, VTS
      *                     should be used, otherwise GTS should be used.
      * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance.
-     * @param overviewModeBehaviorSupplier Supplier of the {@link OverviewModeBehavior}.
      * @param topUiThemeColorProvider {@link ThemeColorProvider} for top UI.
      * @param startSurfaceScrimAnchor {@link ViewGroup} used by start surface layout to show scrim
      *         when overview is visible.
@@ -90,15 +85,12 @@
     public LayoutManagerChrome(LayoutManagerHost host, ViewGroup contentContainer,
             boolean createOverviewLayout, @Nullable StartSurface startSurface,
             ObservableSupplier<TabContentManager> tabContentManagerSupplier,
-            OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier,
             Supplier<TopUiThemeColorProvider> topUiThemeColorProvider, JankTracker jankTracker,
             ViewGroup startSurfaceScrimAnchor, ScrimCoordinator scrimCoordinator) {
         super(host, contentContainer, tabContentManagerSupplier, topUiThemeColorProvider);
         Context context = host.getContext();
         LayoutRenderHost renderHost = host.getLayoutRenderHost();
 
-        mOverviewModeObservers = new ObserverList<OverviewModeObserver>();
-
         // Build Event Filter Handlers
         mToolbarSwipeHandler = createToolbarSwipeHandler(/* supportSwipeDown = */ true);
 
@@ -138,9 +130,6 @@
                 }
             }
         }
-
-        mOverviewModeBehaviorSupplier = overviewModeBehaviorSupplier;
-        mOverviewModeBehaviorSupplier.set(this);
     }
 
     /**
@@ -206,7 +195,6 @@
     @Override
     public void destroy() {
         super.destroy();
-        mOverviewModeObservers.clear();
 
         if (mTabContentManagerSupplier != null) {
             mTabContentManagerSupplier = null;
@@ -269,62 +257,16 @@
     protected void startShowing(Layout layout, boolean animate) {
         mCreatingNtp = false;
         super.startShowing(layout, animate);
-
-        Layout layoutBeingShown = getActiveLayout();
-
-        // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver.
-        // Check if we should notify OverviewModeObservers.
-        if (isOverviewLayout(layoutBeingShown)) {
-            boolean showToolbar = animate && (!mEnableAnimations
-                    || getTabModelSelector().getCurrentModel().getCount() <= 0);
-            notifyObserversStartedShowing(showToolbar);
-        }
-    }
-
-    @Override
-    public void startHiding(int nextTabId, boolean hintAtTabSelection) {
-        super.startHiding(nextTabId, hintAtTabSelection);
-
-        // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver.
-        Layout layoutBeingHidden = getActiveLayout();
-        if (isOverviewLayout(layoutBeingHidden)) {
-            boolean showToolbar = true;
-            if (mEnableAnimations && layoutBeingHidden == mOverviewLayout) {
-                final LayoutTab tab = layoutBeingHidden.getLayoutTab(nextTabId);
-                showToolbar = tab != null ? !tab.showToolbar() : true;
-            }
-
-            boolean creatingNtp = layoutBeingHidden == mOverviewLayout && mCreatingNtp;
-
-            notifyObserversStartedHiding(showToolbar, creatingNtp);
-        }
-    }
-
-    @Override
-    public void doneShowing() {
-        super.doneShowing();
-
-        // TODO(crbug.com/1108496): Remove after migrates to LayoutStateObserver.
-        if (isOverviewLayout(getActiveLayout())) {
-            notifyObserversFinishedShowing();
-        }
     }
 
     @Override
     public void doneHiding() {
-        Layout layoutBeingHidden = getActiveLayout();
-
         if (getNextLayout() == getDefaultLayout()) {
             Tab tab = getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
             emptyCachesExcept(tab != null ? tab.getId() : Tab.INVALID_TAB_ID);
         }
 
         super.doneHiding();
-
-        // TODO(crbug.com/1108496): Remove after migrates to Observer.
-        if (isOverviewLayout(layoutBeingHidden)) {
-            notifyObserversFinishedHiding();
-        }
     }
 
     @Override
@@ -404,22 +346,6 @@
         return mEnableAnimations;
     }
 
-    @Override
-    public boolean overviewVisible() {
-        Layout activeLayout = getActiveLayout();
-        return isOverviewLayout(activeLayout) && !activeLayout.isStartingToHide();
-    }
-
-    @Override
-    public void addOverviewModeObserver(OverviewModeObserver listener) {
-        mOverviewModeObservers.addObserver(listener);
-    }
-
-    @Override
-    public void removeOverviewModeObserver(OverviewModeObserver listener) {
-        mOverviewModeObservers.removeObserver(listener);
-    }
-
     // ChromeAccessibilityUtil.Observer
 
     @Override
@@ -571,36 +497,4 @@
                     .closeTab(lastTab, tab, false, false, false);
         }
     }
-
-    private void notifyObserversStartedShowing(boolean showToolbar) {
-        mOverviewModeBehaviorSupplier.onAvailable((unused) -> {
-            for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) {
-                overviewModeObserver.onOverviewModeStartedShowing(showToolbar);
-            }
-        });
-    }
-
-    private void notifyObserversFinishedShowing() {
-        mOverviewModeBehaviorSupplier.onAvailable((unused) -> {
-            for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) {
-                overviewModeObserver.onOverviewModeFinishedShowing();
-            }
-        });
-    }
-
-    private void notifyObserversStartedHiding(boolean showToolbar, boolean creatingNtp) {
-        mOverviewModeBehaviorSupplier.onAvailable((unused) -> {
-            for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) {
-                overviewModeObserver.onOverviewModeStartedHiding(showToolbar, creatingNtp);
-            }
-        });
-    }
-
-    private void notifyObserversFinishedHiding() {
-        mOverviewModeBehaviorSupplier.onAvailable((unused) -> {
-            for (OverviewModeObserver overviewModeObserver : mOverviewModeObservers) {
-                overviewModeObserver.onOverviewModeFinishedHiding();
-            }
-        });
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
index 375da47..488aeec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
@@ -9,7 +9,6 @@
 
 import org.chromium.base.jank_tracker.JankTracker;
 import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.compositor.layouts.phone.SimpleAnimationLayout;
@@ -40,16 +39,14 @@
      * @param startSurface An interface to talk to the Grid Tab Switcher. If it's NULL, VTS
      *                     should be used, otherwise GTS should be used.
      * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance.
-     * @param overviewModeBehaviorSupplier Supplier of the {@link OverviewModeBehavior}.
      * @param topUiThemeColorProvider {@link ThemeColorProvider} for top UI.
      */
     public LayoutManagerChromePhone(LayoutManagerHost host, ViewGroup contentContainer,
             StartSurface startSurface,
             ObservableSupplier<TabContentManager> tabContentManagerSupplier,
-            OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier,
             Supplier<TopUiThemeColorProvider> topUiThemeColorProvider, JankTracker jankTracker) {
         super(host, contentContainer, true, startSurface, tabContentManagerSupplier,
-                overviewModeBehaviorSupplier, topUiThemeColorProvider, jankTracker, null, null);
+                topUiThemeColorProvider, jankTracker, null, null);
     }
 
     @Override
@@ -144,7 +141,7 @@
             // smoothly.
             getActiveLayout().onTabCreating(sourceId);
         } else if (animationsEnabled()) {
-            if (!overviewVisible()) {
+            if (!isLayoutVisible(LayoutType.TAB_SWITCHER)) {
                 if (getActiveLayout() != null && getActiveLayout().isStartingToHide()) {
                     setNextLayout(mSimpleAnimationLayout, true);
                     // The method Layout#doneHiding() will automatically show the next layout.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
index b4d91e1..f58b69e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -8,7 +8,6 @@
 
 import org.chromium.base.jank_tracker.JankTracker;
 import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.compositor.LayerTitleCache;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
@@ -42,7 +41,6 @@
      * @param contentContainer A {@link ViewGroup} for Android views to be bound to.
      * @param startSurface An interface to talk to the Grid Tab Switcher.
      * @param tabContentManagerSupplier Supplier of the {@link TabContentManager} instance.
-     * @param overviewModeBehaviorSupplier Supplier of the {@link OverviewModeBehavior}.
      * @param topUiThemeColorProvider {@link ThemeColorProvider} for top UI.
      * @param startSurfaceScrimAnchor {@link ViewGroup} used by start surface layout to show scrim
      *         when overview is visible.
@@ -51,14 +49,13 @@
     public LayoutManagerChromeTablet(LayoutManagerHost host, ViewGroup contentContainer,
             StartSurface startSurface,
             ObservableSupplier<TabContentManager> tabContentManagerSupplier,
-            OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier,
             Supplier<TopUiThemeColorProvider> topUiThemeColorProvider, JankTracker jankTracker,
             ViewGroup startSurfaceScrimAnchor, ScrimCoordinator scrimCoordinator,
             ActivityLifecycleDispatcher lifecycleDispatcher) {
         super(host, contentContainer,
                 TabUiFeatureUtilities.isGridTabSwitcherEnabled(host.getContext()), startSurface,
-                tabContentManagerSupplier, overviewModeBehaviorSupplier, topUiThemeColorProvider,
-                jankTracker, startSurfaceScrimAnchor, scrimCoordinator);
+                tabContentManagerSupplier, topUiThemeColorProvider, jankTracker,
+                startSurfaceScrimAnchor, scrimCoordinator);
 
         mTabStripLayoutHelperManager = new StripLayoutHelperManager(host.getContext(), this,
                 mHost.getLayoutRenderHost(), () -> mLayerTitleCache, lifecycleDispatcher);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeBehavior.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeBehavior.java
deleted file mode 100644
index d35ef749..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/OverviewModeBehavior.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2015 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.compositor.layouts;
-
-/**
- * Exposes the current overview mode state as well as a way to listen to overview mode state
- * changes.
- *
- * DEPRECATED, please use {@link org.chromium.chrome.browser.layouts.LayoutStateProvider} instead.
- */
-@Deprecated
-public interface OverviewModeBehavior {
-    /**
-     * An observer that is notified when the overview mode state changes.
-     *
-     * DEPRECATED, please use {@link
-     * org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver} instead.
-     */
-    @Deprecated
-    interface OverviewModeObserver {
-        /**
-         * Called when overview mode starts showing.
-         * @param showToolbar Whether or not to show the normal toolbar when animating into overview
-         * mode.
-         */
-        void onOverviewModeStartedShowing(boolean showToolbar);
-
-        /**
-         * Called when overview mode finishes showing.
-         */
-        void onOverviewModeFinishedShowing();
-
-        /**
-         * Called when overview mode starts hiding.
-         * @param showToolbar    Whether or not to show the normal toolbar when animating out of
-         *                       overview mode.
-         * @param delayAnimation Whether or not to delay any related overview animations until after
-         *                       overview mode is finished hiding.
-         */
-        void onOverviewModeStartedHiding(boolean showToolbar, boolean delayAnimation);
-
-        /**
-         * Called when overview mode finishes hiding.
-         */
-        void onOverviewModeFinishedHiding();
-    }
-
-    /**
-     * @return Whether or not the overview {@link Layout} is visible.
-     */
-    boolean overviewVisible();
-
-    /**
-     * @param listener Registers {@code listener} for overview mode status changes.
-     */
-    void addOverviewModeObserver(OverviewModeObserver listener);
-
-    /**
-     * @param listener Unregisters {@code listener} for overview mode status changes.
-     */
-    void removeOverviewModeObserver(OverviewModeObserver listener);
-}
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 ebcab69..e0f4204 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
@@ -1009,7 +1009,7 @@
         tab.setIsDying(true);
 
         // 3. Fake a selection on the next tab now.
-        Tab nextTab = mModel.getNextTabIfClosed(tab.getId());
+        Tab nextTab = mModel.getNextTabIfClosed(tab.getId(), /*uponExit=*/false);
         if (nextTab != null) tabSelected(time, nextTab.getId(), tab.getId());
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java
index d466189..c81f3ff9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java
@@ -1375,30 +1375,6 @@
     }
 
     /**
-     * Logs the number of impressions and CTR for the previous week for the current user.
-     * @param previousWeekImpressions The number of times the user saw the Contextual Search Bar.
-     * @param previousWeekCtr The CTR expressed as a percentage.
-     */
-    public static void logPreviousWeekCtr(int previousWeekImpressions, int previousWeekCtr) {
-        RecordHistogram.recordCount1MHistogram(
-                "Search.ContextualSearchPreviousWeekImpressions", previousWeekImpressions);
-        RecordHistogram.recordPercentageHistogram(
-                "Search.ContextualSearchPreviousWeekCtr", previousWeekCtr);
-    }
-
-    /**
-     * Logs the number of impressions and CTR for previous 28-day period for the current user.
-     * @param previous28DayImpressions The number of times the user saw the Contextual Search Bar.
-     * @param previous28DayCtr The CTR expressed as a percentage.
-     */
-    public static void logPrevious28DayCtr(int previous28DayImpressions, int previous28DayCtr) {
-        RecordHistogram.recordCount1MHistogram(
-                "Search.ContextualSearchPrevious28DayImpressions", previous28DayImpressions);
-        RecordHistogram.recordPercentageHistogram(
-                "Search.ContextualSearchPrevious28DayCtr", previous28DayCtr);
-    }
-
-    /**
      * Logs a duration since the outcomes (and associated timestamp) were saved in persistent
      * storage.
      * @param durationMs The duration to log, in milliseconds.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java
deleted file mode 100644
index dab1907..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java
+++ /dev/null
@@ -1,236 +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.
-
-package org.chromium.chrome.browser.contextualsearch;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-
-/**
- * Provides a ContextualSearchHeuristic for click-through rate Recording, logging, and eventually
- * suppression.
- * Records impressions and CTR when the Bar is dismissed.
- * Logs "impressions" and "CTR" per user in UMA for the previous week and 28-day period.
- * An impression is a view of our UX (the Bar) and CTR is the "click-through rate" (user opens of
- * the Bar).
- * This class also implements the device-based native integer storage required by the
- * native {@code CtrAggregator} class.
- */
-public class CtrSuppression extends ContextualSearchHeuristic {
-    private long mNativePointer;
-
-    private final SharedPreferencesManager mPreferenceManager;
-
-    /**
-     * Constructs an object that tracks impressions and clicks per user to produce CTR and
-     * impression metrics.
-     */
-    CtrSuppression() {
-        mPreferenceManager = SharedPreferencesManager.getInstance();
-
-        // This needs to be done last in this constructor because the native code may call
-        // into this object.
-        mNativePointer = CtrSuppressionJni.get().init(CtrSuppression.this);
-    }
-
-    /**
-     * This method should be called to clean up storage when an instance of this class is
-     * no longer in use.
-     */
-    public void destroy() {
-        if (mNativePointer != 0L) {
-            CtrSuppressionJni.get().destroy(mNativePointer, CtrSuppression.this);
-        }
-    }
-
-    // ============================================================================================
-    // ContextualSearchHeuristic overrides.
-    // ============================================================================================
-
-    @Override
-    protected boolean isConditionSatisfiedAndEnabled() {
-        return false;
-    }
-
-    @Override
-    protected void logConditionState() {
-        // Since the CTR for previous time periods never changes, we only need to write to the UMA
-        // log when we may have moved to a new week, or we have new persistent data.
-        // We cache the current week in persistent storage so we can tell when it changes.
-        boolean didWeekChange = didWeekChange(
-                CtrSuppressionJni.get().getCurrentWeekNumber(mNativePointer, CtrSuppression.this));
-        if (didWeekChange) {
-            if (CtrSuppressionJni.get().hasPreviousWeekData(mNativePointer, CtrSuppression.this)) {
-                int previousWeekImpressions = CtrSuppressionJni.get().getPreviousWeekImpressions(
-                        mNativePointer, CtrSuppression.this);
-                int previousWeekCtr = (int) (100
-                        * CtrSuppressionJni.get().getPreviousWeekCtr(
-                                mNativePointer, CtrSuppression.this));
-                ContextualSearchUma.logPreviousWeekCtr(previousWeekImpressions, previousWeekCtr);
-            }
-
-            if (CtrSuppressionJni.get().hasPrevious28DayData(mNativePointer, CtrSuppression.this)) {
-                int previous28DayImpressions = CtrSuppressionJni.get().getPrevious28DayImpressions(
-                        mNativePointer, CtrSuppression.this);
-                int previous28DayCtr = (int) (100
-                        * CtrSuppressionJni.get().getPrevious28DayCtr(
-                                mNativePointer, CtrSuppression.this));
-                ContextualSearchUma.logPrevious28DayCtr(previous28DayImpressions, previous28DayCtr);
-            }
-        }
-    }
-
-    @Override
-    protected void logResultsSeen(boolean wasSearchContentViewSeen, boolean wasActivatedByTap) {
-        if (wasActivatedByTap) {
-            CtrSuppressionJni.get().recordImpression(
-                    mNativePointer, CtrSuppression.this, wasSearchContentViewSeen);
-        }
-    }
-
-    @Override
-    protected void logRankerTapSuppression(ContextualSearchInteractionRecorder recorder) {
-        if (CtrSuppressionJni.get().hasPreviousWeekData(mNativePointer, CtrSuppression.this)) {
-            int previousWeekImpressions = CtrSuppressionJni.get().getPreviousWeekImpressions(
-                    mNativePointer, CtrSuppression.this);
-            int previousWeekCtr = (int) (100
-                    * CtrSuppressionJni.get().getPreviousWeekCtr(
-                            mNativePointer, CtrSuppression.this));
-            recorder.logFeature(
-                    ContextualSearchInteractionRecorder.Feature.PREVIOUS_WEEK_IMPRESSIONS_COUNT,
-                    previousWeekImpressions);
-            recorder.logFeature(
-                    ContextualSearchInteractionRecorder.Feature.PREVIOUS_WEEK_CTR_PERCENT,
-                    previousWeekCtr);
-        }
-
-        if (CtrSuppressionJni.get().hasPrevious28DayData(mNativePointer, CtrSuppression.this)) {
-            int previous28DayImpressions = CtrSuppressionJni.get().getPrevious28DayImpressions(
-                    mNativePointer, CtrSuppression.this);
-            int previous28DayCtr = (int) (100
-                    * CtrSuppressionJni.get().getPrevious28DayCtr(
-                            mNativePointer, CtrSuppression.this));
-            recorder.logFeature(
-                    ContextualSearchInteractionRecorder.Feature.PREVIOUS_28DAY_IMPRESSIONS_COUNT,
-                    previous28DayImpressions);
-            recorder.logFeature(
-                    ContextualSearchInteractionRecorder.Feature.PREVIOUS_28DAY_CTR_PERCENT,
-                    previous28DayCtr);
-        }
-    }
-
-    /** @return the CTR from the previous 28 days, or 0 if no data. */
-    int getPrevious28DayCtr() {
-        if (!CtrSuppressionJni.get().hasPrevious28DayData(mNativePointer, CtrSuppression.this)) {
-            return 0;
-        }
-        return (int) (100
-                * CtrSuppressionJni.get().getPrevious28DayCtr(mNativePointer, CtrSuppression.this));
-    }
-
-    // ============================================================================================
-    // Device integer storage.
-    // ============================================================================================
-
-    @CalledByNative
-    void writeClicks(int weekRemainder, int value) {
-        mPreferenceManager.writeInt(getKeyForClicksWeek(weekRemainder), value);
-    }
-
-    @CalledByNative
-    void writeImpressions(int weekRemainder, int value) {
-        mPreferenceManager.writeInt(getKeyForImpressionsWeek(weekRemainder), value);
-    }
-
-    @CalledByNative
-    void writeOldestWeek(int value) {
-        mPreferenceManager.writeInt(ChromePreferenceKeys.CONTEXTUAL_SEARCH_OLDEST_WEEK, value);
-    }
-
-    @CalledByNative
-    void writeNewestWeek(int value) {
-        mPreferenceManager.writeInt(ChromePreferenceKeys.CONTEXTUAL_SEARCH_NEWEST_WEEK, value);
-    }
-
-    @CalledByNative
-    int readClicks(int weekRemainder) {
-        return mPreferenceManager.readInt(getKeyForClicksWeek(weekRemainder));
-    }
-
-    @CalledByNative
-    int readImpressions(int weekRemainder) {
-        return mPreferenceManager.readInt(getKeyForImpressionsWeek(weekRemainder));
-    }
-
-    @CalledByNative
-    int readOldestWeek() {
-        return mPreferenceManager.readInt(ChromePreferenceKeys.CONTEXTUAL_SEARCH_OLDEST_WEEK);
-    }
-
-    @CalledByNative
-    int readNewestWeek() {
-        return mPreferenceManager.readInt(ChromePreferenceKeys.CONTEXTUAL_SEARCH_NEWEST_WEEK);
-    }
-
-    private String getKeyForClicksWeek(int weekRemainder) {
-        return ChromePreferenceKeys.CONTEXTUAL_SEARCH_CLICKS_WEEK_PREFIX.createKey(weekRemainder);
-    }
-
-    private String getKeyForImpressionsWeek(int weekRemainder) {
-        return ChromePreferenceKeys.CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_PREFIX.createKey(
-                weekRemainder);
-    }
-
-    // ============================================================================================
-    // Private helpers.
-    // ============================================================================================
-
-    /**
-     * Updates the "current week number" preference and returns whether the week has changed.
-     * @param currentWeekNumber The week number of the current week.
-     * @return {@code true} if the current week number is different from the last time we checked,
-     *         or we have never checked.
-     */
-    private boolean didWeekChange(int currentWeekNumber) {
-        if (mPreferenceManager.readInt(ChromePreferenceKeys.CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER)
-                == currentWeekNumber) {
-            return false;
-        } else {
-            mPreferenceManager.writeInt(
-                    ChromePreferenceKeys.CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER, currentWeekNumber);
-            return true;
-        }
-    }
-
-    // ============================================================================================
-    // Native callback support.
-    // ============================================================================================
-
-    @CalledByNative
-    private void clearNativePointer() {
-        assert mNativePointer != 0;
-        mNativePointer = 0;
-    }
-
-    // ============================================================================================
-    // Native methods.
-    // ============================================================================================
-
-    @NativeMethods
-    interface Natives {
-        long init(CtrSuppression caller);
-
-        void destroy(long nativeCtrSuppression, CtrSuppression caller);
-        void recordImpression(long nativeCtrSuppression, CtrSuppression caller, boolean wasSeen);
-        int getCurrentWeekNumber(long nativeCtrSuppression, CtrSuppression caller);
-        boolean hasPreviousWeekData(long nativeCtrSuppression, CtrSuppression caller);
-        int getPreviousWeekImpressions(long nativeCtrSuppression, CtrSuppression caller);
-        float getPreviousWeekCtr(long nativeCtrSuppression, CtrSuppression caller);
-        boolean hasPrevious28DayData(long nativeCtrSuppression, CtrSuppression caller);
-        int getPrevious28DayImpressions(long nativeCtrSuppression, CtrSuppression caller);
-        float getPrevious28DayCtr(long nativeCtrSuppression, CtrSuppression caller);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java
index b58e400..96d9158 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java
@@ -11,8 +11,6 @@
  * and can be used as signals to drive an ML tap suppression model.
  */
 public class TapSuppressionHeuristics extends ContextualSearchHeuristics {
-    private CtrSuppression mCtrSuppression;
-
     /**
      * Gets all the heuristics needed for Tap suppression.
      * @param selectionController The {@link ContextualSearchSelectionController}.
@@ -30,8 +28,6 @@
             ContextualSearchContext contextualSearchContext, int tapDurationMs,
             boolean wasSelectionEmptyBeforeTap, int fontSizeDips, int elementRunLength) {
         super();
-        mCtrSuppression = new CtrSuppression();
-        mHeuristics.add(mCtrSuppression);
         mHeuristics.add(new EngagementSuppression());
         mHeuristics.add(new RecentScrollTapSuppression(selectionController));
         mHeuristics.add(new TapFarFromPreviousSuppression(
@@ -49,17 +45,6 @@
         mHeuristics.add(quickAnswersHeuristic);
     }
 
-    /**
-     * This method should be called to clean up storage when an instance of this class is
-     * no longer in use.
-     */
-    public void destroy() {
-        if (mCtrSuppression != null) {
-            mCtrSuppression.destroy();
-            mCtrSuppression = null;
-        }
-    }
-
     @Override
     public void logResultsSeen(boolean wasSearchContentViewSeen, boolean wasActivatedByTap) {
         for (ContextualSearchHeuristic heuristic : mHeuristics) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index 8641b36..f0b445a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -860,6 +860,9 @@
 
     @Override
     public @CloseButtonPosition int getCloseButtonPosition() {
+        if (!CachedFeatureFlags.isEnabled(ChromeFeatureList.CCT_TOOLBAR_CUSTOMIZATIONS)) {
+            return CLOSE_BUTTON_POSITION_DEFAULT;
+        }
         return IntentUtils.safeGetIntExtra(
                 mIntent, EXTRA_CLOSE_BUTTON_POSITION, CLOSE_BUTTON_POSITION_DEFAULT);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java
index 73e5aba..52b85bf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/read_later/ReadingListUtils.java
@@ -11,6 +11,7 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.bookmarks.BookmarkUndoController;
 import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
@@ -18,7 +19,6 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.embedder_support.util.UrlUtilities;
@@ -51,7 +51,7 @@
         BookmarkUndoController.createOneshotBookmarkUndoController(
                 activity, bookmarkModel, snackbarManager);
         bookmarkModel.finishLoadingBookmarkModel(() -> {
-            BookmarkItem bookmarkItem =
+            BookmarkBridge.BookmarkItem bookmarkItem =
                     bookmarkModel.getReadingListItem(currentTab.getOriginalUrl());
             bookmarkModel.deleteBookmarks(bookmarkItem.getId());
         });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java
index 0d7710a..e3170be 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java
@@ -10,7 +10,6 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.base.supplier.ObservableSupplier;
-import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.layouts.LayoutManager;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
@@ -30,8 +29,7 @@
      *
      * @param window The {@link Window} associated with the containing activity.
      * @param tabModelSelector The {@link TabModelSelector} for the containing activity.
-     * @param layoutManagerSupplier An {@link ObservableSupplier} for the
-     *         {@link OverviewModeBehavior} associated with the containing activity.
+     * @param layoutManagerSupplier {@link LayoutManager} associated with the containing activity.
      * @param mFullscreenManager The {@link FullscreenManager} used for containing activity
      */
     public TabbedSystemUiCoordinator(Window window, TabModelSelector tabModelSelector,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
index 9be0e867..a0abb1f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java
@@ -292,7 +292,7 @@
     }
 
     @Override
-    public Tab getNextTabIfClosed(int id) {
+    public Tab getNextTabIfClosed(int id, boolean uponExit) {
         Tab tabToClose = TabModelUtils.getTabById(this, id);
         Tab currentTab = TabModelUtils.getCurrentTab(this);
         if (tabToClose == null) return currentTab;
@@ -301,9 +301,14 @@
         Tab adjacentTab = getTabAt((closingTabIndex == 0) ? 1 : closingTabIndex - 1);
         Tab parentTab =
                 findTabInAllTabModels(CriticalPersistedTabData.from(tabToClose).getParentId());
+        Tab nextMostRecentTab = null;
+        if (uponExit) {
+            nextMostRecentTab = TabModelUtils.getMostRecentTab(this, id);
+        }
 
         // Determine which tab to select next according to these rules:
         //   * If closing a background tab, keep the current tab selected.
+        //   * Otherwise, if closing the tab upon exit select the next most recent tab.
         //   * Otherwise, if not in overview mode, select the parent tab if it exists.
         //   * Otherwise, select an adjacent tab if one exists.
         //   * Otherwise, if closing the last incognito tab, select the current normal tab.
@@ -313,6 +318,8 @@
             nextTab = TabModelUtils.getCurrentTab(mModelDelegate.getCurrentModel());
         } else if (tabToClose != currentTab && currentTab != null && !currentTab.isClosing()) {
             nextTab = currentTab;
+        } else if (nextMostRecentTab != null && !nextMostRecentTab.isClosing()) {
+            nextTab = nextMostRecentTab;
         } else if (parentTab != null && !parentTab.isClosing()
                 && mNextTabPolicySupplier.get() == NextTabPolicy.HIERARCHICAL) {
             nextTab = parentTab;
@@ -598,8 +605,9 @@
 
         Tab currentTabInModel = TabModelUtils.getCurrentTab(this);
         Tab adjacentTabInModel = getTabAt(closingTabIndex == 0 ? 1 : closingTabIndex - 1);
-        Tab nextTab =
-                recommendedNextTab == null ? getNextTabIfClosed(closingTabId) : recommendedNextTab;
+        Tab nextTab = recommendedNextTab == null
+                ? getNextTabIfClosed(closingTabId, /*uponExit=*/false)
+                : recommendedNextTab;
 
         // TODO(dtrainor): Update the list of undoable tabs instead of committing it.
         if (updatePendingTabClosureManager) commitAllTabClosures();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java
index 303377e..a7ecf88 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.vr;
 
 import org.chromium.base.annotations.UsedByReflection;
+import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.components.webxr.ArCoreJavaUtils;
 import org.chromium.components.webxr.ArDelegate;
 
@@ -26,4 +27,14 @@
     public boolean hasActiveArSession() {
         return ArCoreJavaUtils.hasActiveArSession();
     }
+
+    @Override
+    public void handleBackPress() {
+        onBackPressed();
+    }
+
+    @Override
+    public ObservableSupplier<Boolean> getHandleBackPressChangedSupplier() {
+        return ArCoreJavaUtils.hasActiveArSessionSupplier();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java
index e99911e..061373fa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkDataProvider.java
@@ -25,6 +25,13 @@
  * Provides access to more detail about webapks.
  */
 public class WebApkDataProvider {
+    // Contains the details to return for an offline app when testing.
+    private static WebappInfo sWebappInfoForTesting;
+
+    public static void setWebappInfoForTesting(WebappInfo webappInfo) {
+        sWebappInfoForTesting = webappInfo;
+    }
+
     /**
      * Converts a color value to a hex string.
      * @param color The color to convert.
@@ -37,6 +44,8 @@
     }
 
     private static WebappInfo getPartialWebappInfo(String url) {
+        if (sWebappInfoForTesting != null) return sWebappInfoForTesting;
+
         Context appContext = ContextUtils.getApplicationContext();
         String packageName = WebApkValidator.queryFirstWebApkPackage(appContext, url);
         return WebappInfo.create(WebApkIntentDataProviderFactory.create(new Intent(), packageName,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
index 7b747437..b965248 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
@@ -215,13 +215,15 @@
         // App menu is shown during setup.
         Assert.assertTrue("App menu should be showing.", mAppMenuHandler.isAppMenuShowing());
         Assert.assertFalse("Overview shouldn't be showing.",
-                mActivityTestRule.getActivity().getOverviewModeBehavior().overviewVisible());
+                mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                        LayoutType.TAB_SWITCHER));
 
         LayoutTestUtils.startShowingAndWaitForLayout(
                 mActivityTestRule.getActivity().getLayoutManager(), LayoutType.TAB_SWITCHER, false);
 
         Assert.assertTrue("Overview should be showing.",
-                mActivityTestRule.getActivity().getOverviewModeBehavior().overviewVisible());
+                mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                        LayoutType.TAB_SWITCHER));
         Assert.assertFalse("App menu shouldn't be showing.", mAppMenuHandler.isAppMenuShowing());
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             Assert.assertTrue("App menu should be allowed to show.",
@@ -230,12 +232,11 @@
         });
         showAppMenuAndAssertMenuShown();
 
-        TestThreadUtils.runOnUiThreadBlocking(
-                ()
-                        -> mActivityTestRule.getActivity().getLayoutManager().showLayout(
-                                LayoutType.BROWSING, false));
+        LayoutTestUtils.startShowingAndWaitForLayout(
+                mActivityTestRule.getActivity().getLayoutManager(), LayoutType.BROWSING, false);
         Assert.assertFalse("Overview shouldn't be showing.",
-                mActivityTestRule.getActivity().getOverviewModeBehavior().overviewVisible());
+                mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                        LayoutType.TAB_SWITCHER));
         CriteriaHelper.pollUiThread(
                 () -> !mAppMenuHandler.isAppMenuShowing(), "App menu shouldn't be showing.");
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
index a3997a2..bc8e8a3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java
@@ -20,6 +20,7 @@
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RequiresRestart;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
 import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkType;
@@ -31,7 +32,6 @@
 import org.chromium.chrome.test.util.BookmarkTestUtil;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.url.GURL;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkEditTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkEditTest.java
index b3a9cb21..c63f70e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkEditTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkEditTest.java
@@ -28,12 +28,12 @@
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
 import org.chromium.chrome.test.util.BookmarkTestUtil;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.url.GURL;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java
index 0643ed09..6eb00e4f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java
@@ -17,11 +17,11 @@
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
 import org.chromium.chrome.test.util.BookmarkTestUtil;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.url.GURL;
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
index 67643e34..821f521 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java
@@ -64,6 +64,7 @@
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.app.metrics.LaunchCauseMetrics;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
 import org.chromium.chrome.browser.customtabs.CustomTabActivity;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
@@ -92,7 +93,6 @@
 import org.chromium.chrome.test.util.MenuUtils;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.widget.RecyclerViewTestUtils;
 import org.chromium.components.browser_ui.widget.listmenu.ListMenuButton;
@@ -1467,7 +1467,8 @@
         // Verify that bookmark 1 is editable (so more button can be triggered) but not movable.
         BookmarkId partnerBookmarkId1 = getReorderAdapter().getIdByPosition(0);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            BookmarkItem partnerBookmarkItem1 = mBookmarkModel.getBookmarkById(partnerBookmarkId1);
+            BookmarkBridge.BookmarkItem partnerBookmarkItem1 =
+                    mBookmarkModel.getBookmarkById(partnerBookmarkId1);
             partnerBookmarkItem1.forceEditableForTesting();
             Assert.assertEquals("Incorrect bookmark type for item 1", BookmarkType.PARTNER,
                     partnerBookmarkId1.getType());
@@ -1487,7 +1488,8 @@
         // Verify that bookmark 2 is not movable.
         BookmarkId partnerBookmarkId2 = getReorderAdapter().getIdByPosition(1);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            BookmarkItem partnerBookmarkItem2 = mBookmarkModel.getBookmarkById(partnerBookmarkId2);
+            BookmarkBridge.BookmarkItem partnerBookmarkItem2 =
+                    mBookmarkModel.getBookmarkById(partnerBookmarkId2);
             partnerBookmarkItem2.forceEditableForTesting();
             Assert.assertEquals("Incorrect bookmark type for item 2", BookmarkType.PARTNER,
                     partnerBookmarkId2.getType());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
index 105ad13..b41cdc4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -45,7 +45,6 @@
 import org.chromium.base.MathUtils;
 import org.chromium.base.jank_tracker.DummyJankTracker;
 import org.chromium.base.supplier.ObservableSupplierImpl;
-import org.chromium.base.supplier.OneshotSupplierImpl;
 import org.chromium.base.test.UiThreadTest;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -214,12 +213,9 @@
 
         ObservableSupplierImpl<TabContentManager> tabContentManagerSupplier =
                 new ObservableSupplierImpl<>();
-        OneshotSupplierImpl<OverviewModeBehavior> overviewModeBehaviorSupplier =
-                new OneshotSupplierImpl<>();
 
         mManagerPhone = new LayoutManagerChromePhone(layoutManagerHost, container, mStartSurface,
-                tabContentManagerSupplier, overviewModeBehaviorSupplier,
-                () -> mTopUiThemeColorProvider, new DummyJankTracker());
+                tabContentManagerSupplier, () -> mTopUiThemeColorProvider, new DummyJankTracker());
         verify(mStartSurfaceController)
                 .addOverviewModeObserver(mStartSurfaceOverviewModeCaptor.capture());
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
index bef7e910..7311cdb 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/firstrun/TosAndUmaFirstRunFragmentWithEnterpriseSupportTest.java
@@ -9,6 +9,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
 
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -61,6 +62,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.ChromeRenderTestRule;
 import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
+import org.chromium.components.externalauth.ExternalAuthUtils;
 import org.chromium.components.policy.PolicyService;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 
@@ -120,6 +122,8 @@
     public EnterpriseInfo mMockEnterpriseInfo;
     @Mock
     private PrivacyPreferencesManagerImpl mPrivacyPreferencesManagerMock;
+    @Mock
+    private ExternalAuthUtils mExternalAuthUtilsMock;
 
     @Spy
     public ChromeBrowserInitializer mInitializer;
@@ -157,6 +161,8 @@
                 .handlePostNativeStartup(anyBoolean(), any(BrowserParts.class));
         ChromeBrowserInitializer.setForTesting(mInitializer);
 
+        when(mExternalAuthUtilsMock.canUseGooglePlayServices(any())).thenReturn(true);
+        ExternalAuthUtils.setInstanceForTesting(mExternalAuthUtilsMock);
         FirstRunAppRestrictionInfo.setInitializedInstanceForTest(mMockAppRestrictionInfo);
         ToSAndUMAFirstRunFragment.setShowUmaCheckBoxForTesting(true);
         PolicyServiceFactory.setPolicyServiceForTest(mPolicyService);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilTest.java
index 60052898..c14eec9c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilTest.java
@@ -156,14 +156,16 @@
                                 ReturnToChromeUtil.shouldShowStartSurfaceAsTheHomePage(
                                         mActivityTestRule.getActivity())));
 
-        Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                LayoutType.TAB_SWITCHER));
 
         waitTabModelRestoration();
         assertEquals(0,
                 RecordHistogram.getHistogramTotalCountForTesting(
                         ReturnToChromeUtil.UMA_TIME_TO_GTS_FIRST_MEANINGFUL_PAINT));
         assertEquals(2, mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount());
-        Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                LayoutType.TAB_SWITCHER));
     }
 
     /**
@@ -193,8 +195,8 @@
                                         mActivityTestRule.getActivity())));
 
         if (!mActivityTestRule.getActivity().isTablet()) {
-            Assert.assertFalse(
-                    mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
         }
 
         waitTabModelRestoration();
@@ -202,8 +204,8 @@
         // 3 tabs since we created NTP in this case.
         assertEquals(3, mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount());
         if (!mActivityTestRule.getActivity().isTablet()) {
-            Assert.assertFalse(
-                    mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            Assert.assertFalse(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
         }
     }
 
@@ -267,14 +269,16 @@
                                 mActivityTestRule.getActivity())));
 
         if (!mActivityTestRule.getActivity().isTablet()) {
-            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
         }
 
         waitTabModelRestoration();
         // Not 3 because we don't create a tab for NTP in this case.
         assertEquals(2, mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount());
         if (!mActivityTestRule.getActivity().isTablet()) {
-            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
         }
     }
 
@@ -366,7 +370,8 @@
         mActivityTestRule.startMainActivityFromLauncher();
 
         if (!mActivityTestRule.getActivity().isTablet()) {
-            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+            Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                    LayoutType.TAB_SWITCHER));
         }
 
         CriteriaHelper.pollUiThread(
@@ -443,7 +448,8 @@
 
         mActivityTestRule.startMainActivityFromLauncher();
 
-        Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
+        Assert.assertTrue(mActivityTestRule.getActivity().getLayoutManager().isLayoutVisible(
+                LayoutType.TAB_SWITCHER));
 
         CriteriaHelper.pollUiThread(
                 mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDefaultOfflineTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDefaultOfflineTest.java
new file mode 100644
index 0000000..6c4c924d
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappDefaultOfflineTest.java
@@ -0,0 +1,120 @@
+// 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.webapps;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Intent;
+import android.graphics.Color;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
+import org.chromium.chrome.browser.browserservices.intents.WebappInfo;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.offlinepages.OfflineTestUtil;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
+import org.chromium.chrome.test.util.browser.webapps.WebappTestPage;
+import org.chromium.content_public.browser.test.NativeLibraryTestUtils;
+import org.chromium.content_public.browser.test.util.JavaScriptUtils;
+
+/**
+ * Tests for the Default Offline behavior.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public class WebappDefaultOfflineTest {
+    public final WebappActivityTestRule mActivityTestRule = new WebappActivityTestRule();
+
+    @Before
+    public void setUp() {
+        NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess();
+    }
+
+    /**
+     * Simulates what happens when you launch a web app when the network is down.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Webapps"})
+    @EnableFeatures({ChromeFeatureList.PWA_DEFAULT_OFFLINE_PAGE})
+    public void testDefaultOffline() throws Exception {
+        // Make sure the navigations to the test app result in a 404 error.
+        final String testAppUrl =
+                WebappTestPage.getServiceWorkerUrl(mActivityTestRule.getTestServer());
+        OfflineTestUtil.interceptWithOfflineError(testAppUrl);
+
+        WebApkDataProvider.setWebappInfoForTesting(getDefaultWebappInfo(testAppUrl));
+
+        // Launch the test app.
+        runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent());
+
+        // Ensure that web_app_default_offline.html is showing the correct values.
+        Tab tab = mActivityTestRule.getActivity().getActivityTab();
+        assertEquals("\"shortname\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(
+                        tab.getWebContents(), "document.getElementById('app-name').textContent;"));
+        assertEquals("\"No internet\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(),
+                        "document.getElementById('default-web-app-msg').textContent;"));
+        assertEquals("\"data:image/png;base64," + WebappActivityTestRule.TEST_ICON + "\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(
+                        tab.getWebContents(), "document.getElementById('icon').src;"));
+        assertEquals("\" #00FF00\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(),
+                        "getComputedStyle(document.documentElement).getPropertyValue("
+                                + "'--customized-background-color');"));
+        assertEquals("\" #00FF00\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(),
+                        "getComputedStyle(document.documentElement).getPropertyValue("
+                                + "'--dark-mode-background-color');"));
+        assertEquals("\" #0000FF\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(),
+                        "getComputedStyle(document.documentElement).getPropertyValue("
+                                + "'--theme-color');"));
+        assertEquals("\" #0000FF\"",
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(),
+                        "getComputedStyle(document.documentElement).getPropertyValue("
+                                + "'--dark-mode-theme-color');"));
+    }
+
+    private WebappInfo getDefaultWebappInfo(String url) {
+        String id = "webapp_id";
+        String name = "longName";
+        String shortName = "shortname";
+        long backgroundColor = Color.argb(0xff, 0, 0xff, 0);
+        long themeColor = Color.argb(0xff, 0, 0, 0xff);
+
+        Intent intent = new Intent();
+        intent.putExtra(WebappConstants.EXTRA_ID, id);
+        intent.putExtra(WebappConstants.EXTRA_NAME, name);
+        intent.putExtra(WebappConstants.EXTRA_SHORT_NAME, shortName);
+        intent.putExtra(WebappConstants.EXTRA_URL, url);
+        intent.putExtra(WebappConstants.EXTRA_ICON, WebappActivityTestRule.TEST_ICON);
+        intent.putExtra(WebappConstants.EXTRA_BACKGROUND_COLOR, backgroundColor);
+        intent.putExtra(WebappConstants.EXTRA_THEME_COLOR, themeColor);
+
+        return WebappInfo.create(WebappIntentDataProviderFactory.create(intent));
+    }
+
+    private WebappActivity runWebappActivityAndWaitForIdle(Intent intent) {
+        return runWebappActivityAndWaitForIdleWithUrl(
+                intent, WebappTestPage.getServiceWorkerUrl(mActivityTestRule.getTestServer()));
+    }
+
+    private WebappActivity runWebappActivityAndWaitForIdleWithUrl(Intent intent, String url) {
+        mActivityTestRule.startWebappActivity(intent.putExtra(WebappConstants.EXTRA_URL, url));
+        return mActivityTestRule.getActivity();
+    }
+}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
index 2521d51..45ec1f10 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ReadingListSectionHeaderTest.java
@@ -20,9 +20,9 @@
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 
 import java.util.ArrayList;
@@ -42,8 +42,8 @@
 
     private BookmarkListEntry createReadingListEntry(long id, boolean read, int dateAdded) {
         BookmarkId bookmarkId = new BookmarkId(id, BookmarkType.READING_LIST);
-        BookmarkItem bookmarkItem = new BookmarkItem(bookmarkId, null, null, false, null, false,
-                false, dateAdded, read, /*readingListSwappable=*/false);
+        BookmarkItem bookmarkItem = new BookmarkItem(
+                bookmarkId, null, null, false, null, false, false, dateAdded, read);
         return BookmarkListEntry.createBookmarkEntry(bookmarkItem, /*powerBookmarkMeta=*/null);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/read_later/ReadingListUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/read_later/ReadingListUtilsUnitTest.java
index 71e8b4ed..7edef7e 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/read_later/ReadingListUtilsUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/read_later/ReadingListUtilsUnitTest.java
@@ -26,12 +26,12 @@
 import org.chromium.base.FeatureList.TestValues;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
 import org.chromium.chrome.browser.bookmarks.BookmarkModel;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.components.bookmarks.BookmarkId;
-import org.chromium.components.bookmarks.BookmarkItem;
 import org.chromium.components.bookmarks.BookmarkType;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.url.GURL;
@@ -189,8 +189,7 @@
         BookmarkId existingBookmarkId = new BookmarkId(0, BookmarkType.NORMAL);
         BookmarkItem existingBookmark = new BookmarkItem(existingBookmarkId, "Test",
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL), /*isFolder=*/false, /*parent=*/null,
-                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false,
-                /*readingListSwappable=*/false);
+                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false);
         BookmarkBridge bookmarkBridge = Mockito.mock(BookmarkBridge.class);
         doReturn(existingBookmark).when(bookmarkBridge).getBookmarkById(existingBookmarkId);
         BookmarkId newBookmarkId = new BookmarkId(0, BookmarkType.READING_LIST);
@@ -219,8 +218,7 @@
         BookmarkId existingBookmarkId = new BookmarkId(0, BookmarkType.READING_LIST);
         BookmarkItem existingBookmark = new BookmarkItem(existingBookmarkId, "Test",
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL), /*isFolder=*/false, /*parent=*/null,
-                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false,
-                /*readingListSwappable=*/false);
+                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false);
         BookmarkBridge bookmarkBridge = Mockito.mock(BookmarkBridge.class);
         doReturn(existingBookmark).when(bookmarkBridge).getBookmarkById(existingBookmarkId);
         BookmarkId newBookmarkId = new BookmarkId(0, BookmarkType.NORMAL);
@@ -249,13 +247,11 @@
         BookmarkId existingBookmarkId1 = new BookmarkId(1, BookmarkType.READING_LIST);
         BookmarkItem existingBookmark1 = new BookmarkItem(existingBookmarkId1, "Test1",
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL), /*isFolder=*/false, /*parent=*/null,
-                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false,
-                /*readingListSwappable=*/false);
+                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false);
         BookmarkId existingBookmarkId2 = new BookmarkId(2, BookmarkType.READING_LIST);
         BookmarkItem existingBookmark2 = new BookmarkItem(existingBookmarkId2, "Test2",
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL), /*isFolder=*/false, /*parent=*/null,
-                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false,
-                /*readingListSwappable=*/false);
+                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false);
         BookmarkBridge bookmarkBridge = Mockito.mock(BookmarkBridge.class);
         doReturn(existingBookmark1).when(bookmarkBridge).getBookmarkById(existingBookmarkId1);
         doReturn(existingBookmark2).when(bookmarkBridge).getBookmarkById(existingBookmarkId2);
@@ -295,8 +291,7 @@
         BookmarkId existingBookmarkId = new BookmarkId(0, BookmarkType.NORMAL);
         BookmarkItem existingBookmark = new BookmarkItem(existingBookmarkId, "Test",
                 JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL), /*isFolder=*/false, /*parent=*/null,
-                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false,
-                /*readingListSwappable=*/false);
+                /*isEditable=*/true, /*isManaged=*/false, /*dateAdded*/ 0, /*read=*/false);
         BookmarkBridge bookmarkBridge = Mockito.mock(BookmarkBridge.class);
 
         ArrayList<BookmarkId> bookmarks = new ArrayList<>();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabmodel/TabModelImplUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabmodel/TabModelImplUnitTest.java
new file mode 100644
index 0000000..b8eefea
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabmodel/TabModelImplUnitTest.java
@@ -0,0 +1,268 @@
+// 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.tabmodel;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.JniMocker;
+import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.flags.ActivityType;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.homepage.HomepageManager;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tab.MockTab;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabCreationState;
+import org.chromium.chrome.browser.tab.TabLaunchType;
+import org.chromium.chrome.browser.tab.TabSelectionType;
+import org.chromium.chrome.browser.tab.state.CriticalPersistedTabData;
+import org.chromium.chrome.test.util.browser.Features;
+
+/**
+ * Unit tests for {@link TabModelImpl}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+@Features.DisableFeatures(ChromeFeatureList.CONTINUOUS_SEARCH) // crbug.com/1321711 for MockTab.
+public class TabModelImplUnitTest {
+    private static final long FAKE_NATIVE_ADDRESS = 123L;
+
+    @Rule
+    public TestRule mFeaturesProcessor = new Features.JUnitProcessor();
+
+    /**
+     * Disable native calls from {@link TabModelJniBridge}.
+     */
+    @Rule
+    public JniMocker mJniMocker = new JniMocker();
+    @Mock
+    private TabModelJniBridge.Natives mTabModelJniBridge;
+    /**
+     * Required to be non-null for {@link TabModelJniBridge}.
+     */
+    @Mock
+    private Profile mProfile;
+    /**
+     * Required to simulate tab thumbnail deletion.
+     */
+    @Mock
+    private TabContentManager mTabContentManager;
+    /**
+     * Required to handle some tab lookup actions.
+     */
+    @Mock
+    private TabModelDelegate mTabModelDelegate;
+    /**
+     * Required to handle some actions and initialize {@link TabModelOrderControllerImpl}.
+     */
+    @Mock
+    private TabModelSelector mTabModelSelector;
+
+    private int mNextTabId;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        // Disable HomepageManager#shouldCloseAppWithZeroTabs() for TabModelImpl#closeAllTabs().
+        HomepageManager.getInstance().setPrefHomepageEnabled(false);
+
+        mJniMocker.mock(TabModelJniBridgeJni.TEST_HOOKS, mTabModelJniBridge);
+        when(mTabModelJniBridge.init(any(), any(), anyInt())).thenReturn(FAKE_NATIVE_ADDRESS);
+
+        when(mTabModelDelegate.isReparentingInProgress()).thenReturn(false);
+
+        mNextTabId = 0;
+    }
+
+    private Tab createTab(final TabModel model) {
+        return createTab(model, 0, Tab.INVALID_TAB_ID);
+    }
+
+    private Tab createTab(final TabModel model, long activeTimestampMillis, int parentId) {
+        final int launchType = TabLaunchType.FROM_CHROME_UI;
+        MockTab tab = new MockTab(mNextTabId++, model.isIncognito());
+        CriticalPersistedTabData data = new CriticalPersistedTabData(tab);
+        data.setTimestampMillis(activeTimestampMillis);
+        data.setParentId(parentId);
+        tab = (MockTab) MockTab.initializeWithCriticalPersistedTabData(tab, data);
+        tab.setIsInitialized(true);
+        model.addTab(tab, -1, TabLaunchType.FROM_CHROME_UI, TabCreationState.LIVE_IN_FOREGROUND);
+        return tab;
+    }
+
+    private void selectTab(final TabModel model, final Tab tab) {
+        model.setIndex(model.indexOf(tab), TabSelectionType.FROM_USER, false);
+    }
+
+    /**
+     * Create a {@link TabModel} to use for the test.
+     */
+    private TabModel createTabModel(boolean isActive, boolean isIncognito) {
+        AsyncTabParamsManager realAsyncTabParamsManager =
+                AsyncTabParamsManagerFactory.createAsyncTabParamsManager();
+        TabModelOrderControllerImpl orderController =
+                new TabModelOrderControllerImpl(mTabModelSelector);
+        TabModel tabModel;
+        when(mProfile.isOffTheRecord()).thenReturn(isIncognito);
+        tabModel = new TabModelImpl(mProfile, ActivityType.TABBED,
+                /*regularTabCreator=*/null, /*incognitoTabCreator=*/null, orderController,
+                mTabContentManager,
+                ()
+                        -> NextTabPolicy.HIERARCHICAL,
+                realAsyncTabParamsManager, mTabModelDelegate, /*supportsUndo=*/false);
+        when(mTabModelSelector.getModel(isIncognito)).thenReturn(tabModel);
+        tabModel.setActive(isActive);
+        if (isActive) {
+            when(mTabModelSelector.getCurrentModel()).thenReturn(tabModel);
+            when(mTabModelDelegate.getCurrentModel()).thenReturn(tabModel);
+        }
+        when(mTabModelDelegate.getModel(isIncognito)).thenReturn(tabModel);
+        return tabModel;
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_InactiveModel() {
+        TabModel activeIncognito = createTabModel(true, true);
+        TabModel inactiveNormal = createTabModel(false, false);
+
+        Tab incognitoTab0 = createTab(activeIncognito);
+        Tab incognitoTab1 = createTab(activeIncognito);
+        Tab tab0 = createTab(inactiveNormal);
+        Tab tab1 = createTab(inactiveNormal);
+
+        selectTab(activeIncognito, incognitoTab1);
+        selectTab(inactiveNormal, tab1);
+
+        Assert.assertEquals(incognitoTab1, inactiveNormal.getNextTabIfClosed(tab1.getId(), false));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_NotCurrentTab() {
+        TabModel activeNormal = createTabModel(true, false);
+        // Unused but required for correct mocking of mTabModelDelegate to avoid NPE.
+        TabModel inactiveIncognito = createTabModel(false, true);
+
+        Tab tab0 = createTab(activeNormal);
+        Tab tab1 = createTab(activeNormal);
+        Tab tab2 = createTab(activeNormal);
+
+        selectTab(activeNormal, tab0);
+        Assert.assertEquals(tab0, activeNormal.getNextTabIfClosed(tab1.getId(), false));
+        Assert.assertEquals(tab0, activeNormal.getNextTabIfClosed(tab2.getId(), false));
+
+        selectTab(activeNormal, tab1);
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab0.getId(), false));
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab2.getId(), false));
+
+        selectTab(activeNormal, tab2);
+        Assert.assertEquals(tab2, activeNormal.getNextTabIfClosed(tab0.getId(), false));
+        Assert.assertEquals(tab2, activeNormal.getNextTabIfClosed(tab1.getId(), false));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_ParentTab() {
+        TabModel activeNormal = createTabModel(true, false);
+        // Unused but required for correct mocking of mTabModelDelegate to avoid NPE.
+        TabModel inactiveIncognito = createTabModel(false, true);
+
+        Tab tab0 = createTab(activeNormal);
+        Tab tab1 = createTab(activeNormal);
+        Tab tab2 = createTab(activeNormal, 0, tab0.getId());
+
+        selectTab(activeNormal, tab2);
+        Assert.assertEquals(tab0, activeNormal.getNextTabIfClosed(tab2.getId(), false));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_Adjacent() {
+        TabModel activeNormal = createTabModel(true, false);
+        // Unused but required for correct mocking of mTabModelDelegate to avoid NPE.
+        TabModel inactiveIncognito = createTabModel(false, true);
+
+        Tab tab0 = createTab(activeNormal);
+        Tab tab1 = createTab(activeNormal);
+        Tab tab2 = createTab(activeNormal);
+
+        selectTab(activeNormal, tab0);
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab0.getId(), false));
+
+        selectTab(activeNormal, tab1);
+        Assert.assertEquals(tab0, activeNormal.getNextTabIfClosed(tab1.getId(), false));
+
+        selectTab(activeNormal, tab2);
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab2.getId(), false));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_LastIncognitoTab() {
+        TabModel activeIncognito = createTabModel(true, true);
+        TabModel inactiveNormal = createTabModel(false, false);
+
+        Tab incognitoTab0 = createTab(activeIncognito);
+        Tab tab0 = createTab(inactiveNormal);
+        Tab tab1 = createTab(inactiveNormal);
+
+        selectTab(inactiveNormal, tab0);
+        Assert.assertEquals(tab0, activeIncognito.getNextTabIfClosed(incognitoTab0.getId(), false));
+
+        selectTab(inactiveNormal, tab1);
+        Assert.assertEquals(tab1, activeIncognito.getNextTabIfClosed(incognitoTab0.getId(), false));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_MostRecentTab() {
+        TabModel activeNormal = createTabModel(true, false);
+        // Unused but required for correct mocking of mTabModelDelegate to avoid NPE.
+        TabModel inactiveIncognito = createTabModel(false, true);
+
+        // uponExit overrides parent selection..
+        Tab tab0 = createTab(activeNormal, 10, Tab.INVALID_TAB_ID);
+        Tab tab1 = createTab(activeNormal, 200, tab0.getId());
+        Tab tab2 = createTab(activeNormal, 30, tab0.getId());
+
+        selectTab(activeNormal, tab0);
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab0.getId(), true));
+
+        selectTab(activeNormal, tab1);
+        Assert.assertEquals(tab2, activeNormal.getNextTabIfClosed(tab1.getId(), true));
+
+        selectTab(activeNormal, tab2);
+        Assert.assertEquals(tab1, activeNormal.getNextTabIfClosed(tab2.getId(), true));
+    }
+
+    @Test
+    @SmallTest
+    public void testGetNextTabIfClosed_InvalidSelection() {
+        TabModel activeNormal = createTabModel(true, false);
+        // Unused but required for correct mocking of mTabModelDelegate to avoid NPE.
+        TabModel inactiveIncognito = createTabModel(false, true);
+
+        Tab tab0 = createTab(activeNormal);
+        selectTab(activeNormal, tab0);
+        Assert.assertNull(activeNormal.getNextTabIfClosed(tab0.getId(), false));
+    }
+}
diff --git a/chrome/android/modules/cablev2_authenticator/internal/BUILD.gn b/chrome/android/modules/cablev2_authenticator/internal/BUILD.gn
index bc16577..c3ae4ed 100644
--- a/chrome/android/modules/cablev2_authenticator/internal/BUILD.gn
+++ b/chrome/android/modules/cablev2_authenticator/internal/BUILD.gn
@@ -8,7 +8,6 @@
 android_library("java") {
   sources = [ "java/src/org/chromium/chrome/modules/cablev2_authenticator/ModuleImpl.java" ]
   deps = [
-    "//base:base_java",
     "//build/android:build_java",
     "//chrome/android/features/cablev2_authenticator:java",
     "//chrome/android/modules/cablev2_authenticator/public:java",
diff --git a/chrome/android/modules/cablev2_authenticator/public/BUILD.gn b/chrome/android/modules/cablev2_authenticator/public/BUILD.gn
index 25df020..3b128f07 100644
--- a/chrome/android/modules/cablev2_authenticator/public/BUILD.gn
+++ b/chrome/android/modules/cablev2_authenticator/public/BUILD.gn
@@ -9,7 +9,6 @@
     "java/src/org/chromium/chrome/modules/cablev2_authenticator/Module.java",
   ]
   deps = [
-    "//base:base_java",
     "//components/module_installer/android:module_installer_java",
     "//components/module_installer/android:module_interface_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/android/modules/dev_ui/provider/BUILD.gn b/chrome/android/modules/dev_ui/provider/BUILD.gn
index 9c7d2f9c..9d243aa6 100644
--- a/chrome/android/modules/dev_ui/provider/BUILD.gn
+++ b/chrome/android/modules/dev_ui/provider/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/android/features/dev_ui/public:java",
diff --git a/chrome/android/modules/stack_unwinder/internal/BUILD.gn b/chrome/android/modules/stack_unwinder/internal/BUILD.gn
index ab60bae8..7b6428ee 100644
--- a/chrome/android/modules/stack_unwinder/internal/BUILD.gn
+++ b/chrome/android/modules/stack_unwinder/internal/BUILD.gn
@@ -9,7 +9,6 @@
   sources = [ "java/src/org/chromium/chrome/modules/stack_unwinder/StackUnwinderModuleContentsImpl.java" ]
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/android/modules/stack_unwinder/public:java",
diff --git a/chrome/android/modules/stack_unwinder/provider/BUILD.gn b/chrome/android/modules/stack_unwinder/provider/BUILD.gn
index 733f7c1d..0536973 100644
--- a/chrome/android/modules/stack_unwinder/provider/BUILD.gn
+++ b/chrome/android/modules/stack_unwinder/provider/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//chrome/android/modules/stack_unwinder/public:java",
   ]
diff --git a/chrome/android/modules/stack_unwinder/public/BUILD.gn b/chrome/android/modules/stack_unwinder/public/BUILD.gn
index 488f5b25..8144957 100644
--- a/chrome/android/modules/stack_unwinder/public/BUILD.gn
+++ b/chrome/android/modules/stack_unwinder/public/BUILD.gn
@@ -7,7 +7,6 @@
 android_library("java") {
   sources = [ "java/src/org/chromium/chrome/modules/stack_unwinder/StackUnwinderModuleContents.java" ]
   deps = [
-    "//base:base_java",
     "//components/module_installer/android:module_installer_java",
     "//components/module_installer/android:module_interface_java",
   ]
diff --git a/chrome/android/modules/test_dummy/internal/BUILD.gn b/chrome/android/modules/test_dummy/internal/BUILD.gn
index 3bc136d..6ab74a4 100644
--- a/chrome/android/modules/test_dummy/internal/BUILD.gn
+++ b/chrome/android/modules/test_dummy/internal/BUILD.gn
@@ -8,7 +8,6 @@
 android_library("java") {
   sources = [ "java/src/org/chromium/chrome/modules/test_dummy/TestDummyProviderImpl.java" ]
   deps = [
-    "//base:base_java",
     "//build/android:build_java",
     "//chrome/android/modules/test_dummy/public:java",
     "//chrome/browser/test_dummy:java",
diff --git a/chrome/android/modules/test_dummy/provider/BUILD.gn b/chrome/android/modules/test_dummy/provider/BUILD.gn
index d091a72..fa5cd1a7 100644
--- a/chrome/android/modules/test_dummy/provider/BUILD.gn
+++ b/chrome/android/modules/test_dummy/provider/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//chrome/android/modules/test_dummy/public:java",
     "//chrome/browser/test_dummy:java",
     "//components/module_installer/android:module_installer_java",
diff --git a/chrome/android/modules/test_dummy/public/BUILD.gn b/chrome/android/modules/test_dummy/public/BUILD.gn
index 66e42a74..191bb5f 100644
--- a/chrome/android/modules/test_dummy/public/BUILD.gn
+++ b/chrome/android/modules/test_dummy/public/BUILD.gn
@@ -9,7 +9,6 @@
     "java/src/org/chromium/chrome/modules/test_dummy/TestDummyProvider.java",
   ]
   deps = [
-    "//base:base_java",
     "//chrome/browser/test_dummy:java",
     "//components/module_installer/android:module_installer_java",
     "//components/module_installer/android:module_interface_java",
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 653fa4c..dc500854 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -235,7 +235,7 @@
     Turn off automatic updates?
   </message>
   <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION" desc="Text of the auto update toggle feature dialog description.">
-    Your device may no longer work properly, and you may experience security and performance issues. Key features in your apps may also stop working when they become outdated and you’ll lose your right to make legal claims.
+    Your device may no longer work properly, and you may experience security and performance issues. Turning off updates may also impact your right to make legal claims if you experience any issues.
   </message>
   <message name="IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_TURN_OFF_BUTTON" desc="Text of the auto update toggle feature dialog turn off button.">
     Turn off
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1
index c5dc647..afdff03e 100644
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_DESCRIPTION.png.sha1
@@ -1 +1 @@
-88417d7c3108d657ac2aec202ecefa040b76eee5
\ No newline at end of file
+76fa30181517c6a36c0893e3204832f2561bc881
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1
index c5dc647..afdff03e 100644
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_CONSUMER_AUTO_UPDATE_TOGGLE_DIALOG_TITLE.png.sha1
@@ -1 +1 @@
-88417d7c3108d657ac2aec202ecefa040b76eee5
\ No newline at end of file
+76fa30181517c6a36c0893e3204832f2561bc881
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 254c469c..aaef2ce 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2391,6 +2391,21 @@
   <message name="IDS_SETTINGS_SITE_SETTINGS_DEVICE_USE_BLOCKED_EXCEPTIONS" desc="Label for the blocked exceptions site list of the device use content setting.">
     Not allowed to know when you're actively using your device
   </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_DESCRIPTION" desc="Description of the third-party sign-in content setting.">
+    Lets you sign in to websites using the account you have with an identity service
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED" desc="Label for the enabled option of the third-party sign-in content setting.">
+    Sites can show sign-in prompts from identity services
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED" desc="Label for the disabled option of the third-party sign-in content setting.">
+    Block sign-in prompts from identity services
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED_EXCEPTIONS" desc="Label for the allowed exceptions site list of the third-party sign-in content setting.">
+    Allowed to show third-party sign-in prompts
+  </message>
+  <message name="IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED_EXCEPTIONS" desc="Label for the blocked exceptions site list of the third-party sign-in content setting.">
+    Not allowed to show third-party sign-in prompts
+  </message>
   <message name="IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_WRITE_DESCRIPTION" desc="Description of the file system write content setting.">
     Sites usually access files and folders on your device for features like automatically saving your work
   </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED.png.sha1
new file mode 100644
index 0000000..efcb6c7
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED.png.sha1
@@ -0,0 +1 @@
+d6f1209630dfce5e50abbac37d79da7c12e291b4
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED_EXCEPTIONS.png.sha1
new file mode 100644
index 0000000..efcb6c7
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED_EXCEPTIONS.png.sha1
@@ -0,0 +1 @@
+d6f1209630dfce5e50abbac37d79da7c12e291b4
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED.png.sha1
new file mode 100644
index 0000000..efcb6c7
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED.png.sha1
@@ -0,0 +1 @@
+d6f1209630dfce5e50abbac37d79da7c12e291b4
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED_EXCEPTIONS.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED_EXCEPTIONS.png.sha1
new file mode 100644
index 0000000..efcb6c7
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED_EXCEPTIONS.png.sha1
@@ -0,0 +1 @@
+d6f1209630dfce5e50abbac37d79da7c12e291b4
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_DESCRIPTION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..efcb6c7
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+d6f1209630dfce5e50abbac37d79da7c12e291b4
\ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index 2f94219d..7c3c24e 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -65,6 +65,7 @@
     "incognito_profile.icon",
     "ink_highlighter.icon",
     "input.icon",
+    "journeys.icon",
     "key.icon",
     "keyboard_arrow_down.icon",
     "keyboard_arrow_right.icon",
diff --git a/chrome/app/vector_icons/journeys.icon b/chrome/app/vector_icons/journeys.icon
new file mode 100644
index 0000000..3f2af40
--- /dev/null
+++ b/chrome/app/vector_icons/journeys.icon
@@ -0,0 +1,34 @@
+// 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.
+
+CANVAS_DIMENSIONS, 24,
+MOVE_TO, 19, 15,
+R_CUBIC_TO, -1.3f, 0, -2.4f, 0.84f, -2.82f, 2,
+H_LINE_TO, 11,
+R_CUBIC_TO, -1.1f, 0, -2, -0.9f, -2, -2,
+R_CUBIC_TO, 0, -1.1f, 0.9f, -2, 2, -2,
+R_H_LINE_TO, 2,
+R_CUBIC_TO, 2.21f, 0, 4, -1.79f, 4, -4,
+R_CUBIC_TO, 0, -2.21f, -1.79f, -4, -4, -4,
+H_LINE_TO, 7.82f,
+CUBIC_TO, 7.4f, 3.84f, 6.3f, 3, 5, 3,
+CUBIC_TO, 3.34f, 3, 2, 4.34f, 2, 6,
+R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3,
+R_CUBIC_TO, 1.3f, 0, 2.4f, -0.84f, 2.82f, -2,
+H_LINE_TO, 13,
+R_CUBIC_TO, 1.1f, 0, 2, 0.9f, 2, 2,
+R_CUBIC_TO, 0, 1.1f, -0.9f, 2, -2, 2,
+R_H_LINE_TO, -2,
+R_CUBIC_TO, -2.21f, 0, -4, 1.79f, -4, 4,
+R_CUBIC_TO, 0, 2.21f, 1.79f, 4, 4, 4,
+R_H_LINE_TO, 5.18f,
+ARC_TO, 3, 3, 0, 0, 0, 22, 18,
+R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3,
+CLOSE,
+MOVE_TO, 5, 7,
+R_CUBIC_TO, -0.55f, 0, -1, -0.45f, -1, -1,
+R_CUBIC_TO, 0, -0.55f, 0.45f, -1, 1, -1,
+R_CUBIC_TO, 0.55f, 0, 1, 0.45f, 1, 1,
+R_CUBIC_TO, 0, 0.55f, -0.45f, 1, -1, 1,
+CLOSE
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 90db5de..a1da906f 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2732,8 +2732,6 @@
       "android/contextualsearch/contextual_search_ranker_logger_impl.h",
       "android/contextualsearch/contextual_search_tab_helper.cc",
       "android/contextualsearch/contextual_search_tab_helper.h",
-      "android/contextualsearch/ctr_suppression.cc",
-      "android/contextualsearch/ctr_suppression.h",
       "android/contextualsearch/resolved_search_term.cc",
       "android/contextualsearch/resolved_search_term.h",
       "android/contextualsearch/unhandled_tap_notifier_impl.cc",
@@ -3372,6 +3370,8 @@
       "tab/web_contents_state.h",
       "touch_to_fill/touch_to_fill_controller.cc",
       "touch_to_fill/touch_to_fill_controller.h",
+      "touch_to_fill/touch_to_fill_webauthn_credential.cc",
+      "touch_to_fill/touch_to_fill_webauthn_credential.h",
       "translate/android/translate_bridge.cc",
       "translate/android/translate_bridge.h",
       "video_tutorials/internal/android/video_tutorial_service_bridge_factory.cc",
@@ -5073,6 +5073,7 @@
       "//components/arc/common",
       "//components/arc/common:arc_intent_helper_constants",
       "//components/desks_storage",
+      "//components/metrics/structured",
       "//components/metrics/structured:neutrino_logging",
       "//components/metrics/structured:neutrino_logging_util",
       "//components/services/app_service/public/cpp:instance_update",
@@ -7251,6 +7252,8 @@
       "supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h",
       "supervised_user/kids_management_url_checker_client.cc",
       "supervised_user/kids_management_url_checker_client.h",
+      "supervised_user/parental_control_metrics.cc",
+      "supervised_user/parental_control_metrics.h",
       "supervised_user/permission_request_creator.h",
       "supervised_user/supervised_user_constants.cc",
       "supervised_user/supervised_user_constants.h",
@@ -7260,6 +7263,10 @@
       "supervised_user/supervised_user_google_auth_navigation_throttle.h",
       "supervised_user/supervised_user_interstitial.cc",
       "supervised_user/supervised_user_interstitial.h",
+      "supervised_user/supervised_user_metrics_service.cc",
+      "supervised_user/supervised_user_metrics_service.h",
+      "supervised_user/supervised_user_metrics_service_factory.cc",
+      "supervised_user/supervised_user_metrics_service_factory.h",
       "supervised_user/supervised_user_navigation_observer.cc",
       "supervised_user/supervised_user_navigation_observer.h",
       "supervised_user/supervised_user_navigation_throttle.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 067a494..360a385 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -987,12 +987,21 @@
     {"All Supported Locales", kJourneysAllLocalesParams,
      std::size(kJourneysAllLocalesParams), nullptr},
 };
-const FeatureEntry::FeatureParam kJourneysOmniboxActionOnURLsParams[] = {
+const FeatureEntry::FeatureParam kJourneysOmniboxActionOnAllURLsParams[] = {
     {"omnibox_action_on_urls", "true"},
+    {"omnibox_action_on_noisy_urls", "true"},
+};
+const FeatureEntry::FeatureParam kJourneysOmniboxActionOnNonNoisyURLsParams[] =
+    {
+        {"omnibox_action_on_urls", "true"},
+        {"omnibox_action_on_noisy_urls", "false"},
 };
 const FeatureEntry::FeatureVariation kJourneysOmniboxActionVariations[] = {
-    {"Action Chips on URLs", kJourneysOmniboxActionOnURLsParams,
-     std::size(kJourneysOmniboxActionOnURLsParams), nullptr},
+    {"Action Chips on All URLs", kJourneysOmniboxActionOnAllURLsParams,
+     std::size(kJourneysOmniboxActionOnAllURLsParams), nullptr},
+    {"Action Chips on Non-Noisy URLs",
+     kJourneysOmniboxActionOnNonNoisyURLsParams,
+     std::size(kJourneysOmniboxActionOnNonNoisyURLsParams), nullptr},
 };
 const FeatureEntry::FeatureParam kJourneysLabelsWithEntitiesParams[] = {
     {"labels_from_entities", "true"},
@@ -2436,11 +2445,20 @@
     {features::kFedCmAutoSigninFieldTrialParamName, "true"}};
 const FeatureEntry::FeatureParam kFedCmVariationIdpSignout[] = {
     {features::kFedCmIdpSignoutFieldTrialParamName, "true"}};
+#if !BUILDFLAG(IS_ANDROID)
+const FeatureEntry::FeatureParam kFedCmVariationDesktopSettings[] = {
+    {features::kFedCmDesktopSettingsFieldTrialParamName, "true"}};
+#endif  // BUILDFLAG(IS_ANDROID)
 const FeatureEntry::FeatureVariation kFedCmFeatureVariations[] = {
     {"- with FedCM auto sign-in", kFedCmVariationAutoSignin,
      std::size(kFedCmVariationAutoSignin), nullptr},
     {"- with FedCM IDP sign-out", kFedCmVariationIdpSignout,
-     std::size(kFedCmVariationIdpSignout), nullptr}};
+     std::size(kFedCmVariationIdpSignout), nullptr},
+#if !BUILDFLAG(IS_ANDROID)
+    {"- with desktop settings", kFedCmVariationDesktopSettings,
+     std::size(kFedCmVariationDesktopSettings), nullptr}
+#endif  // BUILDFLAG(IS_ANDROID)
+};
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 const FeatureEntry::Choice kForceControlFaceAeChoices[] = {
@@ -2650,6 +2668,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr char kPersonalizationHubInternalName[] = "personalization-hub";
+constexpr char kWallpaperFastRefreshInternalName[] = "wallpaper-fast-refresh";
 constexpr char kWallpaperFullScreenPreviewInternalName[] =
     "wallpaper-fullscreen-preview";
 constexpr char kWallpaperGooglePhotosIntegrationInternalName[] =
@@ -2741,13 +2760,6 @@
     {"(128dip)", kLargeFaviconFromGoogle128,
      std::size(kLargeFaviconFromGoogle128), nullptr}};
 
-const FeatureEntry::Choice kDocumentTransitionSlowdownFactorChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {"5", switches::kDocumentTransitionSlowdownFactor, "5"},
-    {"10", switches::kDocumentTransitionSlowdownFactor, "10"},
-    {"20", switches::kDocumentTransitionSlowdownFactor, "20"},
-    {"50", switches::kDocumentTransitionSlowdownFactor, "50"}};
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // Possible configurations for the snooping protection feature.
 // Empty params configures the feature to apply a simple threshold to one
@@ -4423,10 +4435,6 @@
     {"document-transition", flag_descriptions::kDocumentTransitionName,
      flag_descriptions::kDocumentTransitionDescription, kOsAll,
      FEATURE_VALUE_TYPE(blink::features::kDocumentTransition)},
-    {"document-transition-slowdown-factor",
-     flag_descriptions::kDocumentTransitionSlowdownFactorName,
-     flag_descriptions::kDocumentTransitionSlowdownFactorDescription, kOsAll,
-     MULTI_VALUE_TYPE(kDocumentTransitionSlowdownFactorChoices)},
 #if BUILDFLAG(IS_WIN)
     {"use-winrt-midi-api", flag_descriptions::kUseWinrtMidiApiName,
      flag_descriptions::kUseWinrtMidiApiDescription, kOsWin,
@@ -7452,6 +7460,10 @@
      flag_descriptions::kPersonalizationHubName,
      flag_descriptions::kPersonalizationHubDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kPersonalizationHub)},
+    {kWallpaperFastRefreshInternalName,
+     flag_descriptions::kWallpaperFastRefreshName,
+     flag_descriptions::kWallpaperFastRefreshDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kWallpaperFastRefresh)},
     {kWallpaperFullScreenPreviewInternalName,
      flag_descriptions::kWallpaperFullScreenPreviewName,
      flag_descriptions::kWallpaperFullScreenPreviewDescription, kOsCrOS,
@@ -8620,6 +8632,16 @@
     return !base::FeatureList::IsEnabled(features::kBorealis);
   }
 
+  // Only show wallpaper fast refresh flag if:
+  // * channel is one of Dev/Canary/Unknown, and
+  // * wallpaper Web UI flag is enabled.
+  if (!strcmp(kWallpaperFastRefreshInternalName, entry.internal_name)) {
+    return (channel != version_info::Channel::DEV &&
+            channel != version_info::Channel::CANARY &&
+            channel != version_info::Channel::UNKNOWN) ||
+           !ash::features::IsWallpaperWebUIEnabled();
+  }
+
   // Only show full screen preview flag if wallpaper flag is enabled.
   if (!strcmp(kWallpaperFullScreenPreviewInternalName, entry.internal_name))
     return !ash::features::IsWallpaperWebUIEnabled();
diff --git a/chrome/browser/android/contextualsearch/ctr_suppression.cc b/chrome/browser/android/contextualsearch/ctr_suppression.cc
deleted file mode 100644
index b43beff..0000000
--- a/chrome/browser/android/contextualsearch/ctr_suppression.cc
+++ /dev/null
@@ -1,136 +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.
-
-#include "chrome/browser/android/contextualsearch/ctr_suppression.h"
-
-#include <memory>
-#include <set>
-
-#include "base/android/jni_string.h"
-#include "base/android/scoped_java_ref.h"
-#include "chrome/android/chrome_jni_headers/CtrSuppression_jni.h"
-
-using base::android::AttachCurrentThread;
-using base::android::ConvertUTF8ToJavaString;
-using base::android::JavaParamRef;
-using base::android::ScopedJavaLocalRef;
-using contextual_search::CtrAggregator;
-
-CtrSuppression::CtrSuppression(JNIEnv* env, jobject obj)
-    : WeeklyActivityStorage(contextual_search::kNumWeeksNeededFor28DayData) {
-  java_object_.Reset(env, obj);
-
-  // NOTE: Creating the aggregator needs to be done after setting up the Java
-  // object because the constructor will call back through the Java object
-  // to access storage.
-  aggregator_ = std::make_unique<CtrAggregator>(*this);
-  DCHECK(aggregator_);
-}
-
-CtrSuppression::~CtrSuppression() {
-  JNIEnv* env = AttachCurrentThread();
-  Java_CtrSuppression_clearNativePointer(env, java_object_);
-}
-
-// Java conduit
-
-void CtrSuppression::RecordImpression(JNIEnv* env,
-                                      const JavaParamRef<jobject>& obj,
-                                      jboolean did_click) {
-  aggregator_->RecordImpression(did_click);
-}
-
-jint CtrSuppression::GetCurrentWeekNumber(JNIEnv* env,
-                                          const JavaParamRef<jobject>& obj) {
-  return aggregator_->GetCurrentWeekNumber();
-}
-
-jboolean CtrSuppression::HasPreviousWeekData(JNIEnv* env,
-                                             const JavaParamRef<jobject>& obj) {
-  return aggregator_->HasPreviousWeekData();
-}
-
-jint CtrSuppression::GetPreviousWeekImpressions(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& obj) {
-  return aggregator_->GetPreviousWeekImpressions();
-}
-
-jfloat CtrSuppression::GetPreviousWeekCtr(JNIEnv* env,
-                                          const JavaParamRef<jobject>& obj) {
-  return aggregator_->GetPreviousWeekCtr();
-}
-
-jboolean CtrSuppression::HasPrevious28DayData(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& obj) {
-  return aggregator_->HasPrevious28DayData();
-}
-
-jint CtrSuppression::GetPrevious28DayImpressions(
-    JNIEnv* env,
-    const JavaParamRef<jobject>& obj) {
-  return aggregator_->GetPrevious28DayImpressions();
-}
-
-jfloat CtrSuppression::GetPrevious28DayCtr(JNIEnv* env,
-                                           const JavaParamRef<jobject>& obj) {
-  return aggregator_->GetPrevious28DayCtr();
-}
-
-// WeeklyActivityStorage overrides
-
-int CtrSuppression::ReadClicksForWeekRemainder(int week_remainder) {
-  JNIEnv* env = AttachCurrentThread();
-  return Java_CtrSuppression_readClicks(env, java_object_, week_remainder);
-}
-
-int CtrSuppression::ReadImpressionsForWeekRemainder(int week_remainder) {
-  JNIEnv* env = AttachCurrentThread();
-  return Java_CtrSuppression_readImpressions(env, java_object_, week_remainder);
-}
-
-int CtrSuppression::ReadOldestWeekWritten() {
-  JNIEnv* env = AttachCurrentThread();
-  return Java_CtrSuppression_readOldestWeek(env, java_object_);
-}
-
-int CtrSuppression::ReadNewestWeekWritten() {
-  JNIEnv* env = AttachCurrentThread();
-  return Java_CtrSuppression_readNewestWeek(env, java_object_);
-}
-
-void CtrSuppression::WriteClicksForWeekRemainder(int week_remainder,
-                                                 int value) {
-  JNIEnv* env = AttachCurrentThread();
-  Java_CtrSuppression_writeClicks(env, java_object_, week_remainder, value);
-}
-
-void CtrSuppression::WriteImpressionsForWeekRemainder(int week_remainder,
-                                                      int value) {
-  JNIEnv* env = AttachCurrentThread();
-  Java_CtrSuppression_writeImpressions(env, java_object_, week_remainder,
-                                       value);
-}
-
-void CtrSuppression::WriteOldestWeekWritten(int value) {
-  JNIEnv* env = AttachCurrentThread();
-  Java_CtrSuppression_writeOldestWeek(env, java_object_, value);
-}
-
-void CtrSuppression::WriteNewestWeekWritten(int value) {
-  JNIEnv* env = AttachCurrentThread();
-  Java_CtrSuppression_writeNewestWeek(env, java_object_, value);
-}
-
-// Java wrapper boilerplate
-
-void CtrSuppression::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
-  delete this;
-}
-
-jlong JNI_CtrSuppression_Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
-  CtrSuppression* suppression = new CtrSuppression(env, obj);
-  return reinterpret_cast<intptr_t>(suppression);
-}
diff --git a/chrome/browser/android/contextualsearch/ctr_suppression.h b/chrome/browser/android/contextualsearch/ctr_suppression.h
deleted file mode 100644
index 0b36300..0000000
--- a/chrome/browser/android/contextualsearch/ctr_suppression.h
+++ /dev/null
@@ -1,75 +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.
-
-#ifndef CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_CTR_SUPPRESSION_H_
-#define CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_CTR_SUPPRESSION_H_
-
-#include <stddef.h>
-
-#include "base/android/jni_android.h"
-#include "components/contextual_search/core/browser/ctr_aggregator.h"
-#include "components/contextual_search/core/browser/weekly_activity_storage.h"
-
-// Provides access to aggregated click-through-rate recording for tap
-// suppression.  Implements a Java conduit to the CtrAggregator in the
-// Contextual Search component. This allows Java to access the aggregated CTR
-// values.
-// This class also provides device-specific integer storage through its
-// associated Java class as required to implement the WeeklyActivityStorage.
-class CtrSuppression : public contextual_search::WeeklyActivityStorage {
- public:
-  // Constructs a new CtrSuppression linked to the given Java object.
-  CtrSuppression(JNIEnv* env, jobject obj);
-
-  CtrSuppression(const CtrSuppression&) = delete;
-  CtrSuppression& operator=(const CtrSuppression&) = delete;
-
-  ~CtrSuppression() override;
-
-  // Calls the destructor.  Should be called when this native object is no
-  // longer needed.
-  void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
-
-  // These methods all just call through to the |CtrAggregator| method of the
-  // same name.
-  void RecordImpression(JNIEnv* env,
-                        const base::android::JavaParamRef<jobject>& obj,
-                        jboolean did_click);
-  jint GetCurrentWeekNumber(JNIEnv* env,
-                            const base::android::JavaParamRef<jobject>& obj);
-  jboolean HasPreviousWeekData(JNIEnv* env,
-                               const base::android::JavaParamRef<jobject>& obj);
-  jint GetPreviousWeekImpressions(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& obj);
-  jfloat GetPreviousWeekCtr(JNIEnv* env,
-                            const base::android::JavaParamRef<jobject>& obj);
-  jboolean HasPrevious28DayData(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& obj);
-  jint GetPrevious28DayImpressions(
-      JNIEnv* env,
-      const base::android::JavaParamRef<jobject>& obj);
-  jfloat GetPrevious28DayCtr(JNIEnv* env,
-                             const base::android::JavaParamRef<jobject>& obj);
-
-  // WeeklyActivityStorage Overrides.
-  int ReadClicksForWeekRemainder(int week_remainder) override;
-  int ReadImpressionsForWeekRemainder(int week_remainder) override;
-  int ReadOldestWeekWritten() override;
-  int ReadNewestWeekWritten() override;
-  void WriteClicksForWeekRemainder(int week_remainder, int value) override;
-  void WriteImpressionsForWeekRemainder(int week_remainder, int value) override;
-  void WriteOldestWeekWritten(int value) override;
-  void WriteNewestWeekWritten(int value) override;
-
- private:
-  // The CtrAggregator that we forward requests to.
-  std::unique_ptr<contextual_search::CtrAggregator> aggregator_;
-
-  // The linked Java object.
-  base::android::ScopedJavaGlobalRef<jobject> java_object_;
-};
-
-#endif  // CHROME_BROWSER_ANDROID_CONTEXTUALSEARCH_CTR_SUPPRESSION_H_
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/AndroidManifest.xml b/chrome/browser/android/examples/custom_tabs_client/src/AndroidManifest.xml
index 4987c1d..b670d135 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/AndroidManifest.xml
+++ b/chrome/browser/android/examples/custom_tabs_client/src/AndroidManifest.xml
@@ -22,7 +22,7 @@
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:allowBackup="false"
-        android:theme="@style/Theme.MaterialComponents.Light" >
+        android:theme="@style/Theme.Material3.DayNight" >
 
         <activity
             android:name="org.chromium.customtabsclient.MainActivity"
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
index 14e9a8fd..c9eae16 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
+++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -39,6 +39,8 @@
 import androidx.browser.customtabs.CustomTabsServiceConnection;
 import androidx.browser.customtabs.CustomTabsSession;
 
+import com.google.android.material.button.MaterialButtonToggleGroup;
+
 import org.chromium.customtabsclient.shared.CustomTabsHelper;
 import org.chromium.customtabsclient.shared.ServiceConnection;
 import org.chromium.customtabsclient.shared.ServiceConnectionCallback;
@@ -66,6 +68,7 @@
     private Button mLaunchIncognitoButton;
     private Button mLaunchPartialHeightCctButton;
     private MediaPlayer mMediaPlayer;
+    private MaterialButtonToggleGroup mCloseButtonPositionToggle;
 
     /**
      * Once per second, asks the framework for the process importance, and logs any change.
@@ -122,6 +125,8 @@
         mLaunchPartialHeightCctButton.setOnClickListener(this);
         mMediaPlayer = MediaPlayer.create(this, R.raw.amazing_grace);
         findViewById(R.id.register_twa_service).setOnClickListener(this);
+        mCloseButtonPositionToggle = findViewById(R.id.close_button_position_toggle);
+        mCloseButtonPositionToggle.check(R.id.start_button);
 
         Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
         PackageManager pm = getPackageManager();
@@ -222,6 +227,10 @@
         String url = mEditText.getText().toString();
         int viewId = v.getId();
 
+        // @CloseButtonPosition
+        int closeButtonPosition =
+                mCloseButtonPositionToggle.getCheckedButtonId() == R.id.end_button ? 2 : 1;
+
         if (viewId == R.id.connect_button) {
             bindCustomTabsService();
         } else if (viewId == R.id.warmup_button) {
@@ -249,6 +258,8 @@
             customTabsIntent.intent.putExtra(
                     "com.google.android.apps.chrome.EXTRA_OPEN_NEW_INCOGNITO_TAB",
                     viewId == R.id.launch_incognito_button);
+            customTabsIntent.intent.putExtra(
+                    "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION", closeButtonPosition);
             configSessionConnection(session, customTabsIntent);
             customTabsIntent.launchUrl(this, Uri.parse(url));
         } else if (viewId == R.id.launch_pcct_button) {
@@ -263,6 +274,8 @@
             configSessionConnection(session, customTabsIntent);
             customTabsIntent.intent.putExtra(
                     "androidx.browser.customtabs.extra.INITIAL_ACTIVITY_HEIGHT_IN_PIXEL", 500);
+            customTabsIntent.intent.putExtra(
+                    "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION", closeButtonPosition);
             customTabsIntent.launchUrl(this, Uri.parse(url));
         }
     }
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
index 2dbad91..0c50d65e 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
+++ b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
@@ -16,6 +16,7 @@
 
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
@@ -55,6 +56,47 @@
                 android:layout_gravity="center_horizontal" />
         </LinearLayout>
 
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/toolbar_customizations_text"
+            android:layout_gravity="center"
+            android:layout_marginBottom="8dp"
+            style="?attr/textAppearanceTitleMedium" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|start"
+                android:text="@string/close_button_position_text"
+                android:layout_marginEnd="16dp"
+                style="?attr/textAppearanceLabelLarge" />
+            <com.google.android.material.button.MaterialButtonToggleGroup
+                android:id="@+id/close_button_position_toggle"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|end"
+                app:singleSelection="true"
+                app:selectionRequired="true">
+                <Button
+                    android:id="@+id/start_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/close_button_start_text"
+                    style="?attr/materialButtonOutlinedStyle" />
+                <Button
+                    android:id="@+id/end_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/close_button_end_text"
+                    style="?attr/materialButtonOutlinedStyle" />
+            </com.google.android.material.button.MaterialButtonToggleGroup>
+        </LinearLayout>
+
         <Space
             android:layout_width="match_parent"
             android:layout_height="5dp" />
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
index c61b2467e..defa6c8 100644
--- a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
+++ b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
@@ -16,6 +16,10 @@
 <resources>
     <string name="app_name">Chrome Custom Tabs Example</string>
     <string name="url_hint">Please type the url here.</string>
+    <string name="toolbar_customizations_text">Toolbar Customizations</string>
+    <string name="close_button_position_text">Close Button Position</string>
+    <string name="close_button_start_text">Default/Start</string>
+    <string name="close_button_end_text">End</string>
     <string name="warmup_button_text">Warmup Chrome</string>
     <string name="may_launch_button_text">May Launch URL</string>
     <string name="launch_button_text">Launch URL in a Chrome Custom Tab</string>
diff --git a/chrome/browser/android/historical_tab_saver.cc b/chrome/browser/android/historical_tab_saver.cc
index 529aad4..d790d028 100644
--- a/chrome/browser/android/historical_tab_saver.cc
+++ b/chrome/browser/android/historical_tab_saver.cc
@@ -58,7 +58,7 @@
 }
 
 void CreateHistoricalGroup(TabModel* model,
-                           std::u16string group_title,
+                           const std::u16string& group_title,
                            std::vector<TabAndroid*> tabs) {
   DCHECK(model);
   sessions::TabRestoreService* service =
@@ -191,7 +191,7 @@
       env, base::android::ScopedJavaLocalRef(jtabs_android));
   CreateHistoricalGroup(TabModelList::FindNativeTabModelForJavaObject(
                             ScopedJavaLocalRef<jobject>(env, jtab_model.obj())),
-                        title, tabs_android);
+                        title, std::move(tabs_android));
 }
 
 // static
@@ -215,7 +215,8 @@
   CreateHistoricalBulkClosure(
       TabModelList::FindNativeTabModelForJavaObject(
           ScopedJavaLocalRef<jobject>(env, jtab_model.obj())),
-      android_group_ids, group_titles, per_tab_android_group_id,
+      std::move(android_group_ids), std::move(group_titles),
+      std::move(per_tab_android_group_id),
       TabAndroid::GetAllNativeTabs(
           env, base::android::ScopedJavaLocalRef(jtabs_android)));
 }
diff --git a/chrome/browser/android/messages/BUILD.gn b/chrome/browser/android/messages/BUILD.gn
index aa6f34e..de89b66 100644
--- a/chrome/browser/android/messages/BUILD.gn
+++ b/chrome/browser/android/messages/BUILD.gn
@@ -10,7 +10,6 @@
   annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
diff --git a/chrome/browser/android/metrics/BUILD.gn b/chrome/browser/android/metrics/BUILD.gn
index a20b034..5710cfc 100644
--- a/chrome/browser/android/metrics/BUILD.gn
+++ b/chrome/browser/android/metrics/BUILD.gn
@@ -33,7 +33,6 @@
   android_library("ukm_java_test_support") {
     testonly = true
     sources = _test_jni_sources
-    deps = [ "//base:base_java" ]
   }
 
   android_library("ukm_javatests") {
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
index 40b311e..92fa5e9 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps_unittest.cc
@@ -36,6 +36,7 @@
 #include "storage/common/file_system/file_system_mount_option.h"
 #include "storage/common/file_system/file_system_types.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace {
 
@@ -231,7 +232,7 @@
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
   std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(base::in_place, package_name,
+  added_links.emplace_back(absl::in_place, package_name,
                            CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
       std::move(added_links), {},
@@ -284,7 +285,7 @@
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
   std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(base::in_place, package_name,
+  added_links.emplace_back(absl::in_place, package_name,
                            CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
       std::move(added_links), {},
@@ -314,7 +315,7 @@
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   VerifyIntentFilters(app_id, {kTestAuthority});
   std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(base::in_place, package_name,
+  added_links.emplace_back(absl::in_place, package_name,
                            CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
       std::move(added_links), {},
@@ -331,7 +332,7 @@
   VerifyIntentFilters(app_id, {kTestAuthority, kTestAuthority2});
   std::vector<arc::mojom::SupportedLinksPtr> added_links2;
   added_links2.emplace_back(
-      base::in_place, package_name,
+      absl::in_place, package_name,
       CreateFilterList(package_name, {kTestAuthority, kTestAuthority2}));
   intent_helper()->OnSupportedLinksChanged(
       std::move(added_links2), {},
@@ -361,7 +362,7 @@
   intent_helper()->OnIntentFiltersUpdatedForPackage(
       package_name, CreateFilterList(package_name, {kTestAuthority}));
   std::vector<arc::mojom::SupportedLinksPtr> added_links;
-  added_links.emplace_back(base::in_place, package_name,
+  added_links.emplace_back(absl::in_place, package_name,
                            CreateFilterList(package_name, {kTestAuthority}));
   intent_helper()->OnSupportedLinksChanged(
       std::move(added_links), {},
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index f325cf6..3f6498a 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -3836,20 +3836,33 @@
 }
 
 IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPI) {
-  // TODO(crbug.com/1267977): fix this test to work with site isolation for
-  // <webview>.
-  if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled())
-    return;
-
   TestHelper("testLoadDataAPI", "web_view/shim", NEEDS_TEST_SERVER);
+
+  // Ensure that when site-isolated guests are enabled, the guest process is
+  // locked after the loadDataWithBaseURL navigation and is allowed to access
+  // resources belonging to the base URL's origin.
+  if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled()) {
+    content::WebContents* guest =
+        GetGuestViewManager()->WaitForSingleGuestCreated();
+    ASSERT_TRUE(guest);
+    content::RenderFrameHost* main_frame = guest->GetMainFrame();
+    EXPECT_TRUE(main_frame->GetSiteInstance()->RequiresDedicatedProcess());
+    EXPECT_TRUE(main_frame->GetProcess()->IsProcessLockedToSiteForTesting());
+
+    auto* security_policy = content::ChildProcessSecurityPolicy::GetInstance();
+    url::Origin base_origin = url::Origin::Create(GURL("http://localhost"));
+    EXPECT_TRUE(security_policy->CanAccessDataForOrigin(
+        main_frame->GetProcess()->GetID(), base_origin));
+
+    // Ensure the process doesn't have access to some other origin. This
+    // verifies that site isolation is enforced.
+    url::Origin another_origin = url::Origin::Create(GURL("http://foo.com"));
+    EXPECT_FALSE(security_policy->CanAccessDataForOrigin(
+        main_frame->GetProcess()->GetID(), another_origin));
+  }
 }
 
 IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestLoadDataAPIAccessibleResources) {
-  // TODO(crbug.com/1267977): fix this test to work with site isolation for
-  // <webview>.
-  if (content::SiteIsolationPolicy::IsSiteIsolationForGuestsEnabled())
-    return;
-
   TestHelper("testLoadDataAPIAccessibleResources", "web_view/shim",
              NEEDS_TEST_SERVER);
 }
diff --git a/chrome/browser/ash/arc/input_method_manager/input_connection_impl.cc b/chrome/browser/ash/arc/input_method_manager/input_connection_impl.cc
index 105ebfe..78af0a714 100644
--- a/chrome/browser/ash/arc/input_method_manager/input_connection_impl.cc
+++ b/chrome/browser/ash/arc/input_method_manager/input_connection_impl.cc
@@ -9,6 +9,7 @@
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "ui/base/ime/ash/ime_bridge.h"
 #include "ui/base/ime/ash/ime_keymap.h"
 #include "ui/events/base_event_utils.h"
@@ -104,7 +105,7 @@
   std::u16string text;
 
   if (!client) {
-    return mojom::TextInputStatePtr(base::in_place, 0, text, text_range,
+    return mojom::TextInputStatePtr(absl::in_place, 0, text, text_range,
                                     selection_range, ui::TEXT_INPUT_TYPE_NONE,
                                     false, 0, is_input_state_update_requested,
                                     composition_text_range);
@@ -117,7 +118,7 @@
   client->GetTextFromRange(text_range, &text);
 
   return mojom::TextInputStatePtr(
-      base::in_place, selection_range.start(), text, text_range,
+      absl::in_place, selection_range.start(), text, text_range,
       selection_range, client->GetTextInputType(), client->ShouldDoLearning(),
       client->GetTextInputFlags(), is_input_state_update_requested,
       composition_text_range);
diff --git a/chrome/browser/ash/child_accounts/family_user_parental_control_metrics.cc b/chrome/browser/ash/child_accounts/family_user_parental_control_metrics.cc
index 70d4553..3c4bedb 100644
--- a/chrome/browser/ash/child_accounts/family_user_parental_control_metrics.cc
+++ b/chrome/browser/ash/child_accounts/family_user_parental_control_metrics.cc
@@ -31,20 +31,6 @@
       ChildUserServiceFactory::GetForBrowserContext(profile_);
   DCHECK(child_user_service);
   child_user_service->ReportTimeLimitPolicy();
-
-  SupervisedUserService* supervised_user_service =
-      SupervisedUserServiceFactory::GetForProfile(profile_);
-  DCHECK(supervised_user_service);
-  // Ignores the first report during OOBE. Prefs related to web filter
-  // policy may not have been successfully sync during OOBE process, which
-  // introduces bias.
-  if (first_report_on_current_device_) {
-    first_report_on_current_device_ = false;
-  } else {
-    // Ignores reports when web filter prefs are reset to default value. It
-    // might happen during sign out.
-    supervised_user_service->ReportNonDefaultWebFilterValue();
-  }
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/child_accounts/family_user_parental_control_metrics_unittest.cc b/chrome/browser/ash/child_accounts/family_user_parental_control_metrics_unittest.cc
index 6d9980a..1ca59fe 100644
--- a/chrome/browser/ash/child_accounts/family_user_parental_control_metrics_unittest.cc
+++ b/chrome/browser/ash/child_accounts/family_user_parental_control_metrics_unittest.cc
@@ -27,9 +27,6 @@
 #include "chrome/browser/ash/child_accounts/time_limits/app_types.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/supervised_user/supervised_user_service.h"
-#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/common/chrome_features.h"
@@ -50,8 +47,6 @@
 constexpr base::TimeDelta kOneDay = base::Days(1);
 constexpr char kStartTime[] = "1 Jan 2020 21:15";
 
-constexpr char kExampleHost0[] = "http://www.example0.com";
-constexpr char kExampleURL1[] = "http://www.example1.com/123";
 const app_time::AppId kArcApp(apps::AppType::kArc, "packageName");
 
 arc::mojom::ArcPackageInfoPtr CreateArcAppPackage(
@@ -100,9 +95,6 @@
     profile_builder.SetIsSupervisedProfile();
     profile_ = profile_builder.Build();
     EXPECT_TRUE(profile_->IsChild());
-    supervised_user_service_ =
-        SupervisedUserServiceFactory::GetForProfile(profile_.get());
-    supervised_user_service_->Init();
     parental_control_metrics_ =
         std::make_unique<FamilyUserParentalControlMetrics>(profile_.get());
   }
@@ -134,7 +126,6 @@
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<FamilyUserParentalControlMetrics> parental_control_metrics_;
-  SupervisedUserService* supervised_user_service_ = nullptr;
 };
 
 TEST_F(FamilyUserParentalControlMetricsTest, BedAndScreenTimeLimitMetrics) {
@@ -314,141 +305,4 @@
       /*expected_count=*/4);
 }
 
-TEST_F(FamilyUserParentalControlMetricsTest, WebFilterTypeMetric) {
-  // Overriding the value of prefs::kSupervisedUserSafeSites and
-  // prefs::kDefaultSupervisedUserFilteringBehavior in default storage is
-  // needed, otherwise no report could be triggered policies change or
-  // OnNewDay(). Since the default values are the same of override values, the
-  // WebFilterType doesn't change and no report here.
-  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
-                         SupervisedUserURLFilter::ALLOW);
-  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, true);
-
-  // Tests daily report.
-  OnNewDay();
-  histogram_tester_.ExpectUniqueSample(
-      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::WebFilterType::kTryToBlockMatureSites,
-      /*expected_count=*/1);
-
-  // Tests filter "allow all sites".
-  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, false);
-
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::WebFilterType::kAllowAllSites,
-      /*expected_count=*/1);
-
-  // Tests filter "only allow certain sites" on Family Link app.
-  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
-                         SupervisedUserURLFilter::BLOCK);
-
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::WebFilterType::kCertainSites,
-      /*expected_count=*/1);
-
-  histogram_tester_.ExpectTotalCount(
-      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
-      /*expected_count=*/3);
-}
-
-TEST_F(FamilyUserParentalControlMetricsTest, ManagedSiteListTypeMetric) {
-  // Overriding the value of prefs::kSupervisedUserSafeSites and
-  // prefs::kDefaultSupervisedUserFilteringBehavior in default storage is
-  // needed, otherwise no report could be triggered by policies change or
-  // OnNewDay(). Since the default values are the same of override values, the
-  // WebFilterType doesn't change and no report here.
-  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
-                         SupervisedUserURLFilter::ALLOW);
-  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, true);
-
-  // Tests daily report.
-  OnNewDay();
-  histogram_tester_.ExpectUniqueSample(
-      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::ManagedSiteList::kEmpty,
-      /*expected_count=*/1);
-  histogram_tester_.ExpectUniqueSample(
-      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
-      /*sample=*/0, /*expected_count=*/1);
-  histogram_tester_.ExpectUniqueSample(
-      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
-      /*sample=*/0, /*expected_count=*/1);
-
-  // Blocks `kExampleHost0`.
-  {
-    DictionaryPrefUpdate hosts_update(GetPrefs(),
-                                      prefs::kSupervisedUserManualHosts);
-    base::Value* hosts = hosts_update.Get();
-    hosts->SetBoolKey(kExampleHost0, false);
-  }
-
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::ManagedSiteList::kBlockedListOnly,
-      /*expected_count=*/1);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
-      /*sample=*/0, /*expected_count=*/2);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
-      /*sample=*/1, /*expected_count=*/1);
-
-  // Approves `kExampleHost0`.
-  {
-    DictionaryPrefUpdate hosts_update(GetPrefs(),
-                                      prefs::kSupervisedUserManualHosts);
-    base::Value* hosts = hosts_update.Get();
-    hosts->SetBoolKey(kExampleHost0, true);
-  }
-
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::ManagedSiteList::kApprovedListOnly,
-      /*expected_count=*/1);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
-      /*sample=*/1, /*expected_count=*/1);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
-      /*sample=*/0, /*expected_count=*/2);
-
-  // Blocks `kExampleURL1`.
-  {
-    DictionaryPrefUpdate urls_update(GetPrefs(),
-                                     prefs::kSupervisedUserManualURLs);
-    base::Value* urls = urls_update.Get();
-    urls->SetBoolKey(kExampleURL1, false);
-  }
-
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
-      /*sample=*/
-      SupervisedUserURLFilter::ManagedSiteList::kBoth,
-      /*expected_count=*/1);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
-      /*sample=*/1, /*expected_count=*/2);
-  histogram_tester_.ExpectBucketCount(
-      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
-      /*sample=*/1, /*expected_count=*/2);
-
-  histogram_tester_.ExpectTotalCount(
-      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
-      /*expected_count=*/4);
-  histogram_tester_.ExpectTotalCount(
-      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
-      /*expected_count=*/4);
-  histogram_tester_.ExpectTotalCount(
-      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
-      /*expected_count=*/4);
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_time_controller_unittest.cc b/chrome/browser/ash/child_accounts/time_limits/app_time_controller_unittest.cc
index 9c1f129..44eae8a 100644
--- a/chrome/browser/ash/child_accounts/time_limits/app_time_controller_unittest.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/app_time_controller_unittest.cc
@@ -26,6 +26,8 @@
 #include "chrome/browser/ash/child_accounts/time_limits/app_time_test_utils.h"
 #include "chrome/browser/ash/child_accounts/time_limits/app_types.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+#include "chrome/browser/supervised_user/supervised_user_metrics_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
@@ -182,6 +184,10 @@
   SystemClockClient::InitializeFake();
   testing::Test::SetUp();
 
+  // Disable supervised user metrics reporting, otherwise the mock timer
+  // will never return.
+  SupervisedUserMetricsServiceFactory::GetForBrowserContext(&profile())
+      ->Shutdown();
   // The tests are going to start at local midnight on January 1.
   base::Time time;
   ASSERT_TRUE(base::Time::FromString(kStartTime, &time));
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index 87617d5..4e57bf7 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -263,6 +263,11 @@
 // 1. Lacros-chrome is initialized in the web Kiosk session
 // 2. Full restore is responsible for restoring/launching Lacros.
 browser_util::InitialBrowserAction GetInitialBrowserAction() {
+  if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
+    return browser_util::InitialBrowserAction(
+        mojom::InitialBrowserAction::kOpenNewTabPageWindow);
+  }
+
   return browser_util::InitialBrowserAction(
       user_manager::UserManager::Get()->IsLoggedInAsWebKioskApp() ||
               ash::full_restore::MaybeCreateFullRestoreServiceForLacros()
diff --git a/chrome/browser/autofill/credit_card_accessory_controller_impl_unittest.cc b/chrome/browser/autofill/credit_card_accessory_controller_impl_unittest.cc
index 84200fa..5d4d3ca9 100644
--- a/chrome/browser/autofill/credit_card_accessory_controller_impl_unittest.cc
+++ b/chrome/browser/autofill/credit_card_accessory_controller_impl_unittest.cc
@@ -83,7 +83,7 @@
     : public ChromeRenderViewHostTestHarness {
  public:
   CreditCardAccessoryControllerTest()
-      : af_manager_(&mock_af_driver_, &client_, &data_manager_) {
+      : af_manager_(&mock_af_driver_, &client_) {
     af_manager_.set_credit_card_access_manager_for_test(
         std::make_unique<TestAccessManager>(&mock_af_driver_, &client_,
                                             &data_manager_));
diff --git a/chrome/browser/bluetooth/android/BUILD.gn b/chrome/browser/bluetooth/android/BUILD.gn
index ab147ee..ead9764 100644
--- a/chrome/browser/bluetooth/android/BUILD.gn
+++ b/chrome/browser/bluetooth/android/BUILD.gn
@@ -52,7 +52,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 3477d196..aa1d901e 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -1611,10 +1611,6 @@
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableComponentUpdate)) {
     component_updater::RegisterComponentsForUpdate();
-  } else {
-    // Initialize First-Party Sets even if component updater is disabled.
-    content::FirstPartySetsHandler::GetInstance()->SetPublicFirstPartySets(
-        base::File());
   }
 
   // TODO(stevenjb): Move WIN and MACOSX specific code to appropriate Parts.
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 6eaa18d8..8968aba5 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -602,7 +602,7 @@
   // be used to better identify whether crashes are from enterprise users.
   static crash_reporter::CrashKeyString<4> is_enterprise_managed(
       "is-enterprise-managed");
-  is_enterprise_managed.Set(base::IsMachineExternallyManaged() ? "yes" : "no");
+  is_enterprise_managed.Set(base::IsManagedOrEnterpriseDevice() ? "yes" : "no");
 
   // Set crash keys containing the registry values used to determine Chrome's
   // update channel at process startup; see https://crbug.com/579504.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 06055df..3debb74 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -6476,6 +6476,12 @@
   return local_state->GetBoolean(first_party_sets::kFirstPartySetsEnabled);
 }
 
+bool ChromeContentBrowserClient::WillProvidePublicFirstPartySets() {
+  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kDisableComponentUpdate) &&
+         base::FeatureList::IsEnabled(features::kFirstPartySets);
+}
+
 base::Value::Dict ChromeContentBrowserClient::GetFirstPartySetsOverrides() {
   if (!g_browser_process) {
     // If browser process doesn't exist (e.g. in minimal mode on Android),
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 05ae48af..1b36ff5 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -772,6 +772,7 @@
 
   bool IsFindInPageDisabledForOrigin(const url::Origin& origin) override;
   bool IsFirstPartySetsEnabled() override;
+  bool WillProvidePublicFirstPartySets() override;
   base::Value::Dict GetFirstPartySetsOverrides() override;
 
   bool ShouldPreconnectNavigation(
diff --git a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
index 2df6d40..5e6bd82 100644
--- a/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/drivefs_event_router_unittest.cc
@@ -15,6 +15,7 @@
 #include "extensions/common/extension.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "url/gurl.h"
 
 namespace file_manager {
@@ -161,16 +162,16 @@
 
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 3, 4, "c", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 3, 4, "c", drivefs::mojom::ItemEvent::State::kInProgress,
       25, 40, drivefs::mojom::ItemEventReason::kPin);
   syncing_status.item_events.emplace_back(
-      base::in_place, 3, 4, "d", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 3, 4, "d", drivefs::mojom::ItemEvent::State::kQueued, 0,
       40, drivefs::mojom::ItemEventReason::kPin);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -197,10 +198,10 @@
        OnSyncingStatusUpdate_EmptyStatus_ClearsInProgressOrCompleted) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -214,10 +215,10 @@
 
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
       10, 100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
   testing::Mock::VerifyAndClearExpectations(&observer());
@@ -254,7 +255,7 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
 
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "c", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "c", drivefs::mojom::ItemEvent::State::kInProgress,
       60, 70, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -262,7 +263,7 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_FailedSync) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kPin);
   EXPECT_CALL(
       mock(),
@@ -279,7 +280,7 @@
 
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       80, 100, drivefs::mojom::ItemEventReason::kPin);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -299,7 +300,7 @@
                       100, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kFailed, -1,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kFailed, -1,
       -1, drivefs::mojom::ItemEventReason::kPin);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -307,7 +308,7 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_CompletedSync) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -324,7 +325,7 @@
 
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       80, 100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -344,7 +345,7 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -353,10 +354,10 @@
        OnSyncingStatusUpdate_CompletedSync_WithInProgress) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -392,10 +393,10 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
       10, 100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -403,10 +404,10 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_CompletedSync_WithQueued) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -442,10 +443,10 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -454,7 +455,7 @@
        OnSyncingStatusUpdate_CompletedSync_OtherQueued) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -490,10 +491,10 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -501,7 +502,7 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_CompletedSync_ThenQueued) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -518,7 +519,7 @@
 
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -538,7 +539,7 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -547,7 +548,7 @@
        OnSyncingStatusUpdate_CompletedSync_ThenInProgress) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kInProgress,
       50, 100, drivefs::mojom::ItemEventReason::kTransfer);
   EXPECT_CALL(mock(),
               BroadcastEventImpl(
@@ -574,7 +575,7 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
+      absl::in_place, 1, 1, "a", drivefs::mojom::ItemEvent::State::kCompleted,
       -1, -1, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 
@@ -594,7 +595,7 @@
               "", file_manager_private::TRANSFER_STATE_COMPLETED, 0, 0, 0)));
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kInProgress,
       10, 500, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
@@ -602,7 +603,7 @@
 TEST_F(DriveFsEventRouterTest, OnSyncingStatusUpdate_QueuedOnly) {
   drivefs::mojom::SyncingStatus syncing_status;
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 0,
       100, drivefs::mojom::ItemEventReason::kTransfer);
 
   testing::Mock::VerifyAndClearExpectations(&observer());
@@ -622,7 +623,7 @@
 
   syncing_status.item_events.clear();
   syncing_status.item_events.emplace_back(
-      base::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
+      absl::in_place, 2, 3, "b", drivefs::mojom::ItemEvent::State::kQueued, 10,
       100, drivefs::mojom::ItemEventReason::kTransfer);
   observer().OnSyncingStatusUpdate(syncing_status);
 }
diff --git a/chrome/browser/commerce/android/BUILD.gn b/chrome/browser/commerce/android/BUILD.gn
index 9260029..93ff0860 100644
--- a/chrome/browser/commerce/android/BUILD.gn
+++ b/chrome/browser/commerce/android/BUILD.gn
@@ -12,7 +12,6 @@
   ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/browser/profiles/android:java",
@@ -33,7 +32,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/test/android:chrome_java_test_support",
     "//components/payments/content/android:java",
diff --git a/chrome/browser/commerce/shopping_list/android/BUILD.gn b/chrome/browser/commerce/shopping_list/android/BUILD.gn
index 1478890..3a5a073e 100644
--- a/chrome/browser/commerce/shopping_list/android/BUILD.gn
+++ b/chrome/browser/commerce/shopping_list/android/BUILD.gn
@@ -8,7 +8,6 @@
 android_library("java") {
   deps = [
     "//base:base_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/component_updater/chrome_component_updater_configurator.cc b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
index fd22361..905548a 100644
--- a/chrome/browser/component_updater/chrome_component_updater_configurator.cc
+++ b/chrome/browser/component_updater/chrome_component_updater_configurator.cc
@@ -161,7 +161,7 @@
 std::string ChromeConfigurator::GetDownloadPreference() const {
 #if BUILDFLAG(IS_WIN)
   // This group policy is supported only on Windows and only for enterprises.
-  return base::IsMachineExternallyManaged()
+  return base::IsEnterpriseDevice()
              ? base::SysWideToUTF8(
                    GoogleUpdateSettings::GetDownloadPreference())
              : std::string();
diff --git a/chrome/browser/content_creation/notes/internal/android/BUILD.gn b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
index 535d926..deefe50 100644
--- a/chrome/browser/content_creation/notes/internal/android/BUILD.gn
+++ b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
@@ -89,7 +89,6 @@
   sources = [ "java/src/org/chromium/chrome/browser/content_creation/notes/fonts/TypefaceRequestTest.java" ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base/test:test_support_java",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/crash_upload_list/crash_upload_list.cc b/chrome/browser/crash_upload_list/crash_upload_list.cc
index c0a7879..d45462e 100644
--- a/chrome/browser/crash_upload_list/crash_upload_list.cc
+++ b/chrome/browser/crash_upload_list/crash_upload_list.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/crash_upload_list/crash_upload_list.h"
 
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
 #include "components/crash/core/browser/crash_upload_list_crashpad.h"
@@ -25,7 +24,7 @@
 #include "chrome/browser/crash_upload_list/crash_upload_list_android.h"
 #endif
 
-#if !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS))
+#if !BUILDFLAG(IS_CHROMEOS)
 #include "components/crash/core/browser/crash_upload_list_crashpad.h"
 #endif
 
@@ -51,8 +50,7 @@
 // which isn't compatible with CrashUploadListCrashpad. crash_sender continues
 // to log uploads in CrashUploadList::kReporterLogFilename.
 // Linux is handled below.
-#if !(BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) || \
-      BUILDFLAG(IS_LINUX))
+#if !(BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX))
   if (crash_reporter::IsCrashpadEnabled()) {
     return new CrashUploadListCrashpad();
   }
diff --git a/chrome/browser/dependency_injection/BUILD.gn b/chrome/browser/dependency_injection/BUILD.gn
index 01f35779..7155373 100644
--- a/chrome/browser/dependency_injection/BUILD.gn
+++ b/chrome/browser/dependency_injection/BUILD.gn
@@ -7,7 +7,6 @@
 android_library("java") {
   sources = [ "android/java/src/org/chromium/chrome/browser/dependency_injection/ActivityScope.java" ]
   deps = [
-    "//base:base_java",
     "//third_party/android_deps:dagger_java",
     "//third_party/android_deps:javax_inject_javax_inject_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/dev_ui_browser_resources.grd b/chrome/browser/dev_ui_browser_resources.grd
index 2c380bef..2f1936f 100644
--- a/chrome/browser/dev_ui_browser_resources.grd
+++ b/chrome/browser/dev_ui_browser_resources.grd
@@ -36,7 +36,7 @@
       <include name="IDR_LOCAL_STATE_JS" file="${root_gen_dir}\chrome\browser\resources\local_state\local_state.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_MEDIA_DATA_TABLE_JS" file="${root_gen_dir}\chrome\browser\resources\media\media_data_table.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_MEDIA_ENGAGEMENT_HTML" file="resources\media\media_engagement.html" type="BINDATA" />
-      <include name="IDR_MEDIA_ENGAGEMENT_JS" file="resources\media\media_engagement.js" type="BINDATA" />
+      <include name="IDR_MEDIA_ENGAGEMENT_JS" file="${root_gen_dir}\chrome\browser\resources\media\media_engagement.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_MEDIA_ENGAGEMENT_SCORE_DETAILS_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\chrome\browser\media\media_engagement_score_details.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_MEDIA_HISTORY_HTML" file="resources\media\media_history.html" type="BINDATA" allowexternalscript="true" />
       <include name="IDR_MEDIA_HISTORY_JS" file="${root_gen_dir}\chrome\browser\resources\media\media_history.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/browser/device_api/device_attribute_api.cc b/chrome/browser/device_api/device_attribute_api.cc
index 963400f..6356e23 100644
--- a/chrome/browser/device_api/device_attribute_api.cc
+++ b/chrome/browser/device_api/device_attribute_api.cc
@@ -29,7 +29,7 @@
     "The current origin cannot use this web API because it is not allowed by "
     "the DeviceAttributesAllowedForOrigins policy.";
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if !BUILDFLAG(IS_CHROMEOS)
 const char kNotSupportedPlatformErrorMessage[] =
     "This web API is not supported on the current platform.";
 #endif
diff --git a/chrome/browser/downgrade/downgrade_manager.cc b/chrome/browser/downgrade/downgrade_manager.cc
index a5d6a85..7b7f817e 100644
--- a/chrome/browser/downgrade/downgrade_manager.cc
+++ b/chrome/browser/downgrade/downgrade_manager.cc
@@ -153,7 +153,7 @@
 bool UserDataSnapshotEnabled() {
   return g_snapshots_enabled_for_testing ||
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-         base::IsMachineExternallyManaged() ||
+         base::IsEnterpriseDevice() ||
 #endif
          policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().is_valid();
 }
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index f9ae937..05fc44b 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -350,7 +350,7 @@
   // Returns whether holding space in-progress downloads notification
   // suppression is enabled given test parameterization.
   bool IsHoldingSpaceInProgressDownloadsNotificationSuppressionEnabled() const {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
     return GetParam();
 #else
     return false;
diff --git a/chrome/browser/feature_guide/notifications/BUILD.gn b/chrome/browser/feature_guide/notifications/BUILD.gn
index 35172cc..f4fc0a72 100644
--- a/chrome/browser/feature_guide/notifications/BUILD.gn
+++ b/chrome/browser/feature_guide/notifications/BUILD.gn
@@ -36,10 +36,7 @@
   android_library("java") {
     sources = [ "android/java/src/org/chromium/chrome/browser/feature_guide/notifications/FeatureNotificationGuideService.java" ]
 
-    deps = [
-      "//base:base_java",
-      "//third_party/androidx:androidx_annotation_annotation_java",
-    ]
+    deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
     srcjar_deps = [ ":jni_enums" ]
   }
 }
diff --git a/chrome/browser/feed/android/BUILD.gn b/chrome/browser/feed/android/BUILD.gn
index d916cc44..7edf94c31 100644
--- a/chrome/browser/feed/android/BUILD.gn
+++ b/chrome/browser/feed/android/BUILD.gn
@@ -237,7 +237,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/browser/feature_engagement:java",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
index 42eba916..b72354a 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -382,7 +382,7 @@
 }
 
 void ChromeInternalLogSource::PopulateSyncLogs(SystemLogsResponse* response) {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
   // We are only interested in sync logs for the primary user profile.
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
 #else
diff --git a/chrome/browser/first_run/android/BUILD.gn b/chrome/browser/first_run/android/BUILD.gn
index 639eb387..9855ad2 100644
--- a/chrome/browser/first_run/android/BUILD.gn
+++ b/chrome/browser/first_run/android/BUILD.gn
@@ -10,7 +10,6 @@
     "java/src/org/chromium/chrome/browser/firstrun/MobileFreProgress.java",
   ]
   deps = [
-    "//base:base_java",
     "//chrome/browser/preferences:java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
diff --git a/chrome/browser/first_run/first_run_browsertest.cc b/chrome/browser/first_run/first_run_browsertest.cc
index 390d27c..db70503 100644
--- a/chrome/browser/first_run/first_run_browsertest.cc
+++ b/chrome/browser/first_run/first_run_browsertest.cc
@@ -19,7 +19,6 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/first_run/first_run.h"
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index fe7822b77..963de4b 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -84,11 +84,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "allow-disable-mouse-acceleration",
-    "owners": [ "zentaro" ],
-    "expiry_milestone": 82
-  },
-  {
     "name": "allow-disable-touchpad-haptic-feedback",
     "owners": [ "gavinwill", "cros-peripherals@google.com" ],
     "expiry_milestone": 105
@@ -1616,11 +1611,6 @@
     "expiry_milestone": 106
   },
   {
-    "name": "enable-cascade-layers",
-    "owners": [ "xiaochengh" ],
-    "expiry_milestone": 99
-  },
-  {
     "name": "enable-cast-remoting-query-blocklist",
     "owners": [ "rwkeane@google.com", "openscreen-eng@google.com" ],
     "expiry_milestone": 115
@@ -2008,7 +1998,7 @@
   {
     "name": "enable-drdc",
     "owners": [ "vikassoni", "sunnyps" ],
-    "expiry_milestone": 102
+    "expiry_milestone": 110
   },
   {
     "name": "enable-enhanced-safe-browsing",
@@ -2780,11 +2770,6 @@
     "expiry_milestone": 90
   },
   {
-    "name": "enable-table-ng",
-    "owners": [ "atotic@google.com" ],
-    "expiry_milestone": 96
-  },
-  {
     "name": "enable-tflite-language-detection",
     "owners": [ "sophiechang", "chrome-intelligence-core@google.com" ],
     "expiry_milestone": 110
@@ -6054,6 +6039,11 @@
     "expiry_milestone": -1
   },
   {
+    "name": "wallpaper-fast-refresh",
+    "owners": ["ckincaid@google.com", "assistive-eng@google.com"],
+    "expiry_milestone": 105
+  },
+  {
     "name": "wallpaper-fullscreen-preview",
     "owners": ["cowmoo@google.com", "assistive-eng@google.com"],
     "expiry_milestone": 98
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index ea760090..986c406 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -745,12 +745,6 @@
 const char kDocumentTransitionDescription[] =
     "Controls the availability of the documentTransition JavaScript API.";
 
-const char kDocumentTransitionSlowdownFactorName[] =
-    "documentTransition API Duration Control";
-const char kDocumentTransitionSlowdownFactorDescription[] =
-    "Slows down animations triggered by documentTransition JavaScript API for "
-    "debugging.";
-
 const char kEnableAutoDisableAccessibilityName[] = "Auto-disable Accessibility";
 const char kEnableAutoDisableAccessibilityDescription[] =
     "When accessibility APIs are no longer being requested, automatically "
@@ -2708,6 +2702,12 @@
 const char kWalletServiceUseSandboxDescription[] =
     "For developers: use the sandbox service for Google Payments API calls.";
 
+const char kWallpaperFastRefreshName[] =
+    "Enable shortened wallpaper daily refresh interval for manual testing";
+const char kWallpaperFastRefreshDescription[] =
+    "Allows developers to see a new wallpaper once every ten seconds rather "
+    "than once per day when using the daily refresh feature.";
+
 const char kWallpaperFullScreenPreviewName[] =
     "Enable wallpaper full screen preview UI";
 const char kWallpaperFullScreenPreviewDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 24a190d..938e98ec 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -428,9 +428,6 @@
 extern const char kDocumentTransitionName[];
 extern const char kDocumentTransitionDescription[];
 
-extern const char kDocumentTransitionSlowdownFactorName[];
-extern const char kDocumentTransitionSlowdownFactorDescription[];
-
 extern const char kEnableAutofillAddressSavePromptName[];
 extern const char kEnableAutofillAddressSavePromptDescription[];
 
@@ -1514,6 +1511,9 @@
 extern const char kWalletServiceUseSandboxName[];
 extern const char kWalletServiceUseSandboxDescription[];
 
+extern const char kWallpaperFastRefreshName[];
+extern const char kWallpaperFastRefreshDescription[];
+
 extern const char kWallpaperFullScreenPreviewName[];
 extern const char kWallpaperFullScreenPreviewDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 32f0967..b7d2438ca 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -189,6 +189,7 @@
     &kCCTResizableForFirstParties,
     &kCCTResizableForThirdParties,
     &kCCTResourcePrefetch,
+    &kCCTToolbarCustomizations,
     &kDontAutoHideBrowserControls,
     &kChromeNewDownloadTab,
     &kChromeShareLongScreenshot,
@@ -240,6 +241,7 @@
     &kLensCameraAssistedSearch,
     &kLensOnQuickActionSearchWidget,
     &kLocationBarModelOptimizations,
+    &kMostRecentTabOnBackgroundCloseTab,
     &kNewWindowAppMenu,
     &kNotificationPermissionVariant,
     &kPageAnnotationsService,
@@ -502,6 +504,9 @@
 const base::Feature kCCTResourcePrefetch{"CCTResourcePrefetch",
                                          base::FEATURE_ENABLED_BY_DEFAULT};
 
+const base::Feature kCCTToolbarCustomizations{"CCTToolbarCustomizations",
+                                              base::FEATURE_ENABLED_BY_DEFAULT};
+
 const base::Feature kDontAutoHideBrowserControls{
     "DontAutoHideBrowserControls", base::FEATURE_DISABLED_BY_DEFAULT};
 
@@ -667,6 +672,9 @@
 const base::Feature kSearchEnginePromoNewDeviceV2{
     "SearchEnginePromo.NewDeviceVer2", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kMostRecentTabOnBackgroundCloseTab{
+    "MostRecentTabOnBackgroundCloseTab", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kNewWindowAppMenu{"NewWindowAppMenu",
                                       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 fffe7d49..013a3b5 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -47,6 +47,7 @@
 extern const base::Feature kCCTResizableForFirstParties;
 extern const base::Feature kCCTResizableForThirdParties;
 extern const base::Feature kCCTResourcePrefetch;
+extern const base::Feature kCCTToolbarCustomizations;
 extern const base::Feature kDontAutoHideBrowserControls;
 extern const base::Feature kChromeNewDownloadTab;
 extern const base::Feature kChromeShareLongScreenshot;
@@ -105,6 +106,7 @@
 extern const base::Feature kLensCameraAssistedSearch;
 extern const base::Feature kLensOnQuickActionSearchWidget;
 extern const base::Feature kLocationBarModelOptimizations;
+extern const base::Feature kMostRecentTabOnBackgroundCloseTab;
 extern const base::Feature kNewWindowAppMenu;
 extern const base::Feature kNotificationPermissionVariant;
 extern const base::Feature kPageAnnotationsService;
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 68be3d9..9b1e4f4 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
@@ -97,6 +97,7 @@
                     .put(ChromeFeatureList.CCT_RESIZABLE_ALLOW_RESIZE_BY_USER_GESTURE, false)
                     .put(ChromeFeatureList.CCT_RESIZABLE_FOR_FIRST_PARTIES, true)
                     .put(ChromeFeatureList.CCT_RESIZABLE_FOR_THIRD_PARTIES, false)
+                    .put(ChromeFeatureList.CCT_TOOLBAR_CUSTOMIZATIONS, true)
                     .put(ChromeFeatureList.INSTANCE_SWITCHER, true)
                     .put(ChromeFeatureList.WEB_APK_TRAMPOLINE_ON_INITIAL_INTENT, true)
                     .put(ChromeFeatureList.FEED_LOADING_PLACEHOLDER, 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 d6ab04a..55e42a0 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
@@ -255,6 +255,7 @@
     public static final String CCT_RESOURCE_PREFETCH = "CCTResourcePrefetch";
     public static final String CCT_REPORT_PARALLEL_REQUEST_STATUS =
             "CCTReportParallelRequestStatus";
+    public static final String CCT_TOOLBAR_CUSTOMIZATIONS = "CCTToolbarCustomizations";
     public static final String CLOSE_TAB_SUGGESTIONS = "CloseTabSuggestions";
     public static final String DONT_AUTO_HIDE_BROWSER_CONTROLS = "DontAutoHideBrowserControls";
     public static final String CHROME_NEW_DOWNLOAD_TAB = "ChromeNewDownloadTab";
@@ -400,6 +401,8 @@
     public static final String MESSAGES_FOR_ANDROID_SYNC_ERROR = "MessagesForAndroidSyncError";
     public static final String MODAL_PERMISSION_DIALOG_VIEW = "ModalPermissionDialogView";
     public static final String METRICS_SETTINGS_ANDROID = "MetricsSettingsAndroid";
+    public static final String MOST_RECENT_TAB_ON_BACKGROUND_CLOSE_TAB =
+            "MostRecentTabOnBackgroundCloseTab";
     public static final String NEW_WINDOW_APP_MENU = "NewWindowAppMenu";
     public static final String NOTIFICATION_PERMISSION_VARIANT = "NotificationPermissionVariant";
     public static final String OFFLINE_INDICATOR = "OfflineIndicator";
diff --git a/chrome/browser/image_descriptions/BUILD.gn b/chrome/browser/image_descriptions/BUILD.gn
index 02b619c..7134888e 100644
--- a/chrome/browser/image_descriptions/BUILD.gn
+++ b/chrome/browser/image_descriptions/BUILD.gn
@@ -68,7 +68,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/browser/device:java",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/image_editor/public/BUILD.gn b/chrome/browser/image_editor/public/BUILD.gn
index 1b45913..1ad5661 100644
--- a/chrome/browser/image_editor/public/BUILD.gn
+++ b/chrome/browser/image_editor/public/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [ "android/java/src/org/chromium/chrome/browser/image_editor/ImageEditorDialogCoordinator.java" ]
 
   deps = [
-    "//base:base_java",
     "//chrome/browser/share:java",
     "//ui/android:ui_no_recycler_view_java",
   ]
diff --git a/chrome/browser/lens/BUILD.gn b/chrome/browser/lens/BUILD.gn
index 5e6a7fd..fdfe182 100644
--- a/chrome/browser/lens/BUILD.gn
+++ b/chrome/browser/lens/BUILD.gn
@@ -11,7 +11,6 @@
 
   deps = [
     ":java_resources",
-    "//base:base_java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/ui/android/strings:ui_strings_grd",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -35,7 +34,6 @@
   deps = [
     ":java_resources",
     ":util_java",
-    "//base:base_java",
     "//chrome/browser/contextmenu:java",
     "//chrome/browser/ui/android/strings:ui_strings_grd",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/locale/BUILD.gn b/chrome/browser/locale/BUILD.gn
index 9f890be..ed5666b 100644
--- a/chrome/browser/locale/BUILD.gn
+++ b/chrome/browser/locale/BUILD.gn
@@ -75,7 +75,6 @@
     "java/src/org/chromium/chrome/browser/locale/LocaleTemplateUrlLoader.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/login_detection/password_store_sites_browsertest.cc b/chrome/browser/login_detection/password_store_sites_browsertest.cc
index 060d0d3d..e01a403 100644
--- a/chrome/browser/login_detection/password_store_sites_browsertest.cc
+++ b/chrome/browser/login_detection/password_store_sites_browsertest.cc
@@ -87,7 +87,7 @@
 
 // The code under test depends on feature EnablePasswordsAccountStorage which
 // is not enabled for Chrome OS (ash or lacros).
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 #define DISABLE_ON_CHROMEOS(x) DISABLED_##x
 #else
 #define DISABLE_ON_CHROMEOS(x) x
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index fb67c8b..d3b4101 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -14,7 +14,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/media/media_browsertest.h"
 #include "chrome/browser/media/test_license_server.h"
 #include "chrome/browser/media/wv_test_license_server_config.h"
@@ -99,7 +98,7 @@
 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
 const char kEmeSessionClosedAndError[] = "EME_SESSION_CLOSED_AND_ERROR";
 const char kEmeSessionNotFound[] = "EME_SESSION_NOT_FOUND";
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 const char kEmeUnitTestFailure[] = "UNIT_TEST_FAILURE";
 #endif
 #endif
@@ -378,7 +377,7 @@
       public testing::WithParamInterface<const char*> {
  public:
   void TestOutputProtection(bool create_recorder_before_media_keys) {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
     // QueryOutputProtectionStatus() is known to fail on Linux Chrome OS builds.
     std::string expected_title = kEmeUnitTestFailure;
 #else
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller.cc b/chrome/browser/media/router/providers/cast/cast_media_controller.cc
index dd0aa00..beadc4b 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_controller.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_controller.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h"
 #include "components/cast_channel/cast_message_util.h"
 #include "components/cast_channel/enum_table.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using cast_channel::V2MessageType;
 
@@ -226,7 +227,7 @@
       const std::string* url_string = image_value.FindStringKey("url");
       if (!url_string)
         continue;
-      media_status_.images.emplace_back(base::in_place, GURL(*url_string),
+      media_status_.images.emplace_back(absl::in_place, GURL(*url_string),
                                         GetValidSize(&image_value));
     }
   }
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
index 9a020e28..ac495257 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
@@ -19,6 +19,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using base::Value;
 using testing::_;
@@ -360,9 +361,9 @@
 TEST_F(CastMediaControllerTest, UpdateMediaImages) {
   mojom::MediaStatusPtr expected_status = CreateSampleMediaStatus();
   expected_status->images.emplace_back(
-      base::in_place, GURL("https://example.com/1.png"), gfx::Size(123, 456));
+      absl::in_place, GURL("https://example.com/1.png"), gfx::Size(123, 456));
   expected_status->images.emplace_back(
-      base::in_place, GURL("https://example.com/2.png"), gfx::Size(789, 0));
+      absl::in_place, GURL("https://example.com/2.png"), gfx::Size(789, 0));
   const mojom::MediaImage& image1 = *expected_status->images.at(0);
   const mojom::MediaImage& image2 = *expected_status->images.at(1);
 
@@ -383,7 +384,7 @@
   // Set one valid image and one invalid image.
   mojom::MediaStatusPtr expected_status = CreateSampleMediaStatus();
   expected_status->images.emplace_back(
-      base::in_place, GURL("https://example.com/1.png"), gfx::Size(123, 456));
+      absl::in_place, GURL("https://example.com/1.png"), gfx::Size(123, 456));
   const mojom::MediaImage& valid_image = *expected_status->images.at(0);
   Value status_value = CreateMediaStatus(*expected_status);
   status_value.FindListPath("media.metadata.images")->Append("invalid image");
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
index 3386bce..d3d4cab 100644
--- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
@@ -20,6 +20,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/media_router/common/media_source.h"
 #include "components/media_router/common/route_request_result.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
@@ -280,7 +281,7 @@
 
 WiredDisplayMediaRouteProvider::Presentation::Presentation(
     const MediaRoute& route)
-    : route_(route), status_(base::in_place) {}
+    : route_(route), status_(absl::in_place) {}
 
 WiredDisplayMediaRouteProvider::Presentation::Presentation(
     Presentation&& other) = default;
diff --git a/chrome/browser/metrics/chromeos_metrics_provider.cc b/chrome/browser/metrics/chromeos_metrics_provider.cc
index e084f28..10d6189 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider.cc
+++ b/chrome/browser/metrics/chromeos_metrics_provider.cc
@@ -40,6 +40,7 @@
 #include "chrome/common/pref_names.h"
 #include "chromeos/system/statistics_provider.h"
 #include "components/metrics/metrics_service.h"
+#include "components/metrics/structured/recorder.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_manager/user.h"
@@ -317,6 +318,11 @@
     base::OnceClosure callback,
     std::string full_hardware_class) {
   full_hardware_class_ = full_hardware_class;
+
+  // Structured metrics needs to know when full hardware class is available
+  // since events should have full hardware class populated. Notify structured
+  // metrics recorder that HWID is available to start sending events.
+  metrics::structured::Recorder::GetInstance()->OnHardwareClassInitialized();
   std::move(callback).Run();
 }
 
diff --git a/chrome/browser/metrics/variations/chrome_variations_service_client.cc b/chrome/browser/metrics/variations/chrome_variations_service_client.cc
index 33ad153c..1717526b5 100644
--- a/chrome/browser/metrics/variations/chrome_variations_service_client.cc
+++ b/chrome/browser/metrics/variations/chrome_variations_service_client.cc
@@ -77,7 +77,7 @@
 
 bool ChromeVariationsServiceClient::IsEnterprise() {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-  return base::IsMachineExternallyManaged();
+  return base::IsEnterpriseDevice();
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
   return ash::InstallAttributes::Get()->IsEnterpriseManaged();
 #else
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index f614ad3d..8c2239b 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -9,7 +9,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "base/files/file_util.h"
 #include "base/system/sys_info.h"
 #include "chrome/common/chrome_paths.h"
@@ -24,8 +24,7 @@
 
 bool g_access_to_all_files_enabled = false;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) || \
-    BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
 // Returns true if |allowlist| contains |path| or a parent of |path|.
 bool IsPathOnAllowlist(const base::FilePath& path,
                        const std::vector<base::FilePath>& allowlist) {
@@ -40,7 +39,7 @@
 }
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 // Returns true if access is allowed for |path| for a user with |profile_path).
 bool IsAccessAllowedChromeOS(const base::FilePath& path,
                              const base::FilePath& profile_path) {
@@ -120,7 +119,7 @@
 
   return IsPathOnAllowlist(path, allowlist);
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(IS_ANDROID)
 // Returns true if access is allowed for |path|.
@@ -164,7 +163,7 @@
   if (g_access_to_all_files_enabled)
     return true;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
   return IsAccessAllowedChromeOS(path, profile_path);
 #elif BUILDFLAG(IS_ANDROID)
   return IsAccessAllowedAndroid(path);
diff --git a/chrome/browser/net/chrome_network_delegate_browsertest.cc b/chrome/browser/net/chrome_network_delegate_browsertest.cc
index 7f30f021..cfb3f4d5 100644
--- a/chrome/browser/net/chrome_network_delegate_browsertest.cc
+++ b/chrome/browser/net/chrome_network_delegate_browsertest.cc
@@ -6,7 +6,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/net/chrome_network_delegate.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -21,7 +20,7 @@
 #include "net/base/network_delegate.h"
 #include "url/gurl.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 
 class ChromeNetworkDelegateBrowserTest : public InProcessBrowserTest {
  public:
@@ -92,4 +91,4 @@
   EXPECT_EQ(net::ERR_ACCESS_DENIED, observer.last_net_error_code());
 }
 
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/net/chrome_network_delegate_unittest.cc b/chrome/browser/net/chrome_network_delegate_unittest.cc
index 3344083..9464f21 100644
--- a/chrome/browser/net/chrome_network_delegate_unittest.cc
+++ b/chrome/browser/net/chrome_network_delegate_unittest.cc
@@ -10,7 +10,7 @@
 #include "build/chromeos_buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "base/files/file_util.h"
 #include "base/system/sys_info.h"
 #include "base/test/scoped_running_on_chromeos.h"
@@ -35,8 +35,7 @@
 }  // namespace
 
 TEST(ChromeNetworkDelegateStaticTest, IsAccessAllowed) {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) || \
-    BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
   // Chrome OS and Android don't have access to random files.
   EXPECT_FALSE(IsAccessAllowed("/", ""));
   EXPECT_FALSE(IsAccessAllowed("/foo.txt", ""));
@@ -48,7 +47,7 @@
   EXPECT_TRUE(IsAccessAllowed("/foo.txt", ""));
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
   base::FilePath temp_dir;
   ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &temp_dir));
   // Chrome OS allows the following directories.
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc
index 2cba5fc3..f7487e8 100644
--- a/chrome/browser/net/dns_probe_browsertest.cc
+++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -409,7 +409,7 @@
     // Mark as not enterprise managed to prevent the secure DNS mode from
     // being downgraded to off.
     base::win::ScopedDomainStateForTesting scoped_domain(false);
-    EXPECT_FALSE(base::IsMachineExternallyManaged());
+    EXPECT_FALSE(base::IsEnterpriseDevice());
 #endif
 
     // Set the mocked policy provider to act as if no policies are in use by
diff --git a/chrome/browser/net/stub_resolver_config_reader.cc b/chrome/browser/net/stub_resolver_config_reader.cc
index afb2869..1837ace 100644
--- a/chrome/browser/net/stub_resolver_config_reader.cc
+++ b/chrome/browser/net/stub_resolver_config_reader.cc
@@ -228,7 +228,10 @@
   if (android_has_owner_.value_or(false))
     return true;
 #elif BUILDFLAG(IS_WIN)
-  if (base::IsMachineExternallyManaged())
+  // TODO (crbug.com/1320766): For legacy compatibility, this uses
+  // IsEnterpriseDevice() which effectively equates to a domain join check.
+  // Consider whether this should use IsManagedDevice() instead.
+  if (base::IsEnterpriseDevice())
     return true;
 #endif
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/net/stub_resolver_config_reader_browsertest.cc b/chrome/browser/net/stub_resolver_config_reader_browsertest.cc
index 5d5b2a02..b151c34 100644
--- a/chrome/browser/net/stub_resolver_config_reader_browsertest.cc
+++ b/chrome/browser/net/stub_resolver_config_reader_browsertest.cc
@@ -115,7 +115,7 @@
   // Mark as not enterprise managed.
 #if BUILDFLAG(IS_WIN)
   base::win::ScopedDomainStateForTesting scoped_domain(false);
-  EXPECT_FALSE(base::IsMachineExternallyManaged());
+  EXPECT_FALSE(base::IsEnterpriseDevice());
 #endif
 
   std::string good_post_template = "https://foo.test/";
@@ -220,7 +220,7 @@
 // Mark as not enterprise managed.
 #if BUILDFLAG(IS_WIN)
   base::win::ScopedDomainStateForTesting scoped_domain(false);
-  EXPECT_FALSE(base::IsMachineExternallyManaged());
+  EXPECT_FALSE(base::IsEnterpriseDevice());
 #endif
 
   // Start with default non-set policies.
@@ -298,7 +298,7 @@
 // Mark as not enterprise managed.
 #if BUILDFLAG(IS_WIN)
   base::win::ScopedDomainStateForTesting scoped_domain(false);
-  EXPECT_FALSE(base::IsMachineExternallyManaged());
+  EXPECT_FALSE(base::IsEnterpriseDevice());
 #endif
 
   config_reader_->OverrideParentalControlsForTesting(
diff --git a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc
index feac08f..8e4d22e 100644
--- a/chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc
+++ b/chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc
@@ -14,7 +14,6 @@
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "chrome/browser/new_tab_page/one_google_bar/one_google_bar_data.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/webui_url_constants.h"
@@ -31,7 +30,7 @@
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "url/gurl.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/signin/chrome_signin_helper.h"
 #include "components/signin/core/browser/chrome_connected_header_helper.h"
 #include "components/signin/core/browser/signin_header_helper.h"
@@ -166,7 +165,7 @@
 
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   const GURL api_url_;
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
   const bool account_consistency_mirror_required_;
 #endif
 
@@ -183,7 +182,7 @@
     LoadDoneCallback callback)
     : url_loader_factory_(url_loader_factory),
       api_url_(std::move(api_url)),
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
       account_consistency_mirror_required_(account_consistency_mirror_required),
 #endif
       callback_(std::move(callback)) {
@@ -193,7 +192,7 @@
     network::ResourceRequest* request) const {
   variations::AppendVariationsHeaderUnknownSignedIn(
       api_url_, variations::InIncognito::kNo, request);
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
   signin::ChromeConnectedHeaderHelper chrome_connected_header_helper(
       account_consistency_mirror_required_
           ? signin::AccountConsistencyMethod::kMirror
@@ -222,7 +221,7 @@
     request->headers.SetHeader(signin::kChromeConnectedHeader,
                                chrome_connected_header_value);
   }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 void OneGoogleBarLoaderImpl::AuthenticatedURLLoader::Start() {
diff --git a/chrome/browser/offline_pages/android/BUILD.gn b/chrome/browser/offline_pages/android/BUILD.gn
index 9864c3d..d17e7ae 100644
--- a/chrome/browser/offline_pages/android/BUILD.gn
+++ b/chrome/browser/offline_pages/android/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [ "java/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchConfiguration.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/optimization_guide/android/BUILD.gn b/chrome/browser/optimization_guide/android/BUILD.gn
index 79820c8..ad33e46 100644
--- a/chrome/browser/optimization_guide/android/BUILD.gn
+++ b/chrome/browser/optimization_guide/android/BUILD.gn
@@ -50,7 +50,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:jni_java",
     "//chrome/browser/flags:java",
     "//chrome/browser/profiles/android:java",
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
index 5bb54f3..c0dde0ba 100644
--- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
+++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -480,6 +480,10 @@
       "OptimizationGuide.PageContentAnnotationsService."
       "ContentAnnotationsStorageStatus",
       PageContentAnnotationsStorageStatus::kSuccess, 1);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.PageContentAnnotationsService."
+      "ContentAnnotationsStorageStatus.ModelAnnotations",
+      PageContentAnnotationsStorageStatus::kSuccess, 1);
 
   absl::optional<history::VisitContentAnnotations> got_content_annotations =
       GetContentAnnotationsForURL(url);
@@ -550,6 +554,10 @@
         "OptimizationGuide.PageContentAnnotationsService."
         "ContentAnnotationsStorageStatus",
         PageContentAnnotationsStorageStatus::kNoVisitsForUrl, 1);
+    histogram_tester.ExpectUniqueSample(
+        "OptimizationGuide.PageContentAnnotationsService."
+        "ContentAnnotationsStorageStatus.ModelAnnotations",
+        PageContentAnnotationsStorageStatus::kNoVisitsForUrl, 1);
 
     EXPECT_FALSE(GetContentAnnotationsForURL(history_visit.url).has_value());
   }
@@ -615,6 +623,10 @@
       "OptimizationGuide.PageContentAnnotationsService."
       "ContentAnnotationsStorageStatus",
       PageContentAnnotationsStorageStatus::kSuccess, 1);
+  histogram_tester.ExpectUniqueSample(
+      "OptimizationGuide.PageContentAnnotationsService."
+      "ContentAnnotationsStorageStatus.ModelAnnotations",
+      PageContentAnnotationsStorageStatus::kSuccess, 1);
 
   absl::optional<history::VisitContentAnnotations> got_content_annotations =
       GetContentAnnotationsForURL(url);
diff --git a/chrome/browser/page_annotations/test/android/BUILD.gn b/chrome/browser/page_annotations/test/android/BUILD.gn
index 000ebaa..9ae26ea 100644
--- a/chrome/browser/page_annotations/test/android/BUILD.gn
+++ b/chrome/browser/page_annotations/test/android/BUILD.gn
@@ -44,7 +44,6 @@
   sources = [ "java/src/org/chromium/chrome/browser/page_annotations/PageAnnotationsServiceFactoryUnitTest.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/browser/endpoint_fetcher:java",
diff --git a/chrome/browser/partnercustomizations/BUILD.gn b/chrome/browser/partnercustomizations/BUILD.gn
index 1e4bbbe..9ff2773 100644
--- a/chrome/browser/partnercustomizations/BUILD.gn
+++ b/chrome/browser/partnercustomizations/BUILD.gn
@@ -51,7 +51,6 @@
   deps = [
     ":delegate_java",
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/test/android:chrome_java_test_support",
@@ -73,7 +72,6 @@
     ":delegate_java",
     ":java",
     ":test_support_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/password_check/android/BUILD.gn b/chrome/browser/password_check/android/BUILD.gn
index fee4674..09998bb 100644
--- a/chrome/browser/password_check/android/BUILD.gn
+++ b/chrome/browser/password_check/android/BUILD.gn
@@ -68,7 +68,6 @@
 
 android_library("public_ui_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//url:gurl_java",
   ]
@@ -123,7 +122,6 @@
     ":public_ui_java",
     "internal:internal_java",
     "internal:internal_ui_factory_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/android:chrome_java",
diff --git a/chrome/browser/password_edit_dialog/android/BUILD.gn b/chrome/browser/password_edit_dialog/android/BUILD.gn
index e3704be..3ef993d 100644
--- a/chrome/browser/password_edit_dialog/android/BUILD.gn
+++ b/chrome/browser/password_edit_dialog/android/BUILD.gn
@@ -90,7 +90,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/browser/flags:java",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 80fa95d..5de6e92 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/safe_browsing/user_interaction_observer.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/sync/sync_service_factory.h"
+#include "chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/passwords/password_generation_popup_controller_impl.h"
 #include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h"
@@ -430,12 +431,25 @@
     PasswordManagerDriver* driver,
     autofill::mojom::SubmissionReadinessState submission_readiness) {
 #if BUILDFLAG(IS_ANDROID)
+  std::vector<TouchToFillWebAuthnCredential> webauthn_credentials;
+  if (GetWebAuthnCredentialsDelegate() &&
+      GetWebAuthnCredentialsDelegate()->IsWebAuthnAutofillEnabled()) {
+    const std::vector<autofill::Suggestion>& suggestions =
+        GetWebAuthnCredentialsDelegate()->GetWebAuthnSuggestions();
+    base::ranges::transform(suggestions,
+                            std::back_inserter(webauthn_credentials),
+                            [](const auto& suggestion) {
+                              return TouchToFillWebAuthnCredential(
+                                  suggestion.value, suggestion.backend_id);
+                            });
+  }
+
   GetOrCreateTouchToFillController()->Show(
       credential_cache_
           .GetCredentialStore(url::Origin::Create(
               driver->GetLastCommittedURL().DeprecatedGetOriginAsURL()))
           .GetCredentials(),
-      driver->AsWeakPtr(), submission_readiness);
+      webauthn_credentials, driver->AsWeakPtr(), submission_readiness);
 #endif
 }
 
diff --git a/chrome/browser/payments/android/BUILD.gn b/chrome/browser/payments/android/BUILD.gn
index 86ee060..5128ac7 100644
--- a/chrome/browser/payments/android/BUILD.gn
+++ b/chrome/browser/payments/android/BUILD.gn
@@ -18,7 +18,6 @@
   bypass_platform_checks = true
   testonly = true
   deps = [
-    "//base:base_java",
     "//build/android:build_java",
     "//chrome/android:chrome_java",
     "//chrome/browser/android/lifecycle:java",
@@ -54,7 +53,6 @@
   testonly = true
   deps = [
     ":junit_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//build/android:build_java",
diff --git a/chrome/browser/performance_hints/android/BUILD.gn b/chrome/browser/performance_hints/android/BUILD.gn
index 24a2d21e..8d2afb8 100644
--- a/chrome/browser/performance_hints/android/BUILD.gn
+++ b/chrome/browser/performance_hints/android/BUILD.gn
@@ -12,7 +12,6 @@
   sources = [ "java/src/org/chromium/chrome/browser/performance_hints/PerformanceHintsObserver.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/android:content_java",
diff --git a/chrome/browser/policy/android/BUILD.gn b/chrome/browser/policy/android/BUILD.gn
index 02e961e..cfc46fd8 100644
--- a/chrome/browser/policy/android/BUILD.gn
+++ b/chrome/browser/policy/android/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [ "java/src/org/chromium/chrome/browser/policy/CloudManagementSharedPreferences.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//chrome/browser/preferences:java",
     "//components/policy/android:policy_java",
@@ -24,7 +23,6 @@
   ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/browser/profiles/android:java",
diff --git a/chrome/browser/policy/messaging_layer/public/report_client.cc b/chrome/browser/policy/messaging_layer/public/report_client.cc
index 9657258e..b26d082e 100644
--- a/chrome/browser/policy/messaging_layer/public/report_client.cc
+++ b/chrome/browser/policy/messaging_layer/public/report_client.cc
@@ -199,13 +199,13 @@
           [](base::OnceCallback<void(
                  StatusOr<scoped_refptr<StorageModuleInterface>>)>
                  storage_created_cb) {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
             if (StorageSelector::is_use_missive()) {
               StorageSelector::CreateMissiveStorageModule(
                   std::move(storage_created_cb));
               return;
             }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
             // Storage location in the local file system (if local storage is
             // enabled).
diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn
index 62feca1..ce9bedd8 100644
--- a/chrome/browser/preferences/BUILD.gn
+++ b/chrome/browser/preferences/BUILD.gn
@@ -65,7 +65,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index acd95e0..d6559432 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -177,10 +177,6 @@
      */
     public static final String CONTEXTUAL_SEARCH_ALL_TIME_TAP_QUICK_ANSWER_COUNT =
             "contextual_search_all_time_tap_quick_answer_count";
-    public static final KeyPrefix CONTEXTUAL_SEARCH_CLICKS_WEEK_PREFIX =
-            new KeyPrefix("contextual_search_clicks_week_*");
-    public static final String CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER =
-            "contextual_search_current_week_number";
     /**
      * The entity-data impressions count for Contextual Search, i.e. thumbnails shown in the Bar.
      * Cumulative, starting at M-69.
@@ -193,12 +189,8 @@
      */
     public static final String CONTEXTUAL_SEARCH_ENTITY_OPENS_COUNT =
             "contextual_search_entity_opens_count";
-    public static final KeyPrefix CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_PREFIX =
-            new KeyPrefix("contextual_search_impressions_week_*");
     public static final String CONTEXTUAL_SEARCH_LAST_ANIMATION_TIME =
             "contextual_search_last_animation_time";
-    public static final String CONTEXTUAL_SEARCH_NEWEST_WEEK = "contextual_search_newest_week";
-    public static final String CONTEXTUAL_SEARCH_OLDEST_WEEK = "contextual_search_oldest_week";
     /**
      * An encoded set of outcomes of user interaction with Contextual Search, stored as an int.
      */
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
index 5cd6662..9094cda 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
@@ -34,12 +34,9 @@
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_ALL_TIME_OPEN_COUNT,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_ALL_TIME_TAP_COUNT,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_ALL_TIME_TAP_QUICK_ANSWER_COUNT,
-                ChromePreferenceKeys.CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_ENTITY_IMPRESSIONS_COUNT,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_ENTITY_OPENS_COUNT,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_LAST_ANIMATION_TIME,
-                ChromePreferenceKeys.CONTEXTUAL_SEARCH_NEWEST_WEEK,
-                ChromePreferenceKeys.CONTEXTUAL_SEARCH_OLDEST_WEEK,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_PREVIOUS_INTERACTION_ENCODED_OUTCOMES,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_PREVIOUS_INTERACTION_EVENT_ID,
                 ChromePreferenceKeys.CONTEXTUAL_SEARCH_PREVIOUS_INTERACTION_TIMESTAMP,
@@ -174,8 +171,6 @@
     static List<KeyPrefix> getPrefixesInUse() {
         // clang-format off
         return Arrays.asList(
-                ChromePreferenceKeys.CONTEXTUAL_SEARCH_CLICKS_WEEK_PREFIX,
-                ChromePreferenceKeys.CONTEXTUAL_SEARCH_IMPRESSIONS_WEEK_PREFIX,
                 ChromePreferenceKeys.CUSTOM_TABS_DEX_LAST_UPDATE_TIME_PREF_PREFIX,
                 ChromePreferenceKeys.PAYMENTS_PAYMENT_INSTRUMENT_USE_COUNT,
                 ChromePreferenceKeys.PAYMENTS_PAYMENT_INSTRUMENT_USE_DATE,
diff --git a/chrome/browser/prefetch/android/BUILD.gn b/chrome/browser/prefetch/android/BUILD.gn
index 4ddbbc8..84ac0c30 100644
--- a/chrome/browser/prefetch/android/BUILD.gn
+++ b/chrome/browser/prefetch/android/BUILD.gn
@@ -20,7 +20,6 @@
   deps = [
     ":java_resources",
     ":jni_headers",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//chrome/browser/android/lifecycle:java",
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index f35f161..8d8eae1 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -216,13 +216,13 @@
 #if BUILDFLAG(IS_WIN)
   if (!g_disable_domain_check_for_testing) {
     static bool first_call = true;
-    static const bool is_managed = base::IsMachineExternallyManaged();
+    static const bool is_domain_joined = base::IsEnterpriseDevice();
     if (first_call) {
       UMA_HISTOGRAM_BOOLEAN("Settings.TrackedPreferencesNoEnforcementOnDomain",
-                            is_managed);
+                            is_domain_joined);
       first_call = false;
     }
-    if (is_managed)
+    if (is_domain_joined)
       return GROUP_NO_ENFORCEMENT;
   }
 #endif
diff --git a/chrome/browser/privacy/BUILD.gn b/chrome/browser/privacy/BUILD.gn
index 787317c7..400cba5 100644
--- a/chrome/browser/privacy/BUILD.gn
+++ b/chrome/browser/privacy/BUILD.gn
@@ -27,7 +27,6 @@
     deps = [
       ":java_resources",
       ":jni_headers",
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
       "//chrome/browser/android/lifecycle:java",
diff --git a/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter_unittest.cc b/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter_unittest.cc
index e431c9f..be4d33c0 100644
--- a/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter_unittest.cc
+++ b/chrome/browser/privacy_budget/privacy_budget_ukm_entry_filter_unittest.cc
@@ -8,7 +8,6 @@
 
 #include "base/containers/flat_map.h"
 #include "base/metrics/metrics_hashes.h"
-#include "base/template_util.h"
 #include "chrome/browser/privacy_budget/identifiability_study_state.h"
 #include "chrome/browser/privacy_budget/inspectable_identifiability_study_state.h"
 #include "chrome/common/privacy_budget/privacy_budget_features.h"
@@ -18,6 +17,7 @@
 #include "services/metrics/public/mojom/ukm_interface.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 
 using testing::IsSupersetOf;
@@ -35,7 +35,7 @@
 
   // By default the filter should reject all Identifiability events:
   base::flat_map<uint64_t, int64_t> events = {{1, 1}, {2, 2}};
-  ukm::mojom::UkmEntryPtr x(base::in_place, 1,
+  ukm::mojom::UkmEntryPtr x(absl::in_place, 1,
                             ukm::builders::Identifiability::kEntryNameHash,
                             events);
 
@@ -53,7 +53,7 @@
   auto filter = std::make_unique<PrivacyBudgetUkmEntryFilter>(state.get());
 
   base::flat_map<uint64_t, int64_t> events = {{1, 1}, {2, 2}};
-  ukm::mojom::UkmEntryPtr x(base::in_place, 1,
+  ukm::mojom::UkmEntryPtr x(absl::in_place, 1,
                             ukm::builders::Blink_UseCounter::kEntryNameHash,
                             events);
 
@@ -89,7 +89,7 @@
            .ToUkmMetricHash(),
        static_cast<int64_t>(kUnblockedSurface)}};
   ukm::mojom::UkmEntryPtr ukm_entry(
-      base::in_place, 1, ukm::builders::Identifiability::kEntryNameHash,
+      absl::in_place, 1, ukm::builders::Identifiability::kEntryNameHash,
       metrics);
 
   ASSERT_EQ(2u, ukm_entry->metrics.size());
@@ -115,7 +115,7 @@
 
   base::flat_map<uint64_t, int64_t> events = {{1, 1}, {2, 2}};
   ukm::mojom::UkmEntryPtr first_entry(
-      base::in_place, 1, ukm::builders::Identifiability::kEntryNameHash,
+      absl::in_place, 1, ukm::builders::Identifiability::kEntryNameHash,
       events);
   ukm::mojom::UkmEntryPtr second_entry = first_entry.Clone();
 
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
index 29ca537..1ee75252 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
@@ -51,6 +51,8 @@
  public:
   // Possible types of Privacy Sandbox dialogs that may be shown to the user.
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.privacy_sandbox
+  // TODO(crbug.com/1321587): Rename to PromptType as the UI can be presented as
+  // a bubble, a dialog or a bottomsheet.
   enum class DialogType {
     kNone = 0,
     kNotice = 1,
@@ -61,6 +63,8 @@
   // An exhaustive list of actions related to showing & interacting with the
   // dialog. Includes actions which do not impact consent / notice state.
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.privacy_sandbox
+  // TODO(crbug.com/1321587): Rename to PromptAction as the UI can be presented
+  // as a bubble, a dialog or a bottomsheet.
   enum class DialogAction {
     // Notice Interactions:
     kNoticeShown = 0,
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
index d99a8be..d63bffe 100644
--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -218,6 +218,7 @@
 #endif
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+#include "chrome/browser/supervised_user/supervised_user_metrics_service_factory.h"
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #endif
 
@@ -535,6 +536,7 @@
   StorageNotificationServiceFactory::GetInstance();
 #endif
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+  SupervisedUserMetricsServiceFactory::GetInstance();
   SupervisedUserServiceFactory::GetInstance();
 #endif
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index f34f255..ef00df6 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -124,7 +124,6 @@
       "components:closure_compile",
       "domain_reliability_internals:closure_compile",
       "engagement:closure_compile",
-      "media:closure_compile",
       "memory_internals:closure_compile",
       "reset_password:closure_compile",
     ]
diff --git a/chrome/browser/resources/chromeos/accessibility/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
index cddc859..893f22d1 100644
--- a/chrome/browser/resources/chromeos/accessibility/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/BUILD.gn
@@ -9,7 +9,7 @@
 import("//chromecast/chromecast.gni")
 import("strings/accessibility_strings.gni")
 
-assert(is_chromeos_ash || is_chromecast)
+assert(is_chromeos_ash || is_castos)
 
 accessibility_out_dir = "$root_out_dir/resources/chromeos/accessibility/"
 
diff --git a/chrome/browser/resources/chromeos/accessibility/braille_ime/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/braille_ime/BUILD.gn
index 963487ff..e0c6d8a0 100644
--- a/chrome/browser/resources/chromeos/accessibility/braille_ime/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/braille_ime/BUILD.gn
@@ -6,7 +6,7 @@
 import("//chromecast/chromecast.gni")
 import("//third_party/closure_compiler/compile_js.gni")
 
-assert(is_chromeos_ash || is_chromecast)
+assert(is_chromeos_ash || is_castos)
 
 copy("braille_ime_manifest") {
   sources = [ "manifest.json" ]
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
index 0ef94bc..b2cf000 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -61,6 +61,7 @@
   "common/log_types.js",
   "common/msgs.js",
   "common/panel_command.js",
+  "common/panel_menu_data.js",
   "common/spannable.js",
   "common/tree_dumper.js",
   "common/tts_interface.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_menu_data.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_menu_data.js
new file mode 100644
index 0000000..6f30009
--- /dev/null
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/panel_menu_data.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.
+
+/**
+ * @fileoverview Data types for transferring information about panel menus from
+ * the background context to the panel context.
+ */
+
+goog.provide('PanelNodeMenuData');
+goog.provide('ALL_NODE_MENU_DATA');
+
+goog.require('AutomationPredicate');
+
+/** @typedef {{titleId: string, predicate: !AutomationPredicate.Unary}} */
+let PanelNodeMenuData;
+
+
+/** @const {!Array<!PanelNodeMenuData>} */
+ALL_NODE_MENU_DATA = [
+  {titleId: 'role_heading', predicate: AutomationPredicate.heading},
+  {titleId: 'role_landmark', predicate: AutomationPredicate.landmark},
+  {titleId: 'role_link', predicate: AutomationPredicate.link},
+  {
+    titleId: 'panel_menu_form_controls',
+    predicate: AutomationPredicate.formField
+  },
+  {titleId: 'role_table', predicate: AutomationPredicate.table},
+];
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
index 37be154..5a33834 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel.js
@@ -495,24 +495,12 @@
             Panel.onClose();
           });
 
-      const roleListMenuMapping = [
-        {menuTitle: 'role_heading', predicate: AutomationPredicate.heading},
-        {menuTitle: 'role_landmark', predicate: AutomationPredicate.landmark},
-        {menuTitle: 'role_link', predicate: AutomationPredicate.link}, {
-          menuTitle: 'panel_menu_form_controls',
-          predicate: AutomationPredicate.formField
-        },
-        {menuTitle: 'role_table', predicate: AutomationPredicate.table}
-      ];
-
-      for (let i = 0; i < roleListMenuMapping.length; ++i) {
-        const menuTitle = roleListMenuMapping[i].menuTitle;
-        const predicate = roleListMenuMapping[i].predicate;
+      for (const menuData of ALL_NODE_MENU_DATA) {
         // Create node menus asynchronously (because it may require
         // searching a long document) unless that's the specific menu the
         // user requested.
-        const async = (menuTitle !== opt_activateMenuTitle);
-        Panel.addNodeMenu(menuTitle, node, predicate, async);
+        const isActivatedMenu = (menuData.titleId === opt_activateMenuTitle);
+        Panel.addNodeMenu(menuData, node, isActivatedMenu);
       }
 
       if (node && node.standardActions) {
@@ -751,20 +739,22 @@
 
   /**
    * Create a new node menu with the given name and add it to the menu bar.
-   * @param {string} menuMsg The msg id of the new menu to add.
+   * @param {!PanelNodeMenuData} menuData The title/predicate for the new menu.
    * @param {!chrome.automation.AutomationNode} node
-   * @param {AutomationPredicate.Unary} pred
-   * @param {boolean} defer If true, defers populating the menu.
+   * @param {boolean} isActivatedMenu Whether the menu was explicitly activated
+   *     or not. If not, defer population to asynchronous callbacks.
    * @return {PanelMenu} The menu just created.
    */
-  static addNodeMenu(menuMsg, node, pred, defer) {
-    const menu = new PanelNodeMenu(menuMsg, node, pred, defer);
+  static addNodeMenu(menuData, node, isActivatedMenu) {
+    const menu = new PanelNodeMenu(
+        menuData.titleId, node, menuData.predicate,
+        /* defer= */ !isActivatedMenu);
     $('menu-bar').appendChild(menu.menuBarItemElement);
-    menu.menuBarItemElement.addEventListener('mouseover', function() {
+    menu.menuBarItemElement.addEventListener('mouseover', () => {
       Panel.activateMenu(menu, true /* activateFirstItem */);
-    }, false);
+    });
     menu.menuBarItemElement.addEventListener(
-        'mouseup', Panel.onMouseUpOnMenuTitle_.bind(this, menu), false);
+        'mouseup', event => Panel.onMouseUpOnMenuTitle_(menu, event));
     $('menus_background').appendChild(menu.menuContainerElement);
     Panel.menus_.push(menu);
     return menu;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js
index 3431e5c..2c6431ed 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js
@@ -19,7 +19,9 @@
 goog.require('Output');
 goog.require('Output');
 goog.require('PanelCommand');
+goog.require('PanelNodeMenuData');
 goog.require('QueueMode');
 goog.require('constants');
 goog.require('cursors.Cursor');
 goog.require('cursors.Range');
+goog.require('ALL_NODE_MENU_DATA');
diff --git a/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
index 7f4db668..f5ccc842 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
+++ b/chrome/browser/resources/chromeos/accessibility/common/BUILD.gn
@@ -12,7 +12,7 @@
 import("//third_party/closure_compiler/compile_js.gni")
 import("//third_party/closure_compiler/js_unit_tests.gni")
 
-assert(is_chromeos_ash || is_chromecast)
+assert(is_chromeos_ash || is_castos)
 
 accessibility_common_out_dir =
     "$root_out_dir/resources/chromeos/accessibility/common"
diff --git a/chrome/browser/resources/chromeos/accessibility/tools/run_jsbundler.gni b/chrome/browser/resources/chromeos/accessibility/tools/run_jsbundler.gni
index 590e1be..c4dddd06e 100644
--- a/chrome/browser/resources/chromeos/accessibility/tools/run_jsbundler.gni
+++ b/chrome/browser/resources/chromeos/accessibility/tools/run_jsbundler.gni
@@ -4,7 +4,7 @@
 import("//build/config/chromeos/ui_mode.gni")
 import("//chromecast/chromecast.gni")
 
-assert(is_chromeos_ash || is_chromecast)
+assert(is_chromeos_ash || is_castos)
 
 closure_library_dir =
     "//third_party/chromevox/third_party/closure-library/closure/goog"
diff --git a/chrome/browser/resources/chromeos/login/screens.js b/chrome/browser/resources/chromeos/login/screens.js
index 2a278a4..f182b59e 100644
--- a/chrome/browser/resources/chromeos/login/screens.js
+++ b/chrome/browser/resources/chromeos/login/screens.js
@@ -89,7 +89,6 @@
    {tag: 'marketing-opt-in-element', id: 'marketing-opt-in'},
    {tag: 'multidevice-setup-element', id: 'multidevice-setup-screen'},
    {tag: 'offline-ad-login-element', id: 'offline-ad-login'},
-   {tag: 'oobe-eula-element', id: 'oobe-eula-md'},
    {tag: 'oobe-reset-element', id: 'reset'},
    {tag: 'os-install-element', id: 'os-install', condition: 'isOsInstallAllowed'},
    {tag: 'os-trial-element', id: 'os-trial', condition: 'isOsInstallAllowed'},
@@ -130,6 +129,7 @@
     {tag: 'enable-debugging-element', id: 'debugging'},
     {tag: 'enterprise-enrollment-element', id: 'enterprise-enrollment'},
     {tag: 'hid-detection-element', id: 'hid-detection'},
+    {tag: 'oobe-eula-element', id: 'oobe-eula-md'},
     {tag: 'oobe-network-element', id: 'network-selection'},
     {tag: 'packaged-license-element', id: 'packaged-license'},
     {tag: 'quick-start-element', id: 'quick-start'},
diff --git a/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.html b/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.html
index 0c3e21cf..365ed19 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.html
+++ b/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.html
@@ -71,7 +71,7 @@
       </div>
       <div slot="subtitle" class="update-subtitle" hidden="[[!cancelAllowed]]"
           id="checkingForUpdateCancelHint">
-        [[i18nDynamic(locale, cancelHintKey)]]
+        [[i18nDynamic(locale, 'cancelUpdateHint')]]
       </div>
       <paper-progress slot="progress" id="checking-progress"
           indeterminate="[[checkingForUpdate]]">
@@ -93,7 +93,7 @@
       <div slot="subtitle">
         <div>[[i18nDynamic(locale, downloadingUpdatesKey)]]</div>
         <div hidden="[[!cancelAllowed]]">
-          [[i18nDynamic(locale, cancelHintKey)]]
+          [[i18nDynamic(locale, 'cancelUpdateHint')]]
         </div>
         <div id="progress-message" class="progress-message">
           [[progressMessage_]]
diff --git a/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.js b/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.js
index 5f743218..282effda 100644
--- a/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.js
+++ b/chrome/browser/resources/chromeos/login/screens/login/checking_downloading_update.js
@@ -95,11 +95,6 @@
       downloadingUpdatesKey: String,
 
       /**
-       * ID of the localized string for update cancellation message.
-       */
-      cancelHintKey: String,
-
-      /**
        * Message "3 minutes left".
        */
       estimatedTimeLeftMsg_: {
diff --git a/chrome/browser/resources/history/app.ts b/chrome/browser/resources/history/app.ts
index b1bce182..dbe1fa2 100644
--- a/chrome/browser/resources/history/app.ts
+++ b/chrome/browser/resources/history/app.ts
@@ -32,7 +32,6 @@
 import {BrowserService, BrowserServiceImpl} from './browser_service.js';
 import {HistoryPageViewHistogram} from './constants.js';
 import {ForeignSession, QueryResult, QueryState} from './externs.js';
-import {BrowserProxyImpl} from './history_clusters/browser_proxy.js';
 import {HistoryListElement} from './history_list.js';
 import {HistoryToolbarElement} from './history_toolbar.js';
 import {Page, TABBED_PAGES} from './router.js';
@@ -551,13 +550,6 @@
     this.browserService_!.recordHistogram(
         'History.HistoryPageView', histogramValue,
         HistoryPageViewHistogram.END);
-
-    // We don't use `this.browserService_` here, because its chrome.send message
-    // handling is deprecated, and none of the handlers attached to
-    // `this.browserService_` handle History Clusters logic.
-    BrowserProxyImpl.getInstance().handler.notifyHistoryClustersSelected(
-        this.historyClustersSelected_(
-            this.selectedPage_!, this.showHistoryClusters_));
   }
 
   // Override FindShortcutMixin methods.
diff --git a/chrome/browser/resources/media/BUILD.gn b/chrome/browser/resources/media/BUILD.gn
index c1660c2..b46d1ea 100644
--- a/chrome/browser/resources/media/BUILD.gn
+++ b/chrome/browser/resources/media/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//chrome/common/features.gni")
-import("//third_party/closure_compiler/compile_js.gni")
 import("//tools/grit/grit_rule.gni")
 import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/typescript/ts_library.gni")
@@ -12,7 +11,10 @@
 preprocess_folder = "preprocessed"
 copy("copy_mojo") {
   deps = [ "//chrome/browser/media:mojo_bindings_js" ]
-  sources = [ "$root_gen_dir/mojom-webui/chrome/browser/media/history/media_history_store.mojom-webui.js" ]
+  sources = [
+    "$root_gen_dir/mojom-webui/chrome/browser/media/history/media_history_store.mojom-webui.js",
+    "$root_gen_dir/mojom-webui/chrome/browser/media/media_engagement_score_details.mojom-webui.js",
+  ]
   outputs = [ "$target_gen_dir/$preprocess_folder/{{source_file_part}}" ]
 }
 
@@ -21,20 +23,33 @@
   in_files = [
     "media_history.ts",
     "media_data_table.ts",
+    "media_engagement.ts",
+    "webrtc_logs.ts",
   ]
   out_folder = "$target_gen_dir/$preprocess_folder"
 }
 
+# Exclude these files from ts_library()'s output manifest, since they are
+# manually registered in dev_ui_browser_resources.grd.
+non_manifest_files = [
+  "media_history.ts",
+  "media_data_table.ts",
+  "media_engagement.ts",
+  "media_engagement_score_details.mojom-webui.js",
+  "media_history_store.mojom-webui.js",
+]
+
 ts_library("build_ts") {
   root_dir = "$target_gen_dir/$preprocess_folder"
   out_dir = target_gen_dir
   tsconfig_base = "tsconfig_base.json"
-  in_files = [
-    "media_history.ts",
-    "media_data_table.ts",
-    "media_history_store.mojom-webui.js",
+  in_files = non_manifest_files + [ "webrtc_logs.ts" ]
+  manifest_excludes = non_manifest_files
+
+  deps = [
+    "//ui/webui/resources:library",
+    "//ui/webui/resources/mojo:library",
   ]
-  deps = [ "//ui/webui/resources:library" ]
   extra_deps = [
     ":copy_mojo",
     ":preprocess_src",
@@ -47,9 +62,10 @@
   input_files = [
     "webrtc_logs.css",
     "webrtc_logs.html",
-    "webrtc_logs.js",
   ]
   input_files_base_dir = rebase_path(".", "//")
+  manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
+  deps = [ ":build_ts" ]
 }
 
 grit("webrtc_logs_resources") {
@@ -66,28 +82,3 @@
   ]
   output_dir = "$root_gen_dir/chrome"
 }
-
-js_type_check("closure_compile") {
-  closure_flags = default_closure_args + mojom_js_args + [
-                    "js_module_root=" + rebase_path(".", root_build_dir),
-                    "js_module_root=" + rebase_path(
-                            "$root_gen_dir/mojom-webui/chrome/browser/media/history",
-                            root_build_dir),
-                    "js_module_root=" + rebase_path(
-                            "$root_gen_dir/mojom-webui/chrome/browser/media/",
-                            root_build_dir),
-                    "js_module_root=" + rebase_path(
-                            "$root_gen_dir/mojom-webui/services/media_session/public/mojom/",
-                            root_build_dir),
-                  ]
-  deps = [ ":media_engagement" ]
-}
-
-js_library("media_engagement") {
-  deps = [
-    "//chrome/browser/media:mojo_bindings_webui_js",
-    "//ui/webui/resources/js:assert.m",
-    "//ui/webui/resources/js:promise_resolver.m",
-    "//ui/webui/resources/js:util.m",
-  ]
-}
diff --git a/chrome/browser/resources/media/media_engagement.js b/chrome/browser/resources/media/media_engagement.js
deleted file mode 100644
index feec1fd..0000000
--- a/chrome/browser/resources/media/media_engagement.js
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assertNotReached} from 'chrome://resources/js/assert.m.js';
-import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
-import {$} from 'chrome://resources/js/util.m.js';
-import {Origin} from 'chrome://resources/mojo/url/mojom/origin.mojom-webui.js';
-
-import {MediaEngagementConfig, MediaEngagementScoreDetails, MediaEngagementScoreDetailsProvider} from './media_engagement_score_details.mojom-webui.js';
-
-// Allow a function to be provided by tests, which will be called when
-// the page has been populated with media engagement details.
-const pageIsPopulatedResolver = new PromiseResolver();
-window.whenPageIsPopulatedForTest = function() {
-  return pageIsPopulatedResolver.promise;
-};
-
-let detailsProvider = null;
-let info = null;
-let engagementTableBody = null;
-let sortReverse = true;
-let sortKey = 'totalScore';
-let configTableBody = null;
-let showNoPlaybacks = false;
-
-/**
- * Creates a single row in the engagement table.
- * @param {!MediaEngagementScoreDetails} rowInfo The info to create
- *     the row.
- * @return {!HTMLElement}
- */
-function createRow(rowInfo) {
-  const template = $('datarow');
-  const td = template.content.querySelectorAll('td');
-
-  td[0].textContent = rowInfo.origin.scheme + '://' + rowInfo.origin.host;
-  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) {
-    td[0].textContent += ':' + rowInfo.origin.port;
-  }
-
-  td[1].textContent = rowInfo.visits;
-  td[2].textContent = rowInfo.mediaPlaybacks;
-  td[3].textContent = rowInfo.lastMediaPlaybackTime ?
-      new Date(rowInfo.lastMediaPlaybackTime).toISOString() :
-      '';
-  td[4].textContent = rowInfo.isHigh ? 'Yes' : 'No';
-  td[5].textContent = rowInfo.totalScore ? rowInfo.totalScore.toFixed(2) : '0';
-  td[6].getElementsByClassName('engagement-bar')[0].style.width =
-      (rowInfo.totalScore * 50) + 'px';
-  return /** @type {!HTMLElement} */ (
-      document.importNode(template.content, true));
-}
-
-/**
- * Remove all rows from the engagement table.
- */
-function clearTable() {
-  engagementTableBody.innerHTML = trustedTypes.emptyHTML;
-}
-
-/**
- * Sort the engagement info based on |sortKey| and |sortReverse|.
- */
-function sortInfo() {
-  info.sort((a, b) => {
-    return (sortReverse ? -1 : 1) * compareTableItem(sortKey, a, b);
-  });
-}
-
-/**
- * Compares two MediaEngagementScoreDetails objects based on |sortKey|.
- * @param {string} sortKey The name of the property to sort by.
- * @param {Object|Origin} a The first object to compare.
- * @param {Object|Origin} b The second object to compare.
- * @return {number} A negative number if |a| should be ordered before
- *     |b|, a positive number otherwise.
- */
-function compareTableItem(sortKey, a, b) {
-  const val1 = a[sortKey];
-  const val2 = b[sortKey];
-
-  // Compare the hosts of the origin ignoring schemes.
-  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') {
-    return val1 - val2;
-  }
-
-  assertNotReached('Unsupported sort key: ' + sortKey);
-  return 0;
-}
-
-/**
- * Creates a single row in the config table.
- * @param {string} name The name of the config setting.
- * @param {number|string} value The value of the config setting.
- * @return {!HTMLElement}
- */
-function createConfigRow(name, value) {
-  const template = $('configrow');
-  const td = template.content.querySelectorAll('td');
-  td[0].textContent = name;
-  td[1].textContent = value;
-  return /** @type {!HTMLElement} */ (
-      document.importNode(template.content, true));
-}
-
-/**
- * Regenerates the config table.
- * @param {!MediaEngagementConfig} config The config of the MEI
- *     service.
- */
-
-function renderConfigTable(config) {
-  configTableBody.innerHTML = trustedTypes.emptyHTML;
-
-  configTableBody.appendChild(
-      createConfigRow('Min Sessions', config.scoreMinVisits));
-  configTableBody.appendChild(
-      createConfigRow('Lower Threshold', config.highScoreLowerThreshold));
-  configTableBody.appendChild(
-      createConfigRow('Upper Threshold', config.highScoreUpperThreshold));
-
-  configTableBody.appendChild(createConfigRow(
-      'Record MEI data', formatFeatureFlag(config.featureRecordData)));
-  configTableBody.appendChild(createConfigRow(
-      'Bypass autoplay based on MEI',
-      formatFeatureFlag(config.featureBypassAutoplay)));
-  configTableBody.appendChild(createConfigRow(
-      'Preload MEI data', formatFeatureFlag(config.featurePreloadData)));
-  configTableBody.appendChild(createConfigRow(
-      'MEI for HTTPS only', formatFeatureFlag(config.featureHttpsOnly)));
-  configTableBody.appendChild(createConfigRow(
-      'Autoplay disable settings',
-      formatFeatureFlag(config.featureAutoplayDisableSettings)));
-  configTableBody.appendChild(createConfigRow(
-      'Unified autoplay (preference)',
-      formatFeatureFlag(config.prefDisableUnifiedAutoplay)));
-  configTableBody.appendChild(createConfigRow(
-      'Custom autoplay policy',
-      formatFeatureFlag(config.hasCustomAutoplayPolicy)));
-  configTableBody.appendChild(
-      createConfigRow('Autoplay Policy', config.autoplayPolicy));
-  configTableBody.appendChild(createConfigRow(
-      'Preload version',
-      config.preloadVersion ? config.preloadVersion : 'Not Available'));
-}
-
-/**
- * Converts a boolean into a string value.
- * @param {boolean} value The value of the config setting.
- * @return {string}
- */
-function formatFeatureFlag(value) {
-  return value ? 'Enabled' : 'Disabled';
-}
-
-/**
- * Regenerates the engagement table from |info|.
- */
-function renderTable() {
-  clearTable();
-  sortInfo();
-  info.filter(rowInfo => (showNoPlaybacks || rowInfo.mediaPlaybacks > 0))
-      .forEach(rowInfo => engagementTableBody.appendChild(createRow(rowInfo)));
-}
-
-/**
- * Retrieve media engagement info and render the engagement table.
- */
-function updateEngagementTable() {
-  // Populate engagement table.
-  detailsProvider.getMediaEngagementScoreDetails().then(response => {
-    info = response.info;
-    renderTable();
-    pageIsPopulatedResolver.resolve();
-  });
-
-  // Populate config settings.
-  detailsProvider.getMediaEngagementConfig().then(response => {
-    renderConfigTable(response.config);
-  });
-}
-
-document.addEventListener('DOMContentLoaded', function() {
-  detailsProvider = MediaEngagementScoreDetailsProvider.getRemote();
-  updateEngagementTable();
-
-  engagementTableBody = $('engagement-table-body');
-  configTableBody = $('config-table-body');
-
-  // Set table header sort handlers.
-  const engagementTableHeader = $('engagement-table-header');
-  const headers = engagementTableHeader.children;
-  for (let i = 0; i < headers.length; i++) {
-    headers[i].addEventListener('click', (e) => {
-      const newSortKey = e.target.getAttribute('sort-key');
-      if (sortKey === newSortKey) {
-        sortReverse = !sortReverse;
-      } else {
-        sortKey = newSortKey;
-        sortReverse = false;
-      }
-      const oldSortColumn = document.querySelector('.sort-column');
-      oldSortColumn.classList.remove('sort-column');
-      e.target.classList.add('sort-column');
-      if (sortReverse) {
-        e.target.setAttribute('sort-reverse', '');
-      } else {
-        e.target.removeAttribute('sort-reverse');
-      }
-      renderTable();
-    });
-  }
-
-  // Add handler to 'copy all to clipboard' button
-  const copyAllToClipboardButton = $('copy-all-to-clipboard');
-  copyAllToClipboardButton.addEventListener('click', (e) => {
-    // Make sure nothing is selected
-    window.getSelection().removeAllRanges();
-
-    document.execCommand('selectAll');
-    document.execCommand('copy');
-
-    // And deselect everything at the end.
-    window.getSelection().removeAllRanges();
-  });
-
-  // Add handler to 'show no playbacks' checkbox
-  const showNoPlaybacksCheckbox = $('show-no-playbacks');
-  showNoPlaybacksCheckbox.addEventListener('change', (e) => {
-    showNoPlaybacks = e.target.checked;
-    renderTable();
-  });
-});
diff --git a/chrome/browser/resources/media/media_engagement.ts b/chrome/browser/resources/media/media_engagement.ts
new file mode 100644
index 0000000..c50596d
--- /dev/null
+++ b/chrome/browser/resources/media/media_engagement.ts
@@ -0,0 +1,259 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/mojo/url/mojom/origin.mojom-webui.js';
+
+import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
+import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
+
+import {MediaEngagementConfig, MediaEngagementScoreDetails, MediaEngagementScoreDetailsProvider, MediaEngagementScoreDetailsProviderRemote} from './media_engagement_score_details.mojom-webui.js';
+
+// Allow a function to be provided by tests, which will be called when
+// the page has been populated with media engagement details.
+const pageIsPopulatedResolver = new PromiseResolver<void>();
+function whenPageIsPopulatedForTest(): Promise<void> {
+  return pageIsPopulatedResolver.promise;
+}
+Object.assign(window, {whenPageIsPopulatedForTest});
+
+let detailsProvider: MediaEngagementScoreDetailsProviderRemote|null = null;
+let info: MediaEngagementScoreDetails[]|null = null;
+let engagementTableBody: HTMLElement|null = null;
+let sortReverse: boolean = true;
+let sortKey: string = 'totalScore';
+let configTableBody: HTMLElement|null = null;
+let showNoPlaybacks: boolean = false;
+
+/**
+ * Creates a single row in the engagement table.
+ */
+function createRow(rowInfo: MediaEngagementScoreDetails): DocumentFragment {
+  const template = document.querySelector<HTMLTemplateElement>('#datarow');
+  assert(template);
+  const td = template.content.querySelectorAll('td');
+
+  td[0]!.textContent = rowInfo.origin.scheme + '://' + rowInfo.origin.host;
+  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) {
+    td[0]!.textContent += ':' + rowInfo.origin.port;
+  }
+
+  td[1]!.textContent = rowInfo.visits.toString();
+  td[2]!.textContent = rowInfo.mediaPlaybacks.toString();
+  td[3]!.textContent = rowInfo.lastMediaPlaybackTime ?
+      new Date(rowInfo.lastMediaPlaybackTime).toISOString() :
+      '';
+  td[4]!.textContent = rowInfo.isHigh ? 'Yes' : 'No';
+  td[5]!.textContent = rowInfo.totalScore ? rowInfo.totalScore.toFixed(2) : '0';
+  td[6]!.querySelectorAll<HTMLElement>('.engagement-bar')[0]!.style.width =
+      (rowInfo.totalScore * 50) + 'px';
+  return document.importNode(template.content, true);
+}
+
+/**
+ * Remove all rows from the engagement table.
+ */
+function clearTable() {
+  assert(engagementTableBody);
+  engagementTableBody.innerHTML = window.trustedTypes ?
+      window.trustedTypes.emptyHTML as unknown as string :
+      '';
+}
+
+/**
+ * Sort the engagement info based on |sortKey| and |sortReverse|.
+ */
+function sortInfo() {
+  assert(info);
+  info.sort((a, b) => {
+    return (sortReverse ? -1 : 1) * compareTableItem(sortKey, a, b);
+  });
+}
+
+/**
+ * Compares two MediaEngagementScoreDetails objects based on |sortKey|.
+ * @param sortKey The name of the property to sort by.
+ * @param a The first object to compare.
+ * @param b The second object to compare.
+ * @return A negative number if |a| should be ordered before
+ *     |b|, a positive number otherwise.
+ */
+function compareTableItem(
+    sortKey: string, a: MediaEngagementScoreDetails,
+    b: MediaEngagementScoreDetails): number {
+  // Compare the hosts of the origin ignoring schemes.
+  if (sortKey === 'origin') {
+    return a.origin.host > b.origin.host ? 1 : -1;
+  }
+
+  if (sortKey === 'visits' || sortKey === 'mediaPlaybacks' ||
+      sortKey === 'lastMediaPlaybackTime' || sortKey === 'totalScore' ||
+      sortKey === 'audiblePlaybacks' || sortKey === 'significantPlaybacks' ||
+      sortKey === 'highScoreChanges' || sortKey === 'mediaElementPlaybacks' ||
+      sortKey === 'audioContextPlaybacks' || sortKey === 'isHigh') {
+    const val1 = (a as {[key: string]: any})[sortKey];
+    const val2 = (b as {[key: string]: any})[sortKey];
+
+    return (val1 as number) - (val2 as number);
+  }
+
+  assertNotReached('Unsupported sort key: ' + sortKey);
+}
+
+/**
+ * Creates a single row in the config table.
+ * @param name The name of the config setting.
+ * @param value The value of the config setting.
+ */
+function createConfigRow(name: string, value: number|string): DocumentFragment {
+  const template = document.querySelector<HTMLTemplateElement>('#configrow');
+  assert(template);
+  const td = template.content.querySelectorAll('td');
+  td[0]!.textContent = name;
+  td[1]!.textContent = value.toString();
+  return document.importNode(template.content, true);
+}
+
+/**
+ * Regenerates the config table.
+ * @param config The config of the MEI service.
+ */
+
+function renderConfigTable(config: MediaEngagementConfig) {
+  assert(configTableBody);
+  configTableBody.innerHTML = window.trustedTypes ?
+      (window.trustedTypes.emptyHTML as unknown as string) :
+      '';
+
+  configTableBody.appendChild(
+      createConfigRow('Min Sessions', config.scoreMinVisits));
+  configTableBody.appendChild(
+      createConfigRow('Lower Threshold', config.highScoreLowerThreshold));
+  configTableBody.appendChild(
+      createConfigRow('Upper Threshold', config.highScoreUpperThreshold));
+
+  configTableBody.appendChild(createConfigRow(
+      'Record MEI data', formatFeatureFlag(config.featureRecordData)));
+  configTableBody.appendChild(createConfigRow(
+      'Bypass autoplay based on MEI',
+      formatFeatureFlag(config.featureBypassAutoplay)));
+  configTableBody.appendChild(createConfigRow(
+      'Preload MEI data', formatFeatureFlag(config.featurePreloadData)));
+  configTableBody.appendChild(createConfigRow(
+      'MEI for HTTPS only', formatFeatureFlag(config.featureHttpsOnly)));
+  configTableBody.appendChild(createConfigRow(
+      'Autoplay disable settings',
+      formatFeatureFlag(config.featureAutoplayDisableSettings)));
+  configTableBody.appendChild(createConfigRow(
+      'Unified autoplay (preference)',
+      formatFeatureFlag(config.prefDisableUnifiedAutoplay)));
+  configTableBody.appendChild(createConfigRow(
+      'Custom autoplay policy',
+      formatFeatureFlag(config.hasCustomAutoplayPolicy)));
+  configTableBody.appendChild(
+      createConfigRow('Autoplay Policy', config.autoplayPolicy));
+  configTableBody.appendChild(createConfigRow(
+      'Preload version',
+      config.preloadVersion ? config.preloadVersion : 'Not Available'));
+}
+
+/**
+ * Converts a boolean into a string value.
+ */
+function formatFeatureFlag(value: boolean): string {
+  return value ? 'Enabled' : 'Disabled';
+}
+
+/**
+ * Regenerates the engagement table from |info|.
+ */
+function renderTable() {
+  clearTable();
+  sortInfo();
+  assert(info);
+  assert(engagementTableBody);
+  info.filter(rowInfo => (showNoPlaybacks || rowInfo.mediaPlaybacks > 0))
+      .forEach(rowInfo => engagementTableBody!.appendChild(createRow(rowInfo)));
+}
+
+/**
+ * Retrieve media engagement info and render the engagement table.
+ */
+function updateEngagementTable() {
+  assert(detailsProvider);
+  // Populate engagement table.
+  detailsProvider.getMediaEngagementScoreDetails().then(response => {
+    info = response.info;
+    renderTable();
+    pageIsPopulatedResolver.resolve();
+  });
+
+  // Populate config settings.
+  detailsProvider.getMediaEngagementConfig().then(response => {
+    renderConfigTable(response.config);
+  });
+}
+
+document.addEventListener('DOMContentLoaded', function() {
+  detailsProvider = MediaEngagementScoreDetailsProvider.getRemote();
+  updateEngagementTable();
+
+  engagementTableBody =
+      document.querySelector<HTMLElement>('#engagement-table-body');
+  configTableBody = document.querySelector<HTMLElement>('#config-table-body');
+
+  // Set table header sort handlers.
+  const engagementTableHeader =
+      document.querySelector<HTMLElement>('#engagement-table-header');
+  assert(engagementTableHeader);
+  const headers = engagementTableHeader.children;
+  for (let i = 0; i < headers.length; i++) {
+    headers[i]!.addEventListener('click', (e) => {
+      const target = e.target as HTMLElement;
+      const newSortKey = target.getAttribute('sort-key');
+      if (sortKey === newSortKey) {
+        sortReverse = !sortReverse;
+      } else {
+        assert(newSortKey);
+        sortKey = newSortKey;
+        sortReverse = false;
+      }
+      const oldSortColumn = document.querySelector<HTMLElement>('.sort-column');
+      assert(oldSortColumn);
+      oldSortColumn.classList.remove('sort-column');
+      target.classList.add('sort-column');
+      if (sortReverse) {
+        target.setAttribute('sort-reverse', '');
+      } else {
+        target.removeAttribute('sort-reverse');
+      }
+      renderTable();
+    });
+  }
+
+  // Add handler to 'copy all to clipboard' button
+  const copyAllToClipboardButton =
+      document.querySelector<HTMLElement>('#copy-all-to-clipboard');
+  assert(copyAllToClipboardButton);
+  copyAllToClipboardButton.addEventListener('click', () => {
+    // Make sure nothing is selected
+    window.getSelection()!.removeAllRanges();
+
+    document.execCommand('selectAll');
+    document.execCommand('copy');
+
+    // And deselect everything at the end.
+    window.getSelection()!.removeAllRanges();
+  });
+
+  // Add handler to 'show no playbacks' checkbox
+  const showNoPlaybacksCheckbox =
+      document.querySelector<HTMLElement>('#show-no-playbacks');
+  assert(showNoPlaybacksCheckbox);
+  showNoPlaybacksCheckbox.addEventListener('change', (e) => {
+    showNoPlaybacks = (e.target as HTMLInputElement).checked;
+    renderTable();
+  });
+});
diff --git a/chrome/browser/resources/media/media_history.ts b/chrome/browser/resources/media/media_history.ts
index 019cc3d..31e9ba8 100644
--- a/chrome/browser/resources/media/media_history.ts
+++ b/chrome/browser/resources/media/media_history.ts
@@ -14,9 +14,9 @@
 // Allow a function to be provided by tests, which will be called when
 // the page has been populated.
 const mediaHistoryPageIsPopulatedResolver = new PromiseResolver<void>();
-const whenPageIsPopulatedForTest = function() {
+function whenPageIsPopulatedForTest(): Promise<void> {
   return mediaHistoryPageIsPopulatedResolver.promise;
-};
+}
 Object.assign(window, {whenPageIsPopulatedForTest});
 
 let store: MediaHistoryStoreRemote|null = null;
diff --git a/chrome/browser/resources/media/webrtc_logs.js b/chrome/browser/resources/media/webrtc_logs.ts
similarity index 72%
rename from chrome/browser/resources/media/webrtc_logs.js
rename to chrome/browser/resources/media/webrtc_logs.ts
index 9b2cac7..cd42088e 100644
--- a/chrome/browser/resources/media/webrtc_logs.js
+++ b/chrome/browser/resources/media/webrtc_logs.ts
@@ -3,9 +3,16 @@
 // found in the LICENSE file.
 
 import './strings.m.js';
+
+import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {$, appendParam} from 'chrome://resources/js/util.m.js';
+import {appendParam} from 'chrome://resources/js/util.m.js';
+
+
+type EventLogEntry = {
+  [key: string]: number|string,
+};
 
 /**
  * Requests the list of WebRTC logs from the backend.
@@ -16,18 +23,25 @@
 
 /**
  * Callback from backend with the list of WebRTC logs. Builds the UI.
- * @param {!{textLogs: !Array, eventLogs: !Array, version: string}} results
  */
-function updateWebRtcLogsList({textLogs, eventLogs, version}) {
-  updateWebRtcTextLogsList(textLogs, version);
-  updateWebRtcEventLogsList(eventLogs);
+function updateWebRtcLogsList(results: {
+  textLogs: EventLogEntry[],
+  eventLogs: EventLogEntry[],
+  version: string,
+}) {
+  updateWebRtcTextLogsList(results.textLogs, results.version);
+  updateWebRtcEventLogsList(results.eventLogs);
 }
 
-function updateWebRtcTextLogsList(textLogsList, version) {
-  $('text-log-banner').textContent =
+function updateWebRtcTextLogsList(
+    textLogsList: EventLogEntry[], version: string) {
+  const banner = document.querySelector<HTMLElement>('#text-log-banner');
+  assert(banner);
+  banner.textContent =
       loadTimeData.getStringF('webrtcTextLogCountFormat', textLogsList.length);
 
-  const textLogSection = $('text-log-list');
+  const textLogSection = document.querySelector<HTMLElement>('#text-log-list');
+  assert(textLogSection);
 
   // Clear any previous list.
   textLogSection.textContent = '';
@@ -43,21 +57,23 @@
     logBlock.appendChild(title);
 
     const localFileLine = document.createElement('p');
-    if (textLog['local_file'].length === 0) {
+    const localFile = textLog['local_file'] as string;
+    if (localFile.length === 0) {
       localFileLine.textContent =
           loadTimeData.getString('noLocalLogFileMessage');
     } else {
       localFileLine.textContent =
           loadTimeData.getString('webrtcLogLocalFileLabelFormat') + ' ';
       const localFileLink = document.createElement('a');
-      localFileLink.href = 'file://' + textLog['local_file'];
-      localFileLink.textContent = textLog['local_file'];
+      localFileLink.href = 'file://' + localFile;
+      localFileLink.textContent = localFile;
       localFileLine.appendChild(localFileLink);
     }
     logBlock.appendChild(localFileLine);
 
     const uploadLine = document.createElement('p');
-    if (textLog['id'].length === 0) {
+    const id = textLog['id'] as string;
+    if (id.length === 0) {
       uploadLine.textContent =
           loadTimeData.getString('webrtcLogNotUploadedMessage');
     } else {
@@ -79,7 +95,7 @@
         '', '1.', '2.', '3.', '',
         '*Please note that issues filed with no information filled in ' +
             'above will be marked as WontFix*',
-        '', '****DO NOT CHANGE BELOW THIS LINE****', 'report_id:' + textLog.id
+        '', '****DO NOT CHANGE BELOW THIS LINE****', 'report_id:' + id
       ];
       const params = {
         template: 'Defect report from user',
@@ -87,7 +103,8 @@
       };
       let href = 'http://code.google.com/p/chromium/issues/entry';
       for (const param in params) {
-        href = appendParam(href, param, params[param]);
+        href = appendParam(
+            href, param, (params as {[key: string]: string})[param]);
       }
       link.href = href;
       link.target = '_blank';
@@ -99,11 +116,15 @@
     textLogSection.appendChild(logBlock);
   }
 
-  $('text-no-logs').hidden = (textLogsList.length !== 0);
+  const noLogs = document.querySelector<HTMLElement>('#text-no-logs');
+  assert(noLogs);
+  noLogs.hidden = (textLogsList.length !== 0);
 }
 
-function updateWebRtcEventLogsList(eventLogsList) {
-  const eventLogSection = $('event-log-list');
+function updateWebRtcEventLogsList(eventLogsList: EventLogEntry[]) {
+  const eventLogSection =
+      document.querySelector<HTMLElement>('#event-log-list');
+  assert(eventLogSection);
 
   eventLogSection.textContent = '';  // Clear any previous list.
 
@@ -117,19 +138,24 @@
     }
   }
 
-  $('event-log-banner').textContent =
+  const banner = document.querySelector<HTMLElement>('#event-log-banner');
+  assert(banner);
+  banner.textContent =
       loadTimeData.getStringF('webrtcEventLogCountFormat', entries);
 
-  $('event-no-logs').hidden = (entries !== 0);
+  const noLogs = document.querySelector<HTMLElement>('#event-no-logs');
+  assert(noLogs);
+  noLogs.hidden = (entries !== 0);
 }
 
-function createEventLogEntryElement(eventLogEntry) {
+function createEventLogEntryElement(eventLogEntry: EventLogEntry): HTMLElement|
+    null {
   // See LogHistory in webrtc_event_log_manager_remote.cc for an explanation
   // of the various states.
   const state = eventLogEntry['state'];
   if (!state) {
     console.error('Unknown state.');
-    return;
+    return null;
   } else if (state === 'pending' || state === 'actively_uploaded') {
     return createPendingOrActivelyUploadedEventLogEntryElement(eventLogEntry);
   } else if (state === 'not_uploaded') {
@@ -139,14 +165,15 @@
   } else if (state === 'upload_successful') {
     return createUploadSuccessfulEventLogEntryElement(eventLogEntry);
   } else {
-    console.error('Unrecognized state.');
+    assertNotReached();
   }
 }
 
-function createPendingOrActivelyUploadedEventLogEntryElement(eventLogEntry) {
+function createPendingOrActivelyUploadedEventLogEntryElement(
+    eventLogEntry: EventLogEntry): HTMLElement|null {
   const expectedFields = ['capture_time', 'local_file'];
   if (!verifyExpectedFields(eventLogEntry, expectedFields)) {
-    return;
+    return null;
   }
 
   const logBlock = document.createElement('div');
@@ -166,10 +193,11 @@
   return logBlock;
 }
 
-function createNotUploadedEventLogEntryElement(eventLogEntry) {
+function createNotUploadedEventLogEntryElement(eventLogEntry: EventLogEntry):
+    HTMLElement|null {
   const expectedFields = ['capture_time', 'local_id'];
   if (!verifyExpectedFields(eventLogEntry, expectedFields)) {
-    return;
+    return null;
   }
 
   const logBlock = document.createElement('div');
@@ -185,10 +213,11 @@
   return logBlock;
 }
 
-function createUploadUnsuccessfulEventLogEntryElement(eventLogEntry) {
+function createUploadUnsuccessfulEventLogEntryElement(
+    eventLogEntry: EventLogEntry): HTMLElement|null {
   const expectedFields = ['capture_time', 'local_id', 'upload_time'];
   if (!verifyExpectedFields(eventLogEntry, expectedFields)) {
-    return;
+    return null;
   }
 
   const logBlock = document.createElement('div');
@@ -204,11 +233,12 @@
   return logBlock;
 }
 
-function createUploadSuccessfulEventLogEntryElement(eventLogEntry) {
+function createUploadSuccessfulEventLogEntryElement(
+    eventLogEntry: EventLogEntry): HTMLElement|null {
   const expectedFields =
       ['capture_time', 'local_id', 'upload_id', 'upload_time'];
   if (!verifyExpectedFields(eventLogEntry, expectedFields)) {
-    return;
+    return null;
   }
 
   const logBlock = document.createElement('div');
@@ -229,7 +259,8 @@
   return logBlock;
 }
 
-function verifyExpectedFields(entry, expectedFields) {
+function verifyExpectedFields(
+    entry: {[key: string]: string|number}, expectedFields: string[]): boolean {
   for (const fieldIdx in expectedFields) {
     const field = expectedFields[fieldIdx];
     if (!entry[field]) {
@@ -240,26 +271,28 @@
   return true;
 }
 
-function appendCaptureTime(logBlock, eventLogEntry) {
+function appendCaptureTime(
+    logBlock: HTMLElement, eventLogEntry: EventLogEntry) {
   const title = document.createElement('h3');
   title.textContent = loadTimeData.getStringF(
       'webrtcLogHeaderFormat', eventLogEntry['capture_time']);
   logBlock.appendChild(title);
 }
 
-function appendLocalFile(logBlock, eventLogEntry) {
+function appendLocalFile(logBlock: HTMLElement, eventLogEntry: EventLogEntry) {
   // Local file on disk, if still on disk.
   const localFileLine = document.createElement('p');
   localFileLine.textContent =
       loadTimeData.getString('webrtcLogLocalFileLabelFormat') + ' ';
   const localFileLink = document.createElement('a');
-  localFileLink.href = 'file://' + eventLogEntry['local_file'];
-  localFileLink.textContent = eventLogEntry['local_file'];
+  const fileName = eventLogEntry['local_file'] as string;
+  localFileLink.href = 'file://' + fileName;
+  localFileLink.textContent = fileName;
   localFileLine.appendChild(localFileLink);
   logBlock.appendChild(localFileLine);
 }
 
-function appendLocalLogId(logBlock, eventLogEntry) {
+function appendLocalLogId(logBlock: HTMLElement, eventLogEntry: EventLogEntry) {
   const localIdLine = document.createElement('p');
   localIdLine.textContent =
       loadTimeData.getStringF(
diff --git a/chrome/browser/resources/profile_internals/profile_internals_app.html b/chrome/browser/resources/profile_internals/profile_internals_app.html
index cdb2b7c..ccd320f3 100644
--- a/chrome/browser/resources/profile_internals/profile_internals_app.html
+++ b/chrome/browser/resources/profile_internals/profile_internals_app.html
@@ -1,2 +1,38 @@
-<h1>Profile Internals</h1>
-<div id="example-div">[[message_]]</div>
\ No newline at end of file
+<h2>Profiles</h2>\
+<template is="dom-repeat" items="[[profilesList_]]">
+    <h3>[[item.localProfileName]]</h3>
+    <table class="profile">
+        <tr>
+            <td>Profile Path</td>
+            <td>[[item.profilePath]]</td>
+        </tr>
+        <tr>
+            <td>Local Profile Name</td>
+            <td>[[item.localProfileName]]</td>
+        </tr>
+        <tr>
+            <td>Signin State</td>
+            <td>[[item.signinState]]</td>
+        </tr>
+        <tr>
+            <td>Signin Required</td>
+            <td>[[item.signinRequired]]</td>
+        </tr>
+        <tr>
+            <td>Gaia Name</td>
+            <td>[[item.gaiaName]]</td>
+        </tr>
+        <tr>
+            <td>Gaia Id</td>
+            <td>[[item.gaiaId]]</td>
+        </tr>
+        <tr>
+            <td>User Name</td>
+            <td>[[item.userName]]</td>
+        </tr>
+        <tr>
+            <td>Hosted Domain</td>
+            <td>[[item.hostedDomain]]</td>
+        </tr>
+    </table>
+</template>
diff --git a/chrome/browser/resources/profile_internals/profile_internals_app.ts b/chrome/browser/resources/profile_internals/profile_internals_app.ts
index 94a22a34..e8154bb 100644
--- a/chrome/browser/resources/profile_internals/profile_internals_app.ts
+++ b/chrome/browser/resources/profile_internals/profile_internals_app.ts
@@ -8,7 +8,7 @@
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './profile_internals_app.html.js';
-import {ProfileInternalsBrowserProxy, ProfileInternalsBrowserProxyImpl} from './profile_internals_browser_proxy.js';
+import {ProfileInternalsBrowserProxy, ProfileInternalsBrowserProxyImpl, ProfileState} from './profile_internals_browser_proxy.js';
 
 const ProfileInternalsAppElementBase = WebUIListenerMixin(PolymerElement);
 
@@ -23,30 +23,31 @@
 
   static get properties() {
     return {
-      message_: {
-        type: String,
-        value: '',
-      },
+      /**
+       * Profiles list supplied by ProfileInternalsBrowserProxy.
+       */
+      profilesList_: {type: Array, value: () => []},
     };
   }
 
   private profileInternalsBrowserProxy_: ProfileInternalsBrowserProxy =
       ProfileInternalsBrowserProxyImpl.getInstance();
-  private message_: string;
+  private profilesList_: Array<ProfileState>;
 
   override connectedCallback() {
     super.connectedCallback();
     this.addWebUIListener(
-        'profiles-changed',
-        (message: string) => this.handleProfilesChanged_(message));
+        'profiles-list-changed',
+        (profilesList: Array<ProfileState>) =>
+            this.handleProfilesListChanged_(profilesList));
     this.profileInternalsBrowserProxy_.getProfilesList();
   }
 
   /**
    * Handler for when the profiles list are updated.
    */
-  private handleProfilesChanged_(message: string) {
-    this.message_ = message;
+  private handleProfilesListChanged_(profilesList: Array<ProfileState>) {
+    this.profilesList_ = profilesList;
   }
 }
 
diff --git a/chrome/browser/resources/profile_internals/profile_internals_browser_proxy.ts b/chrome/browser/resources/profile_internals/profile_internals_browser_proxy.ts
index e6f17d4..bf0ee5d4 100644
--- a/chrome/browser/resources/profile_internals/profile_internals_browser_proxy.ts
+++ b/chrome/browser/resources/profile_internals/profile_internals_browser_proxy.ts
@@ -2,11 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+export type ProfileState = {
+  profilePath: string,
+  localProfileName: string,
+  signinState: string,
+  signinRequired: boolean,
+  gaiaName: string,
+  gaiaId: string,
+  userName: string,
+  hostedDomain: string,
+};
+
 /**
  * @fileoverview A helper object used by the profile internals debug page
  * to interact with the browser.
  */
-
 export interface ProfileInternalsBrowserProxy {
   getProfilesList(): void;
 }
diff --git a/chrome/browser/resources/settings/chromeos/device_page/device_page.js b/chrome/browser/resources/settings/chromeos/device_page/device_page.js
index 77ed27e3..370cb16 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/device_page.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/device_page.js
@@ -19,128 +19,152 @@
 import '../../settings_page/settings_subpage.js';
 import '../../settings_shared_css.js';
 
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Route, Router} from '../../router.js';
+import {Router} from '../../router.js';
 import {routes} from '../os_route.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl} from './device_page_browser_proxy.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-device-page',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ */
+const SettingsDevicePageElementBase = mixinBehaviors(
+    [I18nBehavior, WebUIListenerBehavior, RouteObserverBehavior],
+    PolymerElement);
 
-  behaviors: [
-    I18nBehavior,
-    WebUIListenerBehavior,
-    RouteObserverBehavior,
-  ],
+/** @polymer */
+class SettingsDevicePageElement extends SettingsDevicePageElementBase {
+  static get is() {
+    return 'settings-device-page';
+  }
 
-  properties: {
-    prefs: {
-      type: Object,
-      notify: true,
-    },
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    showCrostini: Boolean,
-
-    /**
-     * |hasMouse_|, |hasPointingStick_|, and |hasTouchpad_| start undefined so
-     * observers don't trigger until they have been populated.
-     * @private
-     */
-    hasMouse_: Boolean,
-
-    /**
-     * Whether a pointing stick (such as a TrackPoint) is connected.
-     * @private
-     */
-    hasPointingStick_: Boolean,
-
-    /** @private */
-    hasTouchpad_: Boolean,
-
-    /**
-     * Whether the device has a haptic touchpad. If this is true, |hasTouchpad_|
-     * will also be true.
-     * @private
-     */
-    hasHapticTouchpad_: Boolean,
-
-    /**
-     * |hasStylus_| is initialized to false so that dom-if behaves correctly.
-     * @private
-     */
-    hasStylus_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /**
-     * Whether storage management info should be hidden.
-     * @private
-     */
-    hideStorageInfo_: {
-      type: Boolean,
-      value() {
-        // TODO(crbug.com/868747): Show an explanatory message instead.
-        return loadTimeData.valueExists('isDemoSession') &&
-            loadTimeData.getBoolean('isDemoSession');
+  static get properties() {
+    return {
+      prefs: {
+        type: Object,
+        notify: true,
       },
-      readOnly: true,
-    },
 
-    /** @private {!Map<string, string>} */
-    focusConfig_: {
-      type: Object,
-      value() {
-        const map = new Map();
-        if (routes.POINTERS) {
-          map.set(routes.POINTERS.path, '#pointersRow');
-        }
-        if (routes.KEYBOARD) {
-          map.set(routes.KEYBOARD.path, '#keyboardRow');
-        }
-        if (routes.STYLUS) {
-          map.set(routes.STYLUS.path, '#stylusRow');
-        }
-        if (routes.DISPLAY) {
-          map.set(routes.DISPLAY.path, '#displayRow');
-        }
-        if (routes.STORAGE) {
-          map.set(routes.STORAGE.path, '#storageRow');
-        }
-        if (routes.EXTERNAL_STORAGE_PREFERENCES) {
-          map.set(
-              routes.EXTERNAL_STORAGE_PREFERENCES.path,
-              '#externalStoragePreferencesRow');
-        }
-        if (routes.POWER) {
-          map.set(routes.POWER.path, '#powerRow');
-        }
-        return map;
+      showCrostini: Boolean,
+
+      /**
+       * |hasMouse_|, |hasPointingStick_|, and |hasTouchpad_| start undefined so
+       * observers don't trigger until they have been populated.
+       * @private
+       */
+      hasMouse_: Boolean,
+
+      /**
+       * Whether a pointing stick (such as a TrackPoint) is connected.
+       * @private
+       */
+      hasPointingStick_: Boolean,
+
+      /** @private */
+      hasTouchpad_: Boolean,
+
+      /**
+       * Whether the device has a haptic touchpad. If this is true,
+       * |hasTouchpad_| will also be true.
+       * @private
+       */
+      hasHapticTouchpad_: Boolean,
+
+      /**
+       * |hasStylus_| is initialized to false so that dom-if behaves correctly.
+       * @private
+       */
+      hasStylus_: {
+        type: Boolean,
+        value: false,
       },
-    },
 
-    /** @private */
-    androidEnabled_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('androidEnabled');
+      /**
+       * Whether storage management info should be hidden.
+       * @private
+       */
+      hideStorageInfo_: {
+        type: Boolean,
+        value() {
+          // TODO(crbug.com/868747): Show an explanatory message instead.
+          return loadTimeData.valueExists('isDemoSession') &&
+              loadTimeData.getBoolean('isDemoSession');
+        },
+        readOnly: true,
       },
-    },
-  },
 
-  observers: [
-    'pointersChanged_(hasMouse_, hasPointingStick_, hasTouchpad_)',
-  ],
+      /** @private {!Map<string, string>} */
+      focusConfig_: {
+        type: Object,
+        value() {
+          const map = new Map();
+          if (routes.POINTERS) {
+            map.set(routes.POINTERS.path, '#pointersRow');
+          }
+          if (routes.KEYBOARD) {
+            map.set(routes.KEYBOARD.path, '#keyboardRow');
+          }
+          if (routes.STYLUS) {
+            map.set(routes.STYLUS.path, '#stylusRow');
+          }
+          if (routes.DISPLAY) {
+            map.set(routes.DISPLAY.path, '#displayRow');
+          }
+          if (routes.STORAGE) {
+            map.set(routes.STORAGE.path, '#storageRow');
+          }
+          if (routes.EXTERNAL_STORAGE_PREFERENCES) {
+            map.set(
+                routes.EXTERNAL_STORAGE_PREFERENCES.path,
+                '#externalStoragePreferencesRow');
+          }
+          if (routes.POWER) {
+            map.set(routes.POWER.path, '#powerRow');
+          }
+          return map;
+        },
+      },
+
+      /** @private */
+      androidEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('androidEnabled');
+        },
+      },
+    };
+  }
+
+  static get observers() {
+    return [
+      'pointersChanged_(hasMouse_, hasPointingStick_, hasTouchpad_)',
+    ];
+  }
+
+  constructor() {
+    super();
+
+    /** @private {!DevicePageBrowserProxy} */
+    this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.addWebUIListener(
         'has-mouse-changed', this.set.bind(this, 'hasMouse_'));
     this.addWebUIListener(
@@ -150,17 +174,17 @@
     this.addWebUIListener(
         'has-haptic-touchpad-changed',
         this.set.bind(this, 'hasHapticTouchpad_'));
-    DevicePageBrowserProxyImpl.getInstance().initializePointers();
+    this.browserProxy_.initializePointers();
 
     this.addWebUIListener(
         'has-stylus-changed', this.set.bind(this, 'hasStylus_'));
-    DevicePageBrowserProxyImpl.getInstance().initializeStylus();
+    this.browserProxy_.initializeStylus();
 
     this.addWebUIListener(
         'storage-android-enabled-changed',
         this.set.bind(this, 'androidEnabled_'));
-    DevicePageBrowserProxyImpl.getInstance().updateAndroidEnabled();
-  },
+    this.browserProxy_.updateAndroidEnabled();
+  }
 
   /**
    * @return {string}
@@ -180,7 +204,7 @@
       return this.i18n('touchpadTitle');
     }
     return '';
-  },
+  }
 
   /**
    * Handler for tapping the mouse and touchpad settings menu item.
@@ -188,7 +212,7 @@
    */
   onPointersTap_() {
     Router.getInstance().navigateTo(routes.POINTERS);
-  },
+  }
 
   /**
    * Handler for tapping the Keyboard settings menu item.
@@ -196,7 +220,7 @@
    */
   onKeyboardTap_() {
     Router.getInstance().navigateTo(routes.KEYBOARD);
-  },
+  }
 
   /**
    * Handler for tapping the Stylus settings menu item.
@@ -204,7 +228,7 @@
    */
   onStylusTap_() {
     Router.getInstance().navigateTo(routes.STYLUS);
-  },
+  }
 
   /**
    * Handler for tapping the Display settings menu item.
@@ -212,7 +236,7 @@
    */
   onDisplayTap_() {
     Router.getInstance().navigateTo(routes.DISPLAY);
-  },
+  }
 
   /**
    * Handler for tapping the Storage settings menu item.
@@ -220,7 +244,7 @@
    */
   onStorageTap_() {
     Router.getInstance().navigateTo(routes.STORAGE);
-  },
+  }
 
   /**
    * Handler for tapping the Power settings menu item.
@@ -228,12 +252,12 @@
    */
   onPowerTap_() {
     Router.getInstance().navigateTo(routes.POWER);
-  },
+  }
 
   /** @protected */
   currentRouteChanged() {
     this.checkPointerSubpage_();
-  },
+  }
 
   /**
    * @param {boolean} hasMouse
@@ -244,7 +268,7 @@
   pointersChanged_(hasMouse, hasPointingStick, hasTouchpad) {
     this.$.pointersRow.hidden = !hasMouse && !hasPointingStick && !hasTouchpad;
     this.checkPointerSubpage_();
-  },
+  }
 
   /**
    * Leaves the pointer subpage if all pointing devices are detached.
@@ -257,5 +281,7 @@
         Router.getInstance().getCurrentRoute() === routes.POINTERS) {
       Router.getInstance().navigateTo(routes.DEVICE);
     }
-  },
-});
+  }
+}
+
+customElements.define(SettingsDevicePageElement.is, SettingsDevicePageElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/device_page_browser_proxy.js b/chrome/browser/resources/settings/chromeos/device_page/device_page_browser_proxy.js
index 6ae96c6..dbcbccdf 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/device_page_browser_proxy.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/device_page_browser_proxy.js
@@ -2,16 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// clang-format off
-import { addSingletonGetter, addWebUIListener,WebUIListener} from 'chrome://resources/js/cr.m.js';
-// clang-format on
+import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
 
-  /**
-   * Enumeration for device state about remaining space.
-   * These values must be kept in sync with
-   * StorageManagerHandler::StorageSpaceState in C++ code.
-   * @enum {number}
-   */
+/**
+ * Enumeration for device state about remaining space.
+ * These values must be kept in sync with
+ * StorageManagerHandler::StorageSpaceState in C++ code.
+ * @enum {number}
+ */
 export const StorageSpaceState = {
   NORMAL: 0,
   LOW: 1,
@@ -31,13 +29,13 @@
   return systemDisplayApi;
 }
 
-  /**
-   * @typedef {{
-   *   id: string,
-   *   is_dedicated_charger: boolean,
-   *   description: string
-   * }}
-   */
+/**
+ * @typedef {{
+ *   id: string,
+ *   is_dedicated_charger: boolean,
+ *   description: string
+ * }}
+ */
 export let PowerSource;
 
 /**
@@ -356,6 +354,17 @@
   openMyFiles() {
     chrome.send('openMyFiles');
   }
+
+  /** @return {!DevicePageBrowserProxy} */
+  static getInstance() {
+    return instance || (instance = new DevicePageBrowserProxyImpl());
+  }
+
+  /** @param {!DevicePageBrowserProxy} obj */
+  static setInstance(obj) {
+    instance = obj;
+  }
 }
 
-addSingletonGetter(DevicePageBrowserProxyImpl);
+/** @type {?DevicePageBrowserProxy} */
+let instance = null;
diff --git a/chrome/browser/resources/settings/chromeos/device_page/display.js b/chrome/browser/resources/settings/chromeos/device_page/display.js
index 6a090c2..e984ffb 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/display.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/display.js
@@ -6,6 +6,7 @@
  * @fileoverview
  * 'settings-display' is the settings subpage for display settings.
  */
+
 import '//resources/cr_elements/cr_checkbox/cr_checkbox.m.js';
 import '//resources/cr_elements/cr_link_row/cr_link_row.js';
 import '//resources/cr_elements/cr_tabs/cr_tabs.js';
@@ -22,19 +23,19 @@
 import '../../controls/settings_dropdown_menu.js';
 import '//resources/cr_elements/cr_slider/cr_slider.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
+import {assert} from '//resources/js/assert.m.js';
 import {focusWithoutInk} from '//resources/js/cr/ui/focus_without_ink.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {flush, html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Route, Router} from '../../router.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
+import {Route} from '../../router.js';
+import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
 import {routes} from '../os_route.js';
-import {PrefsBehavior} from '../prefs_behavior.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
+import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, getDisplayApi} from './device_page_browser_proxy.js';
 
 /**
  * @typedef {{
@@ -61,298 +62,319 @@
   CUSTOM: 2,
 };
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-display',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {I18nBehaviorInterface}
+ * @implements {PrefsBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ */
+const SettingsDisplayElementBase = mixinBehaviors(
+    [DeepLinkingBehavior, I18nBehavior, PrefsBehavior, RouteObserverBehavior],
+    PolymerElement);
 
-  behaviors: [
-    DeepLinkingBehavior,
-    I18nBehavior,
-    PrefsBehavior,
-    RouteObserverBehavior,
-  ],
+/** @polymer */
+class SettingsDisplayElement extends SettingsDisplayElementBase {
+  static get is() {
+    return 'settings-display';
+  }
 
-  properties: {
-    /**
-     * @type {!chrome.settingsPrivate.PrefObject}
-     * @private
-     */
-    selectedModePref_: {
-      type: Object,
-      value() {
-        return {
-          key: 'fakeDisplaySliderPref',
-          type: chrome.settingsPrivate.PrefType.NUMBER,
-          value: 0,
-        };
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * @type {!chrome.settingsPrivate.PrefObject}
+       * @private
+       */
+      selectedModePref_: {
+        type: Object,
+        value() {
+          return {
+            key: 'fakeDisplaySliderPref',
+            type: chrome.settingsPrivate.PrefType.NUMBER,
+            value: 0,
+          };
+        },
       },
-    },
 
-    /**
-     * @type {!chrome.settingsPrivate.PrefObject}
-     * @private
-     */
-    selectedZoomPref_: {
-      type: Object,
-      value() {
-        return {
-          key: 'fakeDisplaySliderZoomPref',
-          type: chrome.settingsPrivate.PrefType.NUMBER,
-          value: 0,
-        };
+      /**
+       * @type {!chrome.settingsPrivate.PrefObject}
+       * @private
+       */
+      selectedZoomPref_: {
+        type: Object,
+        value() {
+          return {
+            key: 'fakeDisplaySliderZoomPref',
+            type: chrome.settingsPrivate.PrefType.NUMBER,
+            value: 0,
+          };
+        },
       },
-    },
 
-    /**
-     * Array of displays.
-     * @type {!Array<!chrome.system.display.DisplayUnitInfo>}
-     */
-    displays: Array,
+      /**
+       * Array of displays.
+       * @type {!Array<!chrome.system.display.DisplayUnitInfo>}
+       */
+      displays: Array,
 
-    /**
-     * Array of display layouts.
-     * @type {!Array<!chrome.system.display.DisplayLayout>}
-     */
-    layouts: Array,
+      /**
+       * Array of display layouts.
+       * @type {!Array<!chrome.system.display.DisplayLayout>}
+       */
+      layouts: Array,
 
-    /**
-     * String listing the ids in displays. Used to observe changes to the
-     * display configuration (i.e. when a display is added or removed).
-     */
-    displayIds: {type: String, observer: 'onDisplayIdsChanged_'},
+      /**
+       * String listing the ids in displays. Used to observe changes to the
+       * display configuration (i.e. when a display is added or removed).
+       */
+      displayIds: {type: String, observer: 'onDisplayIdsChanged_'},
 
-    /** Primary display id */
-    primaryDisplayId: String,
+      /** Primary display id */
+      primaryDisplayId: String,
 
-    /** @type {!chrome.system.display.DisplayUnitInfo|undefined} */
-    selectedDisplay: Object,
+      /** @type {!chrome.system.display.DisplayUnitInfo|undefined} */
+      selectedDisplay: Object,
 
-    /** Id passed to the overscan dialog. */
-    overscanDisplayId: {
-      type: String,
-      notify: true,
-    },
-
-    /** Ids for mirroring destination displays. */
-    mirroringDestinationIds: Array,
-
-    /** @private {!Array<number>} Mode index values for slider. */
-    modeValues_: Array,
-
-    /**
-     * @private {!Array<SliderTick>} Display zoom slider tick
-     *     values.
-     */
-    zoomValues_: Array,
-
-    /** @private {!DropdownMenuOptionList} */
-    displayModeList_: {
-      type: Array,
-      value: [],
-    },
-
-    /** @private {!DropdownMenuOptionList} */
-    refreshRateList_: {
-      type: Array,
-      value: [],
-    },
-
-    /** @private */
-    unifiedDesktopAvailable_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('unifiedDesktopAvailable');
-      }
-    },
-
-    /** @private */
-    ambientColorAvailable_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('deviceSupportsAmbientColor');
-      }
-    },
-
-    /** @private */
-    listAllDisplayModes_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('listAllDisplayModes');
-      }
-    },
-
-    /** @private */
-    unifiedDesktopMode_: {
-      type: Boolean,
-      value: false,
-    },
-
-    /**
-     * @type {!chrome.settingsPrivate.PrefObject}
-     * @private
-     */
-    selectedParentModePref_: {
-      type: Object,
-      value: function() {
-        return {
-          key: 'fakeDisplayParentModePref',
-          type: chrome.settingsPrivate.PrefType.NUMBER,
-          value: 0,
-        };
+      /** Id passed to the overscan dialog. */
+      overscanDisplayId: {
+        type: String,
+        notify: true,
       },
-    },
 
-    /** @private */
-    scheduleTypesList_: {
-      type: Array,
-      value() {
-        return [
-          {
-            name: loadTimeData.getString('displayNightLightScheduleNever'),
-            value: NightLightScheduleType.NEVER
-          },
-          {
-            name: loadTimeData.getString(
-                'displayNightLightScheduleSunsetToSunRise'),
-            value: NightLightScheduleType.SUNSET_TO_SUNRISE
-          },
-          {
-            name: loadTimeData.getString('displayNightLightScheduleCustom'),
-            value: NightLightScheduleType.CUSTOM
-          }
-        ];
+      /** Ids for mirroring destination displays. */
+      mirroringDestinationIds: Array,
+
+      /** @private {!Array<number>} Mode index values for slider. */
+      modeValues_: Array,
+
+      /**
+       * @private {!Array<SliderTick>} Display zoom slider tick
+       *     values.
+       */
+      zoomValues_: Array,
+
+      /** @private {!DropdownMenuOptionList} */
+      displayModeList_: {
+        type: Array,
+        value: [],
       },
-    },
 
-    /** @private */
-    shouldOpenCustomScheduleCollapse_: {
-      type: Boolean,
-      value: false,
-    },
+      /** @private {!DropdownMenuOptionList} */
+      refreshRateList_: {
+        type: Array,
+        value: [],
+      },
 
-    /** @private */
-    nightLightScheduleSubLabel_: String,
+      /** @private */
+      unifiedDesktopAvailable_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('unifiedDesktopAvailable');
+        }
+      },
 
-    /** @private */
-    logicalResolutionText_: String,
+      /** @private */
+      ambientColorAvailable_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('deviceSupportsAmbientColor');
+        }
+      },
 
-    /** @private {!Array<string>} */
-    displayTabNames_: Array,
+      /** @private */
+      listAllDisplayModes_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('listAllDisplayModes');
+        }
+      },
 
-    /** @private */
-    selectedTab_: Number,
+      /** @private */
+      unifiedDesktopMode_: {
+        type: Boolean,
+        value: false,
+      },
 
-    /**
-     * Contains the settingId of any deep link that wasn't able to be shown,
-     * null otherwise.
-     * @private {?chromeos.settings.mojom.Setting}
-     */
-    pendingSettingId_: {
-      type: Number,
-      value: null,
-    },
+      /**
+       * @type {!chrome.settingsPrivate.PrefObject}
+       * @private
+       */
+      selectedParentModePref_: {
+        type: Object,
+        value: function() {
+          return {
+            key: 'fakeDisplayParentModePref',
+            type: chrome.settingsPrivate.PrefType.NUMBER,
+            value: 0,
+          };
+        },
+      },
 
-    /**
-     * Used by DeepLinkingBehavior to focus this page's deep links.
-     * @type {!Set<!chromeos.settings.mojom.Setting>}
-     */
-    supportedSettingIds: {
-      type: Object,
-      value: () => new Set([
-        chromeos.settings.mojom.Setting.kDisplaySize,
-        chromeos.settings.mojom.Setting.kNightLight,
-        chromeos.settings.mojom.Setting.kDisplayOrientation,
-        chromeos.settings.mojom.Setting.kDisplayArrangement,
-        chromeos.settings.mojom.Setting.kDisplayResolution,
-        chromeos.settings.mojom.Setting.kDisplayRefreshRate,
-        chromeos.settings.mojom.Setting.kDisplayMirroring,
-        chromeos.settings.mojom.Setting.kAllowWindowsToSpanDisplays,
-        chromeos.settings.mojom.Setting.kAmbientColors,
-        chromeos.settings.mojom.Setting.kTouchscreenCalibration,
-        chromeos.settings.mojom.Setting.kNightLightColorTemperature,
-        chromeos.settings.mojom.Setting.kDisplayOverscan,
-      ]),
-    },
-  },
+      /** @private */
+      scheduleTypesList_: {
+        type: Array,
+        value() {
+          return [
+            {
+              name: loadTimeData.getString('displayNightLightScheduleNever'),
+              value: NightLightScheduleType.NEVER
+            },
+            {
+              name: loadTimeData.getString(
+                  'displayNightLightScheduleSunsetToSunRise'),
+              value: NightLightScheduleType.SUNSET_TO_SUNRISE
+            },
+            {
+              name: loadTimeData.getString('displayNightLightScheduleCustom'),
+              value: NightLightScheduleType.CUSTOM
+            }
+          ];
+        },
+      },
 
-  observers: [
-    'updateNightLightScheduleSettings_(prefs.ash.night_light.schedule_type.*,' +
-        ' prefs.ash.night_light.enabled.*)',
-    'onSelectedModeChange_(selectedModePref_.value)',
-    'onSelectedParentModeChange_(selectedParentModePref_.value)',
-    'onSelectedZoomChange_(selectedZoomPref_.value)',
-    'onDisplaysChanged_(displays.*)',
-  ],
+      /** @private */
+      shouldOpenCustomScheduleCollapse_: {
+        type: Boolean,
+        value: false,
+      },
 
-  /**
-   * This represents the index of the mode with the highest refresh rate at
-   * the current resolution.
-   * @private {number}
-   */
-  currentSelectedParentModeIndex_: -1,
+      /** @private */
+      nightLightScheduleSubLabel_: String,
 
-  /**
-   * This is the index of the currently selected mode.
-   * @private {number} Selected mode index received from chrome.
-   */
-  currentSelectedModeIndex_: -1,
+      /** @private */
+      logicalResolutionText_: String,
 
-  /**
-   * Listener for chrome.system.display.onDisplayChanged events.
-   * @type {function(void)|undefined}
-   * @private
-   */
-  displayChangedListener_: undefined,
+      /** @private {!Array<string>} */
+      displayTabNames_: Array,
 
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
+      /** @private */
+      selectedTab_: Number,
 
-  /** @private {string} */
-  invalidDisplayId_: loadTimeData.getString('invalidDisplayId'),
+      /**
+       * Contains the settingId of any deep link that wasn't able to be shown,
+       * null otherwise.
+       * @private {?chromeos.settings.mojom.Setting}
+       */
+      pendingSettingId_: {
+        type: Number,
+        value: null,
+      },
 
-  /** @private {!Route|undefined} */
-  currentRoute_: undefined,
+      /**
+       * Used by DeepLinkingBehavior to focus this page's deep links.
+       * @type {!Set<!chromeos.settings.mojom.Setting>}
+       */
+      supportedSettingIds: {
+        type: Object,
+        value: () => new Set([
+          chromeos.settings.mojom.Setting.kDisplaySize,
+          chromeos.settings.mojom.Setting.kNightLight,
+          chromeos.settings.mojom.Setting.kDisplayOrientation,
+          chromeos.settings.mojom.Setting.kDisplayArrangement,
+          chromeos.settings.mojom.Setting.kDisplayResolution,
+          chromeos.settings.mojom.Setting.kDisplayRefreshRate,
+          chromeos.settings.mojom.Setting.kDisplayMirroring,
+          chromeos.settings.mojom.Setting.kAllowWindowsToSpanDisplays,
+          chromeos.settings.mojom.Setting.kAmbientColors,
+          chromeos.settings.mojom.Setting.kTouchscreenCalibration,
+          chromeos.settings.mojom.Setting.kNightLightColorTemperature,
+          chromeos.settings.mojom.Setting.kDisplayOverscan,
+        ]),
+      },
 
-  /**
-   * Maps a parentModeIndex to the list of possible refresh rates.
-   * All modes have a modeIndex corresponding to the index in the selected
-   * display's mode list. Parent mode indexes represent the mode with the
-   * highest refresh rate at a given resolution. There is 1 and only 1
-   * parentModeIndex for each possible resolution .
-   * @private {!Map<number, DropdownMenuOptionList>}
-   */
-  parentModeToRefreshRateMap_: new Map(),
+    };
+  }
 
-  /**
-   * Map containing an entry for each display mode mapping its modeIndex to
-   * the corresponding parentModeIndex value.
-   * @private {!Map<number, number>} Mode index values for slider.
-   */
-  modeToParentModeMap_: new Map(),
+  static get observers() {
+    return [
+      'updateNightLightScheduleSettings_(prefs.ash.night_light.schedule_type.*,' +
+          ' prefs.ash.night_light.enabled.*)',
+      'onSelectedModeChange_(selectedModePref_.value)',
+      'onSelectedParentModeChange_(selectedParentModePref_.value)',
+      'onSelectedZoomChange_(selectedZoomPref_.value)',
+      'onDisplaysChanged_(displays.*)',
+
+    ];
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /**
+     * This represents the index of the mode with the highest refresh rate at
+     * the current resolution.
+     * @private {number}
+     */
+    this.currentSelectedParentModeIndex_ = -1;
+
+    /**
+     * This is the index of the currently selected mode.
+     * @private {number} Selected mode index received from chrome.
+     */
+    this.currentSelectedModeIndex_ = -1;
+
+    /**
+     * Listener for chrome.system.display.onDisplayChanged events.
+     * @type {function(void)|undefined}
+     * @private
+     */
+    this.displayChangedListener_ = undefined;
+
+    /** @private {string} */
+    this.invalidDisplayId_ = loadTimeData.getString('invalidDisplayId');
+
+    /** @private {!Route|undefined} */
+    this.currentRoute_ = undefined;
+
+    /** @private {?DevicePageBrowserProxy} */
     this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
+
+    /**
+     * Maps a parentModeIndex to the list of possible refresh rates.
+     * All modes have a modeIndex corresponding to the index in the selected
+     * display's mode list. Parent mode indexes represent the mode with the
+     * highest refresh rate at a given resolution. There is 1 and only 1
+     * parentModeIndex for each possible resolution .
+     * @private {!Map<number, DropdownMenuOptionList>}
+     */
+    this.parentModeToRefreshRateMap_ = new Map();
+
+    /**
+     * Map containing an entry for each display mode mapping its modeIndex to
+     * the corresponding parentModeIndex value.
+     * @private {!Map<number, number>} Mode index values for slider.
+     */
+    this.modeToParentModeMap_ = new Map();
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.displayChangedListener_ =
         this.displayChangedListener_ || (() => this.getDisplayInfo_());
     getDisplayApi().onDisplayChanged.addListener(this.displayChangedListener_);
 
     this.getDisplayInfo_();
     this.$.displaySizeSlider.updateValueInstantly = false;
-  },
+  }
 
   /** @override */
-  detached() {
+  disconnectedCallback() {
+    super.disconnectedCallback();
+
     getDisplayApi().onDisplayChanged.removeListener(
         assert(this.displayChangedListener_));
 
     this.currentSelectedModeIndex_ = -1;
     this.currentSelectedParentModeIndex_ = -1;
-  },
+  }
 
   /**
    * Overridden from DeepLinkingBehavior.
@@ -369,23 +391,23 @@
 
     // Continue with deep link attempt.
     return true;
-  },
+  }
 
   /**
-   * @param {!Route|undefined} opt_newRoute
-   * @param {!Route|undefined} opt_oldRoute
+   * @param {!Route} newRoute
+   * @param {!Route=} opt_oldRoute
    */
-  currentRouteChanged(opt_newRoute, opt_oldRoute) {
-    this.currentRoute_ = opt_newRoute;
+  currentRouteChanged(newRoute, opt_oldRoute) {
+    this.currentRoute_ = newRoute;
 
     // When navigating away from the page, deselect any selected display.
-    if (opt_newRoute !== routes.DISPLAY && opt_oldRoute === routes.DISPLAY) {
+    if (newRoute !== routes.DISPLAY && opt_oldRoute === routes.DISPLAY) {
       this.browserProxy_.highlightDisplay(this.invalidDisplayId_);
       return;
     }
 
     // Does not apply to this page.
-    if (opt_newRoute !== routes.DISPLAY) {
+    if (newRoute !== routes.DISPLAY) {
       this.pendingSettingId_ = null;
       return;
     }
@@ -397,7 +419,7 @@
         this.pendingSettingId_ = result.pendingSettingId;
       }
     });
-  },
+  }
 
   /**
    * Shows or hides the overscan dialog.
@@ -411,14 +433,14 @@
     } else {
       this.$.displayOverscan.close();
     }
-  },
+  }
 
   /** @private */
   onDisplayIdsChanged_() {
     // Close any overscan dialog (which will cancel any overscan operation)
     // if displayIds changes.
     this.showOverscanDialog_(false);
-  },
+  }
 
   /** @private */
   getDisplayInfo_() {
@@ -427,7 +449,7 @@
     };
     getDisplayApi().getInfo(
         flags, displays => this.displayInfoFetched_(displays));
-  },
+  }
 
   /**
    * @param {!Array<!chrome.system.display.DisplayUnitInfo>} displays
@@ -444,7 +466,7 @@
     } else {
       this.mirroringDestinationIds = [];
     }
-  },
+  }
 
   /**
    * @param {!Array<!chrome.system.display.DisplayUnitInfo>} displays
@@ -456,7 +478,7 @@
     this.displays = displays;
     this.displayTabNames_ = displays.map(({name}) => name);
     this.updateDisplayInfo_();
-  },
+  }
 
   /**
    * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
@@ -471,7 +493,7 @@
       }
     }
     return 0;
-  },
+  }
 
   /**
    * Checks if the given device policy is enabled.
@@ -481,7 +503,7 @@
    */
   isDevicePolicyEnabled_(policyPref) {
     return policyPref !== undefined && policyPref.value !== null;
-  },
+  }
 
   /**
    * Checks if display resolution is managed by device policy.
@@ -494,7 +516,7 @@
         (resolutionPref.value.external_use_native !== undefined ||
          (resolutionPref.value.external_width !== undefined &&
           resolutionPref.value.external_height !== undefined));
-  },
+  }
 
   /**
    * Checks if display resolution is managed by policy and the policy
@@ -506,7 +528,7 @@
   isDisplayResolutionMandatory_(resolutionPref) {
     return this.isDisplayResolutionManagedByPolicy_(resolutionPref) &&
         !resolutionPref.value.recommended;
-  },
+  }
 
   /**
    * Checks if display scale factor is managed by device policy.
@@ -523,7 +545,7 @@
       return resolutionPref.value.internal_scale_percentage !== undefined;
     }
     return resolutionPref.value.external_scale_percentage !== undefined;
-  },
+  }
 
   /**
    * Checks if display scale factor is managed by policy and the policy
@@ -536,7 +558,7 @@
     return this.isDisplayScaleManagedByPolicy_(
                selectedDisplay, resolutionPref) &&
         !resolutionPref.value.recommended;
-  },
+  }
 
 
   /**
@@ -565,7 +587,7 @@
       });
     }
     this.displayModeList_ = optionList;
-  },
+  }
 
   /**
    * Uses the modes of |selectedDisplay| to build a nested map of width =>
@@ -600,7 +622,7 @@
       modes.get(mode.width).get(mode.height).set(mode.refreshRate, i);
     }
     return modes;
-  },
+  }
 
   /**
    * Parses the display modes for |selectedDisplay|. |displayModeList_| will
@@ -665,7 +687,7 @@
 
     // Use the new sort order.
     this.sortResolutionList_();
-  },
+  }
 
   /**
    * Picks the appropriate parent mode from a refresh rate -> mode index map.
@@ -677,7 +699,7 @@
   getParentModeIndex_(refreshRates) {
     const maxRefreshRate = Math.max(...refreshRates.keys());
     return refreshRates.get(maxRefreshRate);
-  },
+  }
 
   /**
    * Adds a an entry in |displayModeList_| for the resolution represented by
@@ -704,7 +726,7 @@
       name: resolutionOption,
       value: parentModeIndex,
     });
-  },
+  }
 
   /**
    * Adds a an entry in |parentModeToRefreshRateMap_| for the refresh rate
@@ -734,7 +756,7 @@
       name: refreshRateOption,
       value: modeIndex,
     });
-  },
+  }
 
   /**
    * Sorts |displayModeList_| in descending order. First order sort is width,
@@ -753,7 +775,7 @@
                   getWidthFromResolutionString(second.name);
             })
             .reverse();
-  },
+  }
 
   /**
    * Parses display modes for |selectedDisplay|. A 'mode' is a resolution +
@@ -769,7 +791,7 @@
     } else {
       this.parseCompoundDisplayModes_(selectedDisplay);
     }
-  },
+  }
 
   /**
    * Returns a value from |zoomValues_| that is closest to the display zoom
@@ -792,7 +814,7 @@
     }
 
     return /** @type {number} */ (closestMatch);
-  },
+  }
 
   /**
    * Given the display with the current display mode, this function lists all
@@ -809,7 +831,7 @@
         label: this.i18n('displayZoomValue', ariaValue.toString())
       };
     });
-  },
+  }
 
   /**
    * We need to call this explicitly rather than relying on change events
@@ -866,7 +888,7 @@
 
     this.updateLogicalResolutionText_(
         /** @type {number} */ (this.selectedZoomPref_.value));
-  },
+  }
 
   /**
    * Returns true if the resolution setting needs to be displayed.
@@ -876,7 +898,7 @@
    */
   showDropDownResolutionSetting_(display) {
     return !display.isInternal;
-  },
+  }
 
   /**
    * Returns true if the refresh rate setting needs to be displayed.
@@ -887,7 +909,7 @@
   showRefreshRateSetting_(display) {
     return this.listAllDisplayModes_ &&
         this.showDropDownResolutionSetting_(display);
-  },
+  }
 
   /**
    * Returns true if external touch devices are connected and the current
@@ -901,7 +923,7 @@
   showTouchCalibrationSetting_(display) {
     return !display.isInternal &&
         loadTimeData.getBoolean('enableTouchCalibrationSetting');
-  },
+  }
 
   /**
    * Returns true if the overscan setting should be shown for |display|.
@@ -911,7 +933,7 @@
    */
   showOverscanSetting_(display) {
     return !display.isInternal;
-  },
+  }
 
   /**
    * Returns true if the ambient color setting should be shown for |display|.
@@ -922,7 +944,7 @@
    */
   showAmbientColorSetting_(ambientColorAvailable, display) {
     return ambientColorAvailable && display && display.isInternal;
-  },
+  }
 
   /**
    * @return {boolean}
@@ -930,7 +952,7 @@
    */
   hasMultipleDisplays_() {
     return this.displays.length > 1;
-  },
+  }
 
   /**
    * Returns false if the display select menu has to be hidden.
@@ -945,7 +967,7 @@
     }
 
     return false;
-  },
+  }
 
   /**
    * Returns the select menu index indicating whether the display currently is
@@ -960,7 +982,7 @@
       return 0;
     }
     return 1;
-  },
+  }
 
   /**
    * Returns the i18n string for the text to be used for mirroring settings.
@@ -970,7 +992,7 @@
    */
   getDisplayMirrorText_(displays) {
     return this.i18n('displayMirror', displays[0].name);
-  },
+  }
 
   /**
    * @param {boolean} unifiedDesktopAvailable
@@ -987,7 +1009,7 @@
     return unifiedDesktopMode ||
         (unifiedDesktopAvailable && displays.length > 1 &&
          !this.isMirrored_(displays));
-  },
+  }
 
   /**
    * @param {boolean} unifiedDesktopMode
@@ -998,7 +1020,7 @@
     return this.i18n(
         unifiedDesktopMode ? 'displayUnifiedDesktopOn' :
                              'displayUnifiedDesktopOff');
-  },
+  }
 
   /**
    * @param {boolean} unifiedDesktopMode
@@ -1013,7 +1035,7 @@
 
     return this.isMirrored_(displays) ||
         (!unifiedDesktopMode && displays.length > 1);
-  },
+  }
 
   /**
    * @param {!Array<!chrome.system.display.DisplayUnitInfo>} displays
@@ -1023,7 +1045,7 @@
   isMirrored_(displays) {
     return displays !== undefined && displays.length > 0 &&
         !!displays[0].mirroringSourceId;
-  },
+  }
 
   /**
    * @param {!chrome.system.display.DisplayUnitInfo} display
@@ -1033,7 +1055,7 @@
    */
   isSelected_(display, selectedDisplay) {
     return display.id === selectedDisplay.id;
-  },
+  }
 
   /**
    * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
@@ -1042,7 +1064,7 @@
    */
   enableSetResolution_(selectedDisplay) {
     return selectedDisplay.modes.length > 1;
-  },
+  }
 
   /**
    * @param {!chrome.system.display.DisplayUnitInfo} selectedDisplay
@@ -1051,7 +1073,7 @@
    */
   enableDisplayZoomSlider_(selectedDisplay) {
     return selectedDisplay.availableDisplayZoomFactors.length > 1;
-  },
+  }
 
   /**
    * Returns true if the given mode is the best mode for the
@@ -1074,7 +1096,7 @@
     }
 
     return mode.uiScale === 1.0;
-  },
+  }
 
   /**
    * @return {string}
@@ -1100,7 +1122,7 @@
       return this.i18n('displayResolutionTextNative', widthStr, heightStr);
     }
     return this.i18n('displayResolutionText', widthStr, heightStr);
-  },
+  }
 
   /**
    * Updates the logical resolution text to be used for the display size
@@ -1136,7 +1158,7 @@
     }
     this.logicalResolutionText_ =
         this.i18n(logicalResolutionStrId, widthStr, heightStr);
-  },
+  }
 
   /**
    * Determines whether width and height should be swapped in the
@@ -1151,7 +1173,7 @@
 
     return bounds.width > bounds.height !==
         mode.widthInNativePixels > mode.heightInNativePixels;
-  },
+  }
 
 
   /**
@@ -1169,7 +1191,7 @@
     const zoomFactor = this.$.displaySizeSlider.ticks[sliderValue].value;
     this.updateLogicalResolutionText_(
         /** @type {number} */ (zoomFactor));
-  },
+  }
 
   /**
    * @param {!CustomEvent<string>} e |e.detail| is the id of the selected
@@ -1187,15 +1209,15 @@
         return;
       }
     }
-  },
+  }
 
   /** @private */
   onSelectDisplayTab_() {
-    const {selected} = this.$$('cr-tabs');
+    const {selected} = this.shadowRoot.querySelector('cr-tabs');
     if (this.selectedTab_ !== selected) {
       this.setSelectedDisplay_(this.displays[selected]);
     }
-  },
+  }
 
   /**
    * Handles event when a touch calibration option is selected.
@@ -1204,7 +1226,7 @@
    */
   onTouchCalibrationTap_(e) {
     getDisplayApi().showNativeTouchCalibration(this.selectedDisplay.id);
-  },
+  }
 
   /**
    * Handles the event when an option from display select menu is selected.
@@ -1229,7 +1251,7 @@
     getDisplayApi().setDisplayProperties(
         this.selectedDisplay.id, properties,
         () => this.setPropertiesCallback_());
-  },
+  }
 
   /**
    * Handles a change in the |selectedParentModePref| value triggered via the
@@ -1250,7 +1272,7 @@
 
     // Reset |selectedModePref| to the parentMode.
     this.set('selectedModePref_.value', this.selectedParentModePref_.value);
-  },
+  }
 
   /**
    * Returns True if a new parentMode has been set and we have received an
@@ -1265,7 +1287,7 @@
 
     return this.currentSelectedParentModeIndex_ !==
         this.selectedParentModePref_.value;
-  },
+  }
 
   /**
    * Returns True if a new mode has been set and we have received an update
@@ -1284,7 +1306,7 @@
     }
 
     return this.currentSelectedModeIndex_ !== this.selectedModePref_.value;
-  },
+  }
 
   /**
    * Handles a change in |selectedModePref| triggered via the observer.
@@ -1313,7 +1335,7 @@
     getDisplayApi().setDisplayProperties(
         this.selectedDisplay.id, properties,
         () => this.setPropertiesCallback_());
-  },
+  }
 
   /**
    * Triggerend when the display size slider changes its value. This only
@@ -1334,7 +1356,7 @@
     getDisplayApi().setDisplayProperties(
         this.selectedDisplay.id, properties,
         () => this.setPropertiesCallback_());
-  },
+  }
 
   /**
    * Returns whether the option "Auto-rotate" is one of the shown options in
@@ -1345,7 +1367,7 @@
    */
   showAutoRotateOption_(selectedDisplay) {
     return selectedDisplay.isAutoRotationAllowed;
-  },
+  }
 
   /**
    * @param {!Event} event
@@ -1363,7 +1385,7 @@
     getDisplayApi().setDisplayProperties(
         this.selectedDisplay.id, properties,
         () => this.setPropertiesCallback_());
-  },
+  }
 
   /** @private */
   onMirroredTap_(event) {
@@ -1383,7 +1405,7 @@
         console.error('setMirrorMode Error: ' + error.message);
       }
     });
-  },
+  }
 
   /** @private */
   onUnifiedDesktopTap_() {
@@ -1392,7 +1414,7 @@
     };
     getDisplayApi().setDisplayProperties(
         this.primaryDisplayId, properties, () => this.setPropertiesCallback_());
-  },
+  }
 
   /**
    * @param {!Event} e
@@ -1402,12 +1424,12 @@
     e.preventDefault();
     this.overscanDisplayId = this.selectedDisplay.id;
     this.showOverscanDialog_(true);
-  },
+  }
 
   /** @private */
   onCloseOverscanDialog_() {
-    focusWithoutInk(assert(this.$$('#overscan')));
-  },
+    focusWithoutInk(assert(this.shadowRoot.querySelector('#overscan')));
+  }
 
   /** @private */
   updateDisplayInfo_() {
@@ -1445,7 +1467,7 @@
         this.pendingSettingId_ = null;
       }
     });
-  },
+  }
 
   /** @private */
   setPropertiesCallback_() {
@@ -1453,7 +1475,7 @@
       console.error(
           'setDisplayProperties Error: ' + chrome.runtime.lastError.message);
     }
-  },
+  }
 
   /**
    * Invoked when the status of Night Light or its schedule type are changed,
@@ -1474,7 +1496,7 @@
     } else {
       this.nightLightScheduleSubLabel_ = '';
     }
-  },
+  }
 
   /**
    * @return {boolean}
@@ -1485,15 +1507,17 @@
       return false;
     }
     return this.hasMultipleDisplays_() || this.isMirrored_(this.displays);
-  },
+  }
 
   /** @private */
   onDisplaysChanged_() {
     flush();
-    const displayLayout = this.$$('#displayLayout');
+    const displayLayout = this.shadowRoot.querySelector('#displayLayout');
     if (displayLayout) {
       displayLayout.updateDisplays(
           this.displays, this.layouts, this.mirroringDestinationIds);
     }
-  },
-});
+  }
+}
+
+customElements.define(SettingsDisplayElement.is, SettingsDisplayElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/display_layout.js b/chrome/browser/resources/settings/chromeos/device_page/display_layout.js
index 7b4f666..5a7a737 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/display_layout.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/display_layout.js
@@ -8,6 +8,17 @@
  * more displays and allows them to be arranged.
  */
 
+import '//resources/polymer/v3_0/paper-styles/shadow.js';
+import '../../settings_shared_css.js';
+
+import {loadTimeData} from '//resources/js/load_time_data.m.js';
+import {IronResizableBehavior} from '//resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl} from './device_page_browser_proxy.js';
+import {DragBehavior, DragBehaviorInterface, DragPosition} from './drag_behavior.js';
+import {LayoutBehavior, LayoutBehaviorInterface} from './layout_behavior.js';
+
 /**
  * Container for DisplayUnitInfo.  Mostly here to make the DisplaySelectEvent
  * typedef more readable.
@@ -21,86 +32,91 @@
  */
 let DisplaySelectEvent;
 
-import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {IronResizableBehavior} from '//resources/polymer/v3_0/iron-resizable-behavior/iron-resizable-behavior.js';
-import '//resources/polymer/v3_0/paper-styles/shadow.js';
-import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {DragBehavior, DragPosition} from './drag_behavior.js';
-import {LayoutBehavior} from './layout_behavior.js';
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, getDisplayApi, StorageSpaceState} from './device_page_browser_proxy.js';
-import '../../settings_shared_css.js';
-
-
 /** @type {number} */ const MIN_VISUAL_SCALE = .01;
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'display-layout',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DragBehaviorInterface}
+ * @implements {LayoutBehaviorInterface}
+ */
+const DisplayLayoutElementBase = mixinBehaviors(
+    [IronResizableBehavior, DragBehavior, LayoutBehavior], PolymerElement);
 
-  behaviors: [
-    IronResizableBehavior,
-    DragBehavior,
-    LayoutBehavior,
-  ],
+/** @polymer */
+class DisplayLayoutElement extends DisplayLayoutElementBase {
+  static get is() {
+    return 'display-layout';
+  }
 
-  properties: {
-    /**
-     * Array of displays.
-     * @type {!Array<!chrome.system.display.DisplayUnitInfo>}
-     */
-    displays: Array,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** @type {!chrome.system.display.DisplayUnitInfo|undefined} */
-    selectedDisplay: Object,
+  static get properties() {
+    return {
+      /**
+       * Array of displays.
+       * @type {!Array<!chrome.system.display.DisplayUnitInfo>}
+       */
+      displays: Array,
 
-    /**
-     * The ratio of the display area div (in px) to DisplayUnitInfo.bounds.
-     * @type {number}
-     */
-    visualScale: {
-      type: Number,
-      value: 1,
-    },
+      /** @type {!chrome.system.display.DisplayUnitInfo|undefined} */
+      selectedDisplay: Object,
 
-    /**
-     * Ids for mirroring destination displays.
-     * @type {!Array<string>|undefined}
-     * @private
-     */
-    mirroringDestinationIds_: Array,
-  },
+      /**
+       * The ratio of the display area div (in px) to DisplayUnitInfo.bounds.
+       * @type {number}
+       */
+      visualScale: {
+        type: Number,
+        value: 1,
+      },
 
-  /** @private {!{left: number, top: number}} */
-  visualOffset_: {left: 0, top: 0},
-
-  /**
-   * Stores the previous coordinates of a display once dragging starts. Used to
-   * calculate the delta during each step of the drag. Null when there is no
-   * drag in progress.
-   * @private {?{x: number, y: number}}
-   */
-  lastDragCoordinates_: null,
-
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
-
-  /** @private {boolean} */
-  allowDisplayAlignmentApi_:
-      loadTimeData.getBoolean('allowDisplayAlignmentApi'),
-
-  /** @private {string} */
-  invalidDisplayId_: loadTimeData.getString('invalidDisplayId'),
+      /**
+       * Ids for mirroring destination displays.
+       * @type {!Array<string>|undefined}
+       * @private
+       */
+      mirroringDestinationIds_: Array,
+    };
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {!{left: number, top: number}} */
+    this.visualOffset_ = {left: 0, top: 0};
+
+    /**
+     * Stores the previous coordinates of a display once dragging starts. Used
+     * to calculate the delta during each step of the drag. Null when there is
+     * no drag in progress.
+     * @private {?{x: number, y: number}}
+     */
+    this.lastDragCoordinates_ = null;
+
+    /** @private {?DevicePageBrowserProxy} */
     this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
+
+    /** @private {boolean} */
+    this.allowDisplayAlignmentApi_ =
+        loadTimeData.getBoolean('allowDisplayAlignmentApi');
+
+    /** @private {string} */
+    this.invalidDisplayId_ = loadTimeData.getString('invalidDisplayId');
+
+    /** @private {boolean} */
+    this.hasDragStarted_ = false;
+  }
 
   /** @override */
-  detached() {
+  disconnectedCallback() {
+    super.disconnectedCallback();
+
     this.initializeDrag(false);
-  },
+  }
 
   /**
    * Called explicitly when |this.displays| and their associated |this.layouts|
@@ -130,7 +146,7 @@
     this.initializeDrag(
         !this.mirroring, this.$.displayArea,
         (id, amount) => this.onDrag_(id, amount));
-  },
+  }
 
   /**
    * Calculates the visual offset and scale for the display area
@@ -193,7 +209,7 @@
     this.visualScale = Math.max(MIN_VISUAL_SCALE, scale);
 
     return true;
-  },
+  }
 
   /**
    * @param {string} id
@@ -223,7 +239,7 @@
         Math.round(this.visualOffset_.top + (bounds.top * this.visualScale));
     return 'height: ' + height + 'px; width: ' + width + 'px;' +
         ' left: ' + left + 'px; top: ' + top + 'px';
-  },
+  }
 
   /**
    * @param {number} mirroringDestinationIndex
@@ -242,7 +258,7 @@
     return this.getDivStyle_(
         displays[0].id, displays[0].bounds, visualScale,
         (mirroringDestinationDisplayNum - mirroringDestinationIndex) * -4);
-  },
+  }
 
   /**
    * @param {!chrome.system.display.DisplayUnitInfo} display
@@ -252,7 +268,7 @@
    */
   isSelected_(display, selectedDisplay) {
     return display.id === selectedDisplay.id;
-  },
+  }
 
   focusSelectedDisplay_() {
     if (!this.selectedDisplay) {
@@ -264,27 +280,31 @@
     if (selected) {
       selected.focus();
     }
-  },
+  }
 
   /**
    * @param {!DisplaySelectEvent} e
    * @private
    */
   onSelectDisplayTap_(e) {
-    this.fire('select-display', e.model.item.id);
+    const selectDisplayEvent = new CustomEvent(
+        'select-display', {composed: true, detail: e.model.item.id});
+    this.dispatchEvent(selectDisplayEvent);
     // Force active in case the selected display was clicked.
     // TODO(dpapad): Ask @stevenjb, why are we setting 'active' on a div?
     e.target.active = true;
-  },
+  }
 
   /**
    * @param {!DisplaySelectEvent} e
    * @private
    */
   onFocus_(e) {
-    this.fire('select-display', e.model.item.id);
+    const selectDisplayEvent = new CustomEvent(
+        'select-display', {composed: true, detail: e.model.item.id});
+    this.dispatchEvent(selectDisplayEvent);
     this.focusSelectedDisplay_();
-  },
+  }
 
   /**
    * @param {string} id
@@ -304,7 +324,9 @@
       this.browserProxy_.highlightDisplay(id);
       // Make sure the dragged display is also selected.
       if (id !== this.selectedDisplay.id) {
-        this.fire('select-display', id);
+        const selectDisplayEvent =
+            new CustomEvent('select-display', {composed: true, detail: id});
+        this.dispatchEvent(selectDisplayEvent);
       }
 
       const calculatedBounds = this.getCalculatedDisplayBounds(id);
@@ -345,10 +367,11 @@
         this.visualOffset_.left + Math.round(newBounds.left * this.visualScale);
     const top =
         this.visualOffset_.top + Math.round(newBounds.top * this.visualScale);
-    const div = this.$$('#_' + id);
+    const div = this.shadowRoot.querySelector('#_' + id);
     div.style.left = '' + left + 'px';
     div.style.top = '' + top + 'px';
     this.focusSelectedDisplay_();
-  },
+  }
+}
 
-});
+customElements.define(DisplayLayoutElement.is, DisplayLayoutElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/display_overscan_dialog.js b/chrome/browser/resources/settings/chromeos/device_page/display_overscan_dialog.js
index 963e042..4083c33 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/display_overscan_dialog.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/display_overscan_dialog.js
@@ -16,32 +16,46 @@
 import '../os_icons.js';
 import '../../settings_shared_css.js';
 
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {getDisplayApi} from './device_page_browser_proxy.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-display-overscan-dialog',
+/** @polymer */
+class SettingsDisplayOverscanDialogElement extends PolymerElement {
+  static get is() {
+    return 'settings-display-overscan-dialog';
+  }
 
-  properties: {
-    /** Id of the display for which overscan is being applied (or empty). */
-    displayId: {
-      type: String,
-      notify: true,
-      observer: 'displayIdChanged_',
-    },
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** Set to true once changes are saved to avoid a reset/cancel on close. */
-    committed_: Boolean,
-  },
+  static get properties() {
+    return {
+      /** Id of the display for which overscan is being applied (or empty). */
+      displayId: {
+        type: String,
+        notify: true,
+        observer: 'displayIdChanged_',
+      },
 
-  /**
-   * Keyboard event handler for overscan adjustments.
-   * @type {?function(!Event)}
-   * @private
-   */
-  keyHandler_: null,
+      /**
+         Set to true once changes are saved to avoid a reset/cancel on close.
+       */
+      committed_: Boolean,
+    };
+  }
+
+  constructor() {
+    super();
+
+    /**
+     * Keyboard event handler for overscan adjustments.
+     * @type {?function(!Event)}
+     * @private
+     */
+    this.keyHandler_ = null;
+  }
 
   open() {
     this.keyHandler_ = this.handleKeyEvent_.bind(this);
@@ -51,8 +65,8 @@
     this.committed_ = false;
     this.$.dialog.showModal();
     // Don't focus 'reset' by default. 'Tab' will focus 'OK'.
-    this.$$('#reset').blur();
-  },
+    this.shadowRoot.querySelector('#reset').blur();
+  }
 
   close() {
     window.removeEventListener('keydown', this.keyHandler_);
@@ -62,7 +76,7 @@
     if (this.$.dialog.open) {
       this.$.dialog.close();
     }
-  },
+  }
 
   /** @private */
   displayIdChanged_(newValue, oldValue) {
@@ -75,19 +89,19 @@
     }
     this.committed_ = false;
     getDisplayApi().overscanCalibrationStart(newValue);
-  },
+  }
 
   /** @private */
   onResetTap_() {
     getDisplayApi().overscanCalibrationReset(this.displayId);
-  },
+  }
 
   /** @private */
   onSaveTap_() {
     getDisplayApi().overscanCalibrationComplete(this.displayId);
     this.committed_ = true;
     this.close();
-  },
+  }
 
   /**
    * @param {!Event} event
@@ -131,7 +145,7 @@
         return;
     }
     event.preventDefault();
-  },
+  }
 
   /**
    * @param {number} x
@@ -146,7 +160,7 @@
       bottom: y ? -y : 0,
     };
     getDisplayApi().overscanCalibrationAdjust(this.displayId, delta);
-  },
+  }
 
   /**
    * @param {number} x
@@ -162,4 +176,8 @@
     };
     getDisplayApi().overscanCalibrationAdjust(this.displayId, delta);
   }
-});
+}
+
+customElements.define(
+    SettingsDisplayOverscanDialogElement.is,
+    SettingsDisplayOverscanDialogElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/drag_behavior.js b/chrome/browser/resources/settings/chromeos/device_page/drag_behavior.js
index a5e7eed..459f688 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/drag_behavior.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/drag_behavior.js
@@ -2,15 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// clang-format off
-import {assert, assertInstanceof} from 'chrome://resources/js/assert.m.js';
-// clang-format on
-
 /**
  * @fileoverview Behavior for handling dragging elements in a container.
  *     Draggable elements must have the 'draggable' attribute set.
  */
 
+import {assert, assertInstanceof} from 'chrome://resources/js/assert.m.js';
+
 /**
  * @typedef {{
  *   x: number,
@@ -411,3 +409,24 @@
     }
   },
 };
+
+/** @interface */
+export class DragBehaviorInterface {
+  constructor() {
+    /** @type {boolean} */
+    this.dragEnabled;
+
+    /** @type {boolean} */
+    this.keyboardDragEnabled;
+
+    /** @type {number} */
+    this.keyboardDragStepSize;
+  }
+
+  /**
+   * @param {boolean} enabled
+   * @param {(HTMLDivElement|Element)=} opt_container
+   * @param {!function(string, ?DragPosition):void=} opt_callback
+   */
+  initializeDrag(enabled, opt_container, opt_callback) {}
+}
diff --git a/chrome/browser/resources/settings/chromeos/device_page/keyboard.js b/chrome/browser/resources/settings/chromeos/device_page/keyboard.js
index ec2f375..65a9fd7 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/keyboard.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/keyboard.js
@@ -38,7 +38,6 @@
   ASSISTANT_KEY: 7,
 };
 
-
 Polymer({
   _template: html`{__html_template__}`,
   is: 'settings-keyboard',
diff --git a/chrome/browser/resources/settings/chromeos/device_page/layout_behavior.js b/chrome/browser/resources/settings/chromeos/device_page/layout_behavior.js
index 992bfd7a..8a7c1d3b 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/layout_behavior.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/layout_behavior.js
@@ -2,16 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// clang-format off
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {getDisplayApi} from './device_page_browser_proxy.js';
-// clang-format on
-
 /**
  * @fileoverview Behavior for handling display layout, specifically
  *     edge snapping and collisions.
  */
 
+import {assert} from 'chrome://resources/js/assert.m.js';
+
+import {getDisplayApi} from './device_page_browser_proxy.js';
+
 /** @polymerBehavior */
 export const LayoutBehavior = {
   properties: {
@@ -733,3 +732,49 @@
     }
   },
 };
+
+/** @interface */
+export class LayoutBehaviorInterface {
+  constructor() {
+    /**
+     * Array of display layouts.
+     * @type {!Array<!chrome.system.display.DisplayLayout>}
+     */
+    this.layouts;
+
+    /**
+     * Whether or not mirroring is enabled.
+     * @type {boolean}
+     */
+    this.mirroring;
+  }
+
+  /**
+   * @param {!Array<!chrome.system.display.DisplayUnitInfo>} displays
+   * @param {!Array<!chrome.system.display.DisplayLayout>} layouts
+   */
+  initializeDisplayLayout(displays, layouts) {}
+
+
+  /**
+   * Called when a drag event occurs. Checks collisions and updates the layout.
+   * @param {string} id
+   * @param {!chrome.system.display.Bounds} newBounds The new calculated
+   *     bounds for the display.
+   * @return {!chrome.system.display.Bounds}
+   */
+  updateDisplayBounds(id, newBounds) {}
+
+  /**
+   * Called when dragging ends. Sends the updated layout to chrome.
+   * @param {string} id
+   */
+  finishUpdateDisplayBounds(id) {}
+
+  /**
+   * @param {string} displayId
+   * @param {boolean=} opt_notest Set to true if bounds may not be set.
+   * @return {!chrome.system.display.Bounds} bounds
+   */
+  getCalculatedDisplayBounds(displayId, opt_notest) {}
+}
diff --git a/chrome/browser/resources/settings/chromeos/device_page/pointers.js b/chrome/browser/resources/settings/chromeos/device_page/pointers.js
index ebd7b01f..eb18a84 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/pointers.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/pointers.js
@@ -16,158 +16,171 @@
 import '//resources/cr_elements/cr_slider/cr_slider.js';
 
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Route, Router} from '../../router.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
+import {Route} from '../../router.js';
+import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
 import {routes} from '../os_route.js';
-import {PrefsBehavior} from '../prefs_behavior.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
+import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {PrefsBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ */
+const SettingsPointersElementBase = mixinBehaviors(
+    [DeepLinkingBehavior, PrefsBehavior, RouteObserverBehavior],
+    PolymerElement);
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-pointers',
+/** @polymer */
+class SettingsPointersElement extends SettingsPointersElementBase {
+  static get is() {
+    return 'settings-pointers';
+  }
 
-  behaviors: [
-    DeepLinkingBehavior,
-    PrefsBehavior,
-    RouteObserverBehavior,
-  ],
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-  properties: {
-    prefs: {
-      type: Object,
-      notify: true,
-    },
-
-    hasMouse: Boolean,
-
-    hasPointingStick: Boolean,
-
-    hasTouchpad: Boolean,
-
-    hasHapticTouchpad: Boolean,
-
-    swapPrimaryOptions: {
-      readOnly: true,
-      type: Array,
-      value() {
-        return [
-          {
-            value: false,
-            name: loadTimeData.getString('primaryMouseButtonLeft')
-          },
-          {
-            value: true,
-            name: loadTimeData.getString('primaryMouseButtonRight')
-          },
-        ];
+  static get properties() {
+    return {
+      prefs: {
+        type: Object,
+        notify: true,
       },
-    },
 
-    showHeadings_: {
-      type: Boolean,
-      computed: 'computeShowHeadings_(hasMouse, hasPointingStick, hasTouchpad)',
-    },
+      hasMouse: Boolean,
 
-    subsectionClass_: {
-      type: String,
-      computed: 'computeSubsectionClass_(hasMouse, hasPointingStick, ' +
-          'hasTouchpad)',
-    },
+      hasPointingStick: Boolean,
 
-    /**
-     * TODO(michaelpg): settings-slider should optionally take a min and max so
-     * we don't have to generate a simple range of natural numbers ourselves.
-     * These values match the TouchpadSensitivity enum in enums.xml.
-     * @type {!Array<number>}
-     * @private
-     */
-    sensitivityValues_: {
-      type: Array,
-      value: [1, 2, 3, 4, 5],
-      readOnly: true,
-    },
+      hasTouchpad: Boolean,
 
-    /**
-     * The click sensitivity values from prefs are [1,3,5] but ChromeVox needs
-     * to announce them as [1,2,3].
-     * @type {!Array<SliderTick>}
-     * @private
-     */
-    hapticClickSensitivityValues_: {
-      type: Array,
-      value() {
-        return [
-          {value: 1, ariaValue: 1},
-          {value: 3, ariaValue: 2},
-          {value: 5, ariaValue: 3},
-        ];
+      hasHapticTouchpad: Boolean,
+
+      swapPrimaryOptions: {
+        readOnly: true,
+        type: Array,
+        value() {
+          return [
+            {
+              value: false,
+              name: loadTimeData.getString('primaryMouseButtonLeft')
+            },
+            {
+              value: true,
+              name: loadTimeData.getString('primaryMouseButtonRight')
+            },
+          ];
+        },
       },
-      readOnly: true,
-    },
 
-    /**
-     * TODO(khorimoto): Remove this conditional once the feature is launched.
-     * @private
-     */
-    allowScrollSettings_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('allowScrollSettings');
+      showHeadings_: {
+        type: Boolean,
+        computed:
+            'computeShowHeadings_(hasMouse, hasPointingStick, hasTouchpad)',
       },
-    },
 
-    /**
-     * TODO(gavinwill): Remove this conditional once the feature is launched.
-     * @private
-     */
-    allowTouchpadHapticFeedback_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('allowTouchpadHapticFeedback');
+      subsectionClass_: {
+        type: String,
+        computed: 'computeSubsectionClass_(hasMouse, hasPointingStick, ' +
+            'hasTouchpad)',
       },
-    },
 
-    /**
-     * TODO(gavinwill): Remove this conditional once the feature is launched.
-     * @private
-     */
-    allowTouchpadHapticClickSettings_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('allowTouchpadHapticClickSettings');
+      /**
+       * TODO(michaelpg): settings-slider should optionally take a min and max
+       * so we don't have to generate a simple range of natural numbers
+       * ourselves. These values match the TouchpadSensitivity enum in
+       * enums.xml.
+       * @type {!Array<number>}
+       * @private
+       */
+      sensitivityValues_: {
+        type: Array,
+        value: [1, 2, 3, 4, 5],
+        readOnly: true,
       },
-    },
 
-    /**
-     * Used by DeepLinkingBehavior to focus this page's deep links.
-     * @type {!Set<!chromeos.settings.mojom.Setting>}
-     */
-    supportedSettingIds: {
-      type: Object,
-      value: () => new Set([
-        chromeos.settings.mojom.Setting.kTouchpadTapToClick,
-        chromeos.settings.mojom.Setting.kTouchpadTapDragging,
-        chromeos.settings.mojom.Setting.kTouchpadReverseScrolling,
-        chromeos.settings.mojom.Setting.kTouchpadAcceleration,
-        chromeos.settings.mojom.Setting.kTouchpadScrollAcceleration,
-        chromeos.settings.mojom.Setting.kTouchpadSpeed,
-        chromeos.settings.mojom.Setting.kTouchpadHapticFeedback,
-        chromeos.settings.mojom.Setting.kTouchpadHapticClickSensitivity,
-        chromeos.settings.mojom.Setting.kPointingStickAcceleration,
-        chromeos.settings.mojom.Setting.kPointingStickSpeed,
-        chromeos.settings.mojom.Setting.kPointingStickSwapPrimaryButtons,
-        chromeos.settings.mojom.Setting.kMouseSwapPrimaryButtons,
-        chromeos.settings.mojom.Setting.kMouseReverseScrolling,
-        chromeos.settings.mojom.Setting.kMouseAcceleration,
-        chromeos.settings.mojom.Setting.kMouseScrollAcceleration,
-        chromeos.settings.mojom.Setting.kMouseSpeed,
-      ]),
-    },
-  },
+      /**
+       * The click sensitivity values from prefs are [1,3,5] but ChromeVox needs
+       * to announce them as [1,2,3].
+       * @type {!Array<SliderTick>}
+       * @private
+       */
+      hapticClickSensitivityValues_: {
+        type: Array,
+        value() {
+          return [
+            {value: 1, ariaValue: 1},
+            {value: 3, ariaValue: 2},
+            {value: 5, ariaValue: 3},
+          ];
+        },
+        readOnly: true,
+      },
+
+      /**
+       * TODO(khorimoto): Remove this conditional once the feature is launched.
+       * @private
+       */
+      allowScrollSettings_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('allowScrollSettings');
+        },
+      },
+
+      /**
+       * TODO(gavinwill): Remove this conditional once the feature is launched.
+       * @private
+       */
+      allowTouchpadHapticFeedback_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('allowTouchpadHapticFeedback');
+        },
+      },
+
+      /**
+       * TODO(gavinwill): Remove this conditional once the feature is launched.
+       * @private
+       */
+      allowTouchpadHapticClickSettings_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('allowTouchpadHapticClickSettings');
+        },
+      },
+
+      /**
+       * Used by DeepLinkingBehavior to focus this page's deep links.
+       * @type {!Set<!chromeos.settings.mojom.Setting>}
+       */
+      supportedSettingIds: {
+        type: Object,
+        value: () => new Set([
+          chromeos.settings.mojom.Setting.kTouchpadTapToClick,
+          chromeos.settings.mojom.Setting.kTouchpadTapDragging,
+          chromeos.settings.mojom.Setting.kTouchpadReverseScrolling,
+          chromeos.settings.mojom.Setting.kTouchpadAcceleration,
+          chromeos.settings.mojom.Setting.kTouchpadScrollAcceleration,
+          chromeos.settings.mojom.Setting.kTouchpadSpeed,
+          chromeos.settings.mojom.Setting.kTouchpadHapticFeedback,
+          chromeos.settings.mojom.Setting.kTouchpadHapticClickSensitivity,
+          chromeos.settings.mojom.Setting.kPointingStickAcceleration,
+          chromeos.settings.mojom.Setting.kPointingStickSpeed,
+          chromeos.settings.mojom.Setting.kPointingStickSwapPrimaryButtons,
+          chromeos.settings.mojom.Setting.kMouseSwapPrimaryButtons,
+          chromeos.settings.mojom.Setting.kMouseReverseScrolling,
+          chromeos.settings.mojom.Setting.kMouseAcceleration,
+          chromeos.settings.mojom.Setting.kMouseScrollAcceleration,
+          chromeos.settings.mojom.Setting.kMouseSpeed,
+        ]),
+      },
+    };
+  }
 
   /**
    * Headings should only be visible if more than one subsection is present.
@@ -182,7 +195,7 @@
     // Count the number of true values in sectionVisibilities.
     const numVisibleSections = sectionVisibilities.filter(x => x).length;
     return numVisibleSections > 1;
-  },
+  }
 
   /**
    * Mouse, pointing stick, and touchpad sections are only subsections if more
@@ -197,11 +210,11 @@
     const subsections =
         this.computeShowHeadings_(hasMouse, hasPointingStick, hasTouchpad);
     return subsections ? 'subsection' : '';
-  },
+  }
 
   /**
    * @param {!Route} route
-   * @param {Route} oldRoute
+   * @param {!Route=} oldRoute
    */
   currentRouteChanged(route, oldRoute) {
     // Does not apply to this page.
@@ -210,13 +223,13 @@
     }
 
     this.attemptDeepLink();
-  },
+  }
 
   /**
    * @param {!Event} event
    * @private
    */
-  onLearnMoreLinkClicked_: function(event) {
+  onLearnMoreLinkClicked_(event) {
     if (!Array.isArray(event.path) || !event.path.length) {
       return;
     }
@@ -225,26 +238,28 @@
       // Do not toggle reverse scrolling if the contained link is clicked.
       event.stopPropagation();
     }
-  },
+  }
 
   /** @private */
-  onMouseReverseScrollRowClicked_: function() {
+  onMouseReverseScrollRowClicked_() {
     this.setPrefValue(
         'settings.mouse.reverse_scroll',
         !this.getPref('settings.mouse.reverse_scroll').value);
-  },
+  }
 
   /** @private */
-  onTouchpadReverseScrollRowClicked_: function() {
+  onTouchpadReverseScrollRowClicked_() {
     this.setPrefValue(
         'settings.touchpad.natural_scroll',
         !this.getPref('settings.touchpad.natural_scroll').value);
-  },
+  }
 
   /** @private */
-  onTouchpadHapticFeedbackRowClicked_: function() {
+  onTouchpadHapticFeedbackRowClicked_() {
     this.setPrefValue(
         'settings.touchpad.haptic_feedback',
         !this.getPref('settings.touchpad.haptic_feedback').value);
-  },
-});
+  }
+}
+
+customElements.define(SettingsPointersElement.is, SettingsPointersElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/power.js b/chrome/browser/resources/settings/chromeos/device_page/power.js
index c0ed46a..c25bac0 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/power.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/power.js
@@ -14,170 +14,192 @@
 import '../../controls/settings_toggle_button.js';
 import '../../settings_shared_css.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
-import {addWebUIListener, removeWebUIListener, sendWithPromise, WebUIListener} from '//resources/js/cr.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
+import {assertNotReached} from '//resources/js/assert.m.js';
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {Route, Router} from '../../router.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
+import {Route} from '../../router.js';
+import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
 import {recordSettingChange} from '../metrics_recorder.js';
 import {routes} from '../os_route.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, IdleBehavior, LidClosedBehavior, PowerManagementSettings, PowerSource} from './device_page_browser_proxy.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-power',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {I18nBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsPowerElementBase = mixinBehaviors(
+    [
+      DeepLinkingBehavior, I18nBehavior, RouteObserverBehavior,
+      WebUIListenerBehavior
+    ],
+    PolymerElement);
 
-  behaviors: [
-    DeepLinkingBehavior,
-    I18nBehavior,
-    RouteObserverBehavior,
-    WebUIListenerBehavior,
-  ],
+/** @polymer */
+class SettingsPowerElement extends SettingsPowerElementBase {
+  static get is() {
+    return 'settings-power';
+  }
 
-  properties: {
-    /** @private {string} ID of the selected power source, or ''. */
-    selectedPowerSourceId_: String,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** @private {!BatteryStatus|undefined} */
-    batteryStatus_: Object,
+  static get properties() {
+    return {
+      /** @private {string} ID of the selected power source, or ''. */
+      selectedPowerSourceId_: String,
 
-    /** @private {boolean} Whether a low-power (USB) charger is being used. */
-    lowPowerCharger_: Boolean,
+      /** @private {!BatteryStatus|undefined} */
+      batteryStatus_: Object,
 
-    /** @private {boolean} Whether the AC idle behavior is managed by policy. */
-    acIdleManaged_: Boolean,
+      /** @private {boolean} Whether a low-power (USB) charger is being used. */
+      lowPowerCharger_: Boolean,
 
-    /**
-     * @private {boolean} Whether the battery idle behavior is managed by
-     *     policy.
-     */
-    batteryIdleManaged_: Boolean,
+      /**
+         @private {boolean} Whether the AC idle behavior is managed by policy.
+           */
+      acIdleManaged_: Boolean,
 
-    /** @private {string} Text for label describing the lid-closed behavior. */
-    lidClosedLabel_: String,
+      /**
+       * @private {boolean} Whether the battery idle behavior is managed by
+       *     policy.
+       */
+      batteryIdleManaged_: Boolean,
 
-    /** @private {boolean} Whether the system possesses a lid. */
-    hasLid_: Boolean,
+      /**
+         @private {string} Text for label describing the lid-closed behavior.
+           */
+      lidClosedLabel_: String,
 
-    /**
-     * List of available dual-role power sources.
-     * @private {!Array<!PowerSource>|undefined}
-     */
-    powerSources_: Array,
+      /** @private {boolean} Whether the system possesses a lid. */
+      hasLid_: Boolean,
 
-    /** @private */
-    powerSourceLabel_: {
-      type: String,
-      computed:
-          'computePowerSourceLabel_(powerSources_, batteryStatus_.calculating)',
-    },
+      /**
+       * List of available dual-role power sources.
+       * @private {!Array<!PowerSource>|undefined}
+       */
+      powerSources_: Array,
 
-    /** @private */
-    showPowerSourceDropdown_: {
-      type: Boolean,
-      computed: 'computeShowPowerSourceDropdown_(powerSources_)',
-      value: false,
-    },
-
-    /**
-     * The name of the dedicated charging device being used, if present.
-     * @private {string}
-     */
-    powerSourceName_: {
-      type: String,
-      computed: 'computePowerSourceName_(powerSources_, lowPowerCharger_)',
-    },
-
-    /**
-       @private {Array<!{value: IdleBehavior, name: string, selected:
-           boolean}>}
-     */
-    acIdleOptions_: {
-      type: Array,
-      value() {
-        return [];
+      /** @private */
+      powerSourceLabel_: {
+        type: String,
+        computed:
+            'computePowerSourceLabel_(powerSources_, batteryStatus_.calculating)',
       },
-    },
 
-    /**
-       @private {Array<!{value: IdleBehavior, name: string, selected:
-           boolean}>}
-     */
-    batteryIdleOptions_: {
-      type: Array,
-      value() {
-        return [];
+      /** @private */
+      showPowerSourceDropdown_: {
+        type: Boolean,
+        computed: 'computeShowPowerSourceDropdown_(powerSources_)',
+        value: false,
       },
-    },
 
-    /** @private {boolean} */
-    shouldAcIdleSelectBeDisabled_: {
-      type: Boolean,
-      computed: 'hasSingleOption_(acIdleOptions_)',
-    },
-
-    /** @private {boolean} */
-    shouldBatteryIdleSelectBeDisabled_: {
-      type: Boolean,
-      computed: 'hasSingleOption_(batteryIdleOptions_)',
-    },
-
-    /** @private {boolean} */
-    adaptiveChargingEnabled_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('isAdaptiveChargingEnabled');
+      /**
+       * The name of the dedicated charging device being used, if present.
+       * @private {string}
+       */
+      powerSourceName_: {
+        type: String,
+        computed: 'computePowerSourceName_(powerSources_, lowPowerCharger_)',
       },
-    },
 
-    /** @private {!chrome.settingsPrivate.PrefObject} */
-    lidClosedPref_: {
-      type: Object,
-      value() {
-        return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+      /**
+         @private {Array<!{value: IdleBehavior, name: string, selected:
+             boolean}>}
+       */
+      acIdleOptions_: {
+        type: Array,
+        value() {
+          return [];
+        },
       },
-    },
 
-    /** @private {!chrome.settingsPrivate.PrefObject} */
-    adaptiveChargingPref_: {
-      type: Object,
-      value() {
-        return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+      /**
+         @private {Array<!{value: IdleBehavior, name: string, selected:
+             boolean}>}
+       */
+      batteryIdleOptions_: {
+        type: Array,
+        value() {
+          return [];
+        },
       },
-    },
 
-    /**
-     * Used by DeepLinkingBehavior to focus this page's deep links.
-     * @type {!Set<!chromeos.settings.mojom.Setting>}
-     */
-    supportedSettingIds: {
-      type: Object,
-      value: () => new Set([
-        chromeos.settings.mojom.Setting.kPowerIdleBehaviorWhileCharging,
-        chromeos.settings.mojom.Setting.kPowerSource,
-        chromeos.settings.mojom.Setting.kSleepWhenLaptopLidClosed,
-        chromeos.settings.mojom.Setting.kPowerIdleBehaviorWhileOnBattery,
-        chromeos.settings.mojom.Setting.kAdaptiveCharging,
-      ]),
-    },
-  },
+      /** @private {boolean} */
+      shouldAcIdleSelectBeDisabled_: {
+        type: Boolean,
+        computed: 'hasSingleOption_(acIdleOptions_)',
+      },
 
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
+      /** @private {boolean} */
+      shouldBatteryIdleSelectBeDisabled_: {
+        type: Boolean,
+        computed: 'hasSingleOption_(batteryIdleOptions_)',
+      },
+
+      /** @private {boolean} */
+      adaptiveChargingEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isAdaptiveChargingEnabled');
+        },
+      },
+
+      /** @private {!chrome.settingsPrivate.PrefObject} */
+      lidClosedPref_: {
+        type: Object,
+        value() {
+          return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+        },
+      },
+
+      /** @private {!chrome.settingsPrivate.PrefObject} */
+      adaptiveChargingPref_: {
+        type: Object,
+        value() {
+          return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+        },
+      },
+
+      /**
+       * Used by DeepLinkingBehavior to focus this page's deep links.
+       * @type {!Set<!chromeos.settings.mojom.Setting>}
+       */
+      supportedSettingIds: {
+        type: Object,
+        value: () => new Set([
+          chromeos.settings.mojom.Setting.kPowerIdleBehaviorWhileCharging,
+          chromeos.settings.mojom.Setting.kPowerSource,
+          chromeos.settings.mojom.Setting.kSleepWhenLaptopLidClosed,
+          chromeos.settings.mojom.Setting.kPowerIdleBehaviorWhileOnBattery,
+          chromeos.settings.mojom.Setting.kAdaptiveCharging,
+        ]),
+      },
+
+    };
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {?DevicePageBrowserProxy} */
     this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.addWebUIListener(
         'battery-status-changed', this.set.bind(this, 'batteryStatus_'));
     this.addWebUIListener(
@@ -188,7 +210,7 @@
         'power-management-settings-changed',
         this.powerManagementSettingsChanged_.bind(this));
     this.browserProxy_.requestPowerManagementSettings();
-  },
+  }
 
   /**
    * Overridden from DeepLinkingBehavior.
@@ -205,11 +227,11 @@
 
     // Continue with deep link attempt.
     return true;
-  },
+  }
 
   /**
    * @param {!Route} route
-   * @param {Route} oldRoute
+   * @param {!Route=} oldRoute
    */
   currentRouteChanged(route, oldRoute) {
     // Does not apply to this page.
@@ -218,7 +240,7 @@
     }
 
     this.attemptDeepLink();
-  },
+  }
 
   /**
    * @param {!Array<!PowerSource>|undefined} powerSources
@@ -232,7 +254,7 @@
             'calculatingPower' :
             powerSources && powerSources.length ? 'powerSourceLabel' :
                                                   'powerSourceBattery');
-  },
+  }
 
   /**
    * @param {!Array<!PowerSource>} powerSources
@@ -244,7 +266,7 @@
     return powerSources.length > 0 && powerSources.every(function(source) {
       return !source.is_dedicated_charger;
     });
-  },
+  }
 
   /**
    * @param {!Array<!PowerSource>} powerSources
@@ -260,12 +282,12 @@
       return this.i18n('powerSourceAcAdapter');
     }
     return '';
-  },
+  }
 
   /** @private */
   onPowerSourceChange_() {
     this.browserProxy_.setPowerSource(this.$.powerSource.value);
-  },
+  }
 
   /**
    * Used to disable Battery/AC idle select dropdowns.
@@ -275,7 +297,7 @@
    */
   hasSingleOption_(idleOptions) {
     return idleOptions.length === 1;
-  },
+  }
 
   /**
    * @param {!Event} event
@@ -286,15 +308,16 @@
         (parseInt(event.target.value, 10));
     this.browserProxy_.setIdleBehavior(behavior, true /* whenOnAc */);
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onBatteryIdleSelectChange_() {
     const behavior = /** @type {IdleBehavior} */
-        (parseInt(this.$$('#batteryIdleSelect').value, 10));
+        (parseInt(
+            this.shadowRoot.querySelector('#batteryIdleSelect').value, 10));
     this.browserProxy_.setIdleBehavior(behavior, false /* whenOnAc */);
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onLidClosedToggleChange_() {
@@ -304,7 +327,7 @@
         this.$.lidClosedToggle.checked ? LidClosedBehavior.SUSPEND :
                                          LidClosedBehavior.DO_NOTHING);
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onAdaptiveChargingToggleChange_() {
@@ -316,7 +339,7 @@
         /** @type {!chromeos.settings.mojom.SettingChangeValue} */ ({
           boolValue: enabled
         }));
-  },
+  }
 
   /**
    * @param {!Array<PowerSource>} sources External power sources.
@@ -329,7 +352,7 @@
     this.powerSources_ = sources;
     this.selectedPowerSourceId_ = selectedId;
     this.lowPowerCharger_ = lowPowerCharger;
-  },
+  }
 
   /**
    * @param {LidClosedBehavior} behavior Current behavior.
@@ -366,7 +389,7 @@
     }
 
     this.lidClosedPref_ = pref;
-  },
+  }
 
   /**
    * @param {!IdleBehavior} idleBehavior
@@ -411,7 +434,7 @@
       default:
         assertNotReached('Unknown IdleBehavior type');
     }
-  },
+  }
 
   /**
    * @param {!Array<!IdleBehavior>} acIdleBehaviors
@@ -428,7 +451,7 @@
     this.batteryIdleOptions_ = batteryIdleBehaviors.map((idleBehavior) => {
       return this.getIdleOption_(idleBehavior, currBatteryIdleBehavior);
     });
-  },
+  }
 
   /**
    * @param {!PowerManagementSettings} powerManagementSettings Current
@@ -453,7 +476,7 @@
       type: chrome.settingsPrivate.PrefType.BOOLEAN,
       value: powerManagementSettings.adaptiveCharging,
     };
-  },
+  }
 
   /**
    * Returns the row class for the given settings row
@@ -479,7 +502,7 @@
     }
 
     return c;
-  },
+  }
 
   /**
    * @param {*} lhs
@@ -489,5 +512,7 @@
    */
   isEqual_(lhs, rhs) {
     return lhs === rhs;
-  },
-});
+  }
+}
+
+customElements.define(SettingsPowerElement.is, SettingsPowerElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/storage.js b/chrome/browser/resources/settings/chromeos/device_page/storage.js
index 348e9d03..8f344d38 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/storage.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/storage.js
@@ -11,18 +11,16 @@
 import '../../prefs/prefs.js';
 import '../../settings_shared_css.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
-import {focusWithoutInk} from '//resources/js/cr/ui/focus_without_ink.m.js';
 import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Route, Router} from '../../router.js';
 import {routes} from '../os_route.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
-import {RouteOriginBehavior, RouteOriginBehaviorImpl} from '../route_origin_behavior.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
+import {RouteOriginBehavior, RouteOriginBehaviorInterface} from '../route_origin_behavior.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, StorageSpaceState} from './device_page_browser_proxy.js';
 
 /**
  * @typedef {{
@@ -34,65 +32,85 @@
  */
 let StorageSizeStat;
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-storage',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {RouteObserverBehaviorInterface}
+ * @implements {RouteOriginBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsStorageElementBase = mixinBehaviors(
+    [RouteObserverBehavior, RouteOriginBehavior, WebUIListenerBehavior],
+    PolymerElement);
 
-  behaviors: [
-    RouteObserverBehavior,
-    RouteOriginBehavior,
-    WebUIListenerBehavior,
-  ],
+/** @polymer */
+class SettingsStorageElement extends SettingsStorageElementBase {
+  static get is() {
+    return 'settings-storage';
+  }
 
-  properties: {
-    androidEnabled: Boolean,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** @private */
-    showCrostiniStorage_: {
-      type: Boolean,
-      value: false,
-    },
+  static get properties() {
+    return {
+      androidEnabled: Boolean,
 
-    /** @private */
-    showCrostini: Boolean,
+      /** @private */
+      showCrostiniStorage_: {
+        type: Boolean,
+        value: false,
+      },
 
-    /** @private */
-    isGuest_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('isGuest');
-      }
-    },
+      /** @private */
+      showCrostini: Boolean,
 
-    /** @private */
-    showOtherUsers_: {
-      type: Boolean,
-      // Initialize showOtherUsers_ to false if the user is in guest mode.
-      value() {
-        return !loadTimeData.getBoolean('isGuest');
-      }
-    },
+      /** @private */
+      isGuest_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isGuest');
+        }
+      },
 
-    /** @private {StorageSizeStat} */
-    sizeStat_: Object,
-  },
+      /** @private */
+      showOtherUsers_: {
+        type: Boolean,
+        // Initialize showOtherUsers_ to false if the user is in guest mode.
+        value() {
+          return !loadTimeData.getBoolean('isGuest');
+        }
+      },
 
-  /** RouteOriginBehavior override */
-  route_: routes.STORAGE,
+      /** @private {StorageSizeStat} */
+      sizeStat_: Object,
+    };
+  }
 
-  observers: ['handleCrostiniEnabledChanged_(prefs.crostini.enabled.value)'],
+  static get observers() {
+    return ['handleCrostiniEnabledChanged_(prefs.crostini.enabled.value)'];
+  }
 
-  /**
-   * Timer ID for periodic update.
-   * @private {number}
-   */
-  updateTimerId_: -1,
+  constructor() {
+    super();
 
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
+    /** RouteOriginBehavior override */
+    this.route_ = routes.STORAGE;
+    /**
+     * Timer ID for periodic update.
+     * @private {number}
+     */
+    this.updateTimerId_ = -1;
+
+    /** @private {?DevicePageBrowserProxy} */
+    this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.addWebUIListener(
         'storage-size-stat-changed',
         (sizeStat) => this.handleSizeStatChanged_(sizeStat));
@@ -117,31 +135,32 @@
           'storage-system-size-changed',
           (size) => this.handleSystemSizeChanged_(size));
     }
-  },
+  }
 
   ready() {
+    super.ready();
+
     const r = routes;
     this.addFocusConfig(r.CROSTINI_DETAILS, '#crostiniSize');
     this.addFocusConfig(r.ACCOUNTS, '#otherUsersSize');
     this.addFocusConfig(
         r.EXTERNAL_STORAGE_PREFERENCES, '#externalStoragePreferences');
-    this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
+  }
 
   /**
    * RouteObserverBehavior
    * @param {!Route} newRoute
-   * @param {!Route} oldRoute
+   * @param {!Route=} oldRoute
    * @protected
    */
   currentRouteChanged(newRoute, oldRoute) {
-    RouteOriginBehaviorImpl.currentRouteChanged.call(this, newRoute, oldRoute);
+    super.currentRouteChanged(newRoute, oldRoute);
 
     if (Router.getInstance().getCurrentRoute() !== routes.STORAGE) {
       return;
     }
     this.onPageShown_();
-  },
+  }
 
   /** @private */
   onPageShown_() {
@@ -150,7 +169,7 @@
     this.browserProxy_.updateStorageInfo();
     // We update the storage usage periodically when the overlay is visible.
     this.startPeriodicUpdate_();
-  },
+  }
 
   /**
    * Handler for tapping the "My files" item.
@@ -158,7 +177,7 @@
    */
   onMyFilesTap_() {
     this.browserProxy_.openMyFiles();
-  },
+  }
 
   /**
    * Handler for tapping the "Browsing data" item.
@@ -166,7 +185,7 @@
    */
   onBrowsingDataTap_() {
     window.open('chrome://settings/clearBrowserData');
-  },
+  }
 
   /**
    * Handler for tapping the "Apps and Extensions" item.
@@ -174,7 +193,7 @@
    */
   onAppsTap_() {
     window.location = 'chrome://os-settings/app-management';
-  },
+  }
 
   /**
    * Handler for tapping the "Linux storage" item.
@@ -184,7 +203,7 @@
     Router.getInstance().navigateTo(
         routes.CROSTINI_DETAILS, /* dynamicParams */ null,
         /* removeSearch */ true);
-  },
+  }
 
   /**
    * Handler for tapping the "Other users" item.
@@ -194,7 +213,7 @@
     Router.getInstance().navigateTo(
         routes.ACCOUNTS,
         /* dynamicParams */ null, /* removeSearch */ true);
-  },
+  }
 
   /**
    * Handler for tapping the "External storage preferences" item.
@@ -202,7 +221,7 @@
    */
   onExternalStoragePreferencesTap_() {
     Router.getInstance().navigateTo(routes.EXTERNAL_STORAGE_PREFERENCES);
-  },
+  }
 
   /**
    * @param {!StorageSizeStat} sizeStat
@@ -213,7 +232,7 @@
     this.$.inUseLabelArea.style.width = (sizeStat.usedRatio * 100) + '%';
     this.$.availableLabelArea.style.width =
         ((1 - sizeStat.usedRatio) * 100) + '%';
-  },
+  }
 
   /**
    * @param {string} size Formatted string representing the size of My files.
@@ -221,7 +240,7 @@
    */
   handleMyFilesSizeChanged_(size) {
     this.$.myFilesSize.subLabel = size;
-  },
+  }
 
   /**
    * @param {string} size Formatted string representing the size of Browsing
@@ -230,7 +249,7 @@
    */
   handleBrowsingDataSizeChanged_(size) {
     this.$.browsingDataSize.subLabel = size;
-  },
+  }
 
   /**
    * @param {string} size Formatted string representing the size of Apps and
@@ -238,8 +257,8 @@
    * @private
    */
   handleAppsSizeChanged_(size) {
-    this.$$('#appsSize').subLabel = size;
-  },
+    this.shadowRoot.querySelector('#appsSize').subLabel = size;
+  }
 
   /**
    * @param {string} size Formatted string representing the size of Crostini
@@ -248,9 +267,9 @@
    */
   handleCrostiniSizeChanged_(size) {
     if (this.showCrostiniStorage_) {
-      this.$$('#crostiniSize').subLabel = size;
+      this.shadowRoot.querySelector('#crostiniSize').subLabel = size;
     }
-  },
+  }
 
   /**
    * @param {string} size Formatted string representing the size of Other
@@ -265,16 +284,16 @@
       return;
     }
     this.showOtherUsers_ = true;
-    this.$$('#otherUsersSize').subLabel = size;
-  },
+    this.shadowRoot.querySelector('#otherUsersSize').subLabel = size;
+  }
 
   /**
    * @param {string} size Formatted string representing the System size.
    * @private
    */
   handleSystemSizeChanged_(size) {
-    this.$$('#systemSizeSubLabel').innerText = size;
-  },
+    this.shadowRoot.querySelector('#systemSizeSubLabel').innerText = size;
+  }
 
   /**
    * @param {boolean} enabled True if Crostini is enabled.
@@ -282,7 +301,7 @@
    */
   handleCrostiniEnabledChanged_(enabled) {
     this.showCrostiniStorage_ = enabled && this.showCrostini;
-  },
+  }
 
   /**
    * Starts periodic update for storage usage.
@@ -299,7 +318,7 @@
         this.browserProxy_.updateStorageInfo();
       }, 5000);
     }
-  },
+  }
 
   /**
    * Stops periodic update for storage usage.
@@ -310,7 +329,7 @@
       window.clearInterval(this.updateTimerId_);
       this.updateTimerId_ = -1;
     }
-  },
+  }
 
   /**
    * Returns true if the remaining space is low, but not critically low.
@@ -320,7 +339,7 @@
    */
   isSpaceLow_(spaceState) {
     return spaceState === StorageSpaceState.LOW;
-  },
+  }
 
   /**
    * Returns true if the remaining space is critically low.
@@ -330,7 +349,7 @@
    */
   isSpaceCriticallyLow_(spaceState) {
     return spaceState === StorageSpaceState.CRITICALLY_LOW;
-  },
+  }
 
   /**
    * Computes class name of the bar based on the remaining space size.
@@ -347,5 +366,7 @@
       default:
         return '';
     }
-  },
-});
+  }
+}
+
+customElements.define(SettingsStorageElement.is, SettingsStorageElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/storage_external.js b/chrome/browser/resources/settings/chromeos/device_page/storage_external.js
index 0fe7ab5c0..d65b463 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/storage_external.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/storage_external.js
@@ -13,57 +13,71 @@
 import '../../prefs/prefs.js';
 import '../../settings_shared_css.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, getDisplayApi, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, StorageSpaceState} from './device_page_browser_proxy.js';
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage} from './device_page_browser_proxy.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-storage-external',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ * @implements {WebUIListenerBehaviorInterface}
+ */
+const SettingsStorageExternalElementBase =
+    mixinBehaviors([I18nBehavior, WebUIListenerBehavior], PolymerElement);
 
-  behaviors: [
-    I18nBehavior,
-    WebUIListenerBehavior,
-  ],
+/** @polymer */
+class SettingsStorageExternalElement extends
+    SettingsStorageExternalElementBase {
+  static get is() {
+    return 'settings-storage-external';
+  }
 
-  properties: {
-    /**
-     * List of the plugged-in external storages.
-     * @private {Array<!ExternalStorage>}
-     */
-    externalStorages_: {
-      type: Array,
-      value() {
-        return [];
-      }
-    },
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /** @private {!chrome.settingsPrivate.PrefObject} */
-    externalStorageVisiblePref_: {
-      type: Object,
-      value() {
-        return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+  static get properties() {
+    return {
+      /**
+       * List of the plugged-in external storages.
+       * @private {Array<!ExternalStorage>}
+       */
+      externalStorages_: {
+        type: Array,
+        value() {
+          return [];
+        }
       },
-    },
-  },
 
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
+      /** @private {!chrome.settingsPrivate.PrefObject} */
+      externalStorageVisiblePref_: {
+        type: Object,
+        value() {
+          return /** @type {!chrome.settingsPrivate.PrefObject} */ ({});
+        },
+      },
+    };
+  }
 
   /** @override */
-  created() {
+  constructor() {
+    super();
+
+    /** @private {?DevicePageBrowserProxy} */
     this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
+  }
 
   /** @override */
-  attached() {
+  connectedCallback() {
+    super.connectedCallback();
+
     this.browserProxy_.setExternalStoragesUpdatedCallback(
         this.handleExternalStoragesUpdated_.bind(this));
     this.browserProxy_.updateExternalStorages();
-  },
+  }
 
   /**
    * @param {Array<!ExternalStorage>} storages
@@ -71,7 +85,7 @@
    */
   handleExternalStoragesUpdated_(storages) {
     this.externalStorages_ = storages;
-  },
+  }
 
   /**
    * @param {Array<!ExternalStorage>} externalStorages
@@ -83,5 +97,8 @@
         !externalStorages || externalStorages.length === 0 ?
             'storageExternalStorageEmptyListHeader' :
             'storageExternalStorageListHeader');
-  },
-});
+  }
+}
+
+customElements.define(
+    SettingsStorageExternalElement.is, SettingsStorageExternalElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/storage_external_entry.js b/chrome/browser/resources/settings/chromeos/device_page/storage_external_entry.js
index 307cbea..d6cf683e 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/storage_external_entry.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/storage_external_entry.js
@@ -11,41 +11,58 @@
 import '../../prefs/prefs.js';
 import '../../settings_shared_css.js';
 
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
-import {WebUIListenerBehavior} from '//resources/js/web_ui_listener_behavior.m.js';
-import {afterNextRender, flush, html, Polymer, TemplateInstanceBase, Templatizer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/js/web_ui_listener_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {PrefsBehavior} from '../prefs_behavior.js';
+import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs_behavior.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'storage-external-entry',
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {WebUIListenerBehaviorInterface}
+ * @implements {PrefsBehaviorInterface}
+ */
+const StorageExternalEntryElementBase =
+    mixinBehaviors([WebUIListenerBehavior, PrefsBehavior], PolymerElement);
 
-  behaviors: [WebUIListenerBehavior, PrefsBehavior],
+/** @polymer */
+class StorageExternalEntryElement extends StorageExternalEntryElementBase {
+  static get is() {
+    return 'storage-external-entry';
+  }
 
-  properties: {
-    /**
-     * FileSystem UUID of an external storage.
-     */
-    uuid: String,
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /**
-     * Label of an external storage.
-     */
-    label: String,
+  static get properties() {
+    return {
+      /**
+       * FileSystem UUID of an external storage.
+       */
+      uuid: String,
 
-    /** @private {chrome.settingsPrivate.PrefObject} */
-    visiblePref_: {
-      type: Object,
-      value() {
-        return /** @type {chrome.settingsPrivate.PrefObject} */ ({});
+      /**
+       * Label of an external storage.
+       */
+      label: String,
+
+      /** @private {chrome.settingsPrivate.PrefObject} */
+      visiblePref_: {
+        type: Object,
+        value() {
+          return /** @type {chrome.settingsPrivate.PrefObject} */ ({});
+        },
       },
-    },
-  },
 
-  observers: [
-    'updateVisible_(prefs.arc.visible_external_storages.*)',
-  ],
+    };
+  }
+
+  static get observers() {
+    return [
+      'updateVisible_(prefs.arc.visible_external_storages.*)',
+    ];
+  }
 
   /**
    * Handler for when the toggle button for this entry is clicked by a user.
@@ -61,7 +78,7 @@
     }
     chrome.metricsPrivate.recordBoolean(
         'Arc.ExternalStorage.SetVisible', visible);
-  },
+  }
 
   /**
    * Updates |visiblePref_| by reading the preference and check if it contains
@@ -78,5 +95,8 @@
       value: visible,
     };
     this.visiblePref_ = pref;
-  },
-});
+  }
+}
+
+customElements.define(
+    StorageExternalEntryElement.is, StorageExternalEntryElement);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/stylus.js b/chrome/browser/resources/settings/chromeos/device_page/stylus.js
index a3a077c..691eb75 100644
--- a/chrome/browser/resources/settings/chromeos/device_page/stylus.js
+++ b/chrome/browser/resources/settings/chromeos/device_page/stylus.js
@@ -7,116 +7,147 @@
  * 'settings-stylus' is the settings subpage with stylus-specific settings.
  */
 
-const FIND_MORE_APPS_URL = 'https://play.google.com/store/apps/' +
-    'collection/promotion_30023cb_stylus_apps';
-
-import {afterNextRender, Polymer, html, flush, Templatizer, TemplateInstanceBase} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {assert, assertNotReached} from '//resources/js/assert.m.js';
 import '//resources/cr_elements/cr_link_row/cr_link_row.js';
 import '//resources/cr_elements/cr_toggle/cr_toggle.m.js';
 import '//resources/cr_elements/shared_vars_css.m.js';
 import '//resources/js/action_link.js';
 import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
-import {CrPolicyIndicatorType} from '//resources/cr_elements/policy/cr_policy_indicator_behavior.m.js';
-import {I18nBehavior} from '//resources/js/i18n_behavior.m.js';
-import {loadTimeData} from '//resources/js/load_time_data.m.js';
-import {BatteryStatus, DevicePageBrowserProxy, DevicePageBrowserProxyImpl, ExternalStorage, IdleBehavior, LidClosedBehavior, NoteAppInfo, NoteAppLockScreenSupport, PowerManagementSettings, PowerSource, getDisplayApi, StorageSpaceState} from './device_page_browser_proxy.js';
 import '../../controls/settings_toggle_button.js';
 import '../../settings_shared_css.js';
-import {Router, Route} from '../../router.js';
-import {RouteObserverBehavior} from '../route_observer_behavior.js';
-import {routes} from '../os_route.js';
+
+import {CrPolicyIndicatorType} from '//resources/cr_elements/policy/cr_policy_indicator_behavior.m.js';
+import {assert} from '//resources/js/assert.m.js';
+import {loadTimeData} from '//resources/js/load_time_data.m.js';
+import {html, microTask, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Route} from '../../router.js';
+import {DeepLinkingBehavior, DeepLinkingBehaviorInterface} from '../deep_linking_behavior.js';
 import {recordSettingChange} from '../metrics_recorder.js';
-import {DeepLinkingBehavior} from '../deep_linking_behavior.js';
+import {routes} from '../os_route.js';
+import {RouteObserverBehavior, RouteObserverBehaviorInterface} from '../route_observer_behavior.js';
 
-Polymer({
-  _template: html`{__html_template__}`,
-  is: 'settings-stylus',
+import {DevicePageBrowserProxy, DevicePageBrowserProxyImpl, NoteAppInfo, NoteAppLockScreenSupport} from './device_page_browser_proxy.js';
 
-  behaviors: [
-    DeepLinkingBehavior,
-    RouteObserverBehavior,
-  ],
+const FIND_MORE_APPS_URL = 'https://play.google.com/store/apps/' +
+    'collection/promotion_30023cb_stylus_apps';
 
-  properties: {
-    /** Preferences state. */
-    prefs: {
-      type: Object,
-      notify: true,
-    },
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {DeepLinkingBehaviorInterface}
+ * @implements {RouteObserverBehaviorInterface}
+ */
+const SettingsStylusElementBase = mixinBehaviors(
+    [DeepLinkingBehavior, RouteObserverBehavior], PolymerElement);
 
-    /**
-     * Policy indicator type for user policy - used for policy indicator UI
-     * shown when an app that is not allowed to run on lock screen by policy is
-     * selected.
-     * @type {CrPolicyIndicatorType}
-     * @private
-     */
-    userPolicyIndicator_: {
-      type: String,
-      value: CrPolicyIndicatorType.USER_POLICY,
-    },
+/** @polymer */
+class SettingsStylusElement extends SettingsStylusElementBase {
+  static get is() {
+    return 'settings-stylus';
+  }
 
-    /**
-     * Note taking apps the user can pick between.
-     * @private {Array<!NoteAppInfo>}
-     */
-    appChoices_: {
-      type: Array,
-      value() {
-        return [];
-      }
-    },
+  static get template() {
+    return html`{__html_template__}`;
+  }
 
-    /**
-     * True if the device has an internal stylus.
-     * @private
-     */
-    hasInternalStylus_: {
-      type: Boolean,
-      value() {
-        return loadTimeData.getBoolean('hasInternalStylus');
+  static get properties() {
+    return {
+      /** Preferences state. */
+      prefs: {
+        type: Object,
+        notify: true,
       },
-      readOnly: true,
-    },
 
-    /**
-     * Currently selected note taking app.
-     * @private {?NoteAppInfo}
-     */
-    selectedApp_: {
-      type: Object,
-      value: null,
-    },
+      /**
+       * Policy indicator type for user policy - used for policy indicator UI
+       * shown when an app that is not allowed to run on lock screen by policy
+       * is selected.
+       * @type {CrPolicyIndicatorType}
+       * @private
+       */
+      userPolicyIndicator_: {
+        type: String,
+        value: CrPolicyIndicatorType.USER_POLICY,
+      },
 
-    /**
-     * True if the ARC container has not finished starting yet.
-     * @private
-     */
-    waitingForAndroid_: {
-      type: Boolean,
-      value: false,
-    },
+      /**
+       * Note taking apps the user can pick between.
+       * @private {Array<!NoteAppInfo>}
+       */
+      appChoices_: {
+        type: Array,
+        value() {
+          return [];
+        }
+      },
 
-    /**
-     * Used by DeepLinkingBehavior to focus this page's deep links.
-     * @type {!Set<!chromeos.settings.mojom.Setting>}
-     */
-    supportedSettingIds: {
-      type: Object,
-      value: () => new Set([
-        chromeos.settings.mojom.Setting.kStylusToolsInShelf,
-        chromeos.settings.mojom.Setting.kStylusNoteTakingApp,
-        chromeos.settings.mojom.Setting.kStylusNoteTakingFromLockScreen,
-        chromeos.settings.mojom.Setting.kStylusLatestNoteOnLockScreen,
-      ]),
-    },
-  },
+      /**
+       * True if the device has an internal stylus.
+       * @private
+       */
+      hasInternalStylus_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('hasInternalStylus');
+        },
+        readOnly: true,
+      },
+
+      /**
+       * Currently selected note taking app.
+       * @private {?NoteAppInfo}
+       */
+      selectedApp_: {
+        type: Object,
+        value: null,
+      },
+
+      /**
+       * True if the ARC container has not finished starting yet.
+       * @private
+       */
+      waitingForAndroid_: {
+        type: Boolean,
+        value: false,
+      },
+
+      /**
+       * Used by DeepLinkingBehavior to focus this page's deep links.
+       * @type {!Set<!chromeos.settings.mojom.Setting>}
+       */
+      supportedSettingIds: {
+        type: Object,
+        value: () => new Set([
+          chromeos.settings.mojom.Setting.kStylusToolsInShelf,
+          chromeos.settings.mojom.Setting.kStylusNoteTakingApp,
+          chromeos.settings.mojom.Setting.kStylusNoteTakingFromLockScreen,
+          chromeos.settings.mojom.Setting.kStylusLatestNoteOnLockScreen,
+        ]),
+      },
+
+    };
+  }
+
+  /** @override */
+  constructor() {
+    super();
+
+    /** @private {?DevicePageBrowserProxy} */
+    this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
+  }
+
+  /** @override */
+  ready() {
+    super.ready();
+
+    this.browserProxy_.setNoteTakingAppsUpdatedCallback(
+        this.onNoteAppsUpdated_.bind(this));
+    this.browserProxy_.requestNoteTakingApps();
+  }
 
   /**
    * @param {!Route} route
-   * @param {Route} oldRoute
+   * @param {!Route=} oldRoute
    */
   currentRouteChanged(route, oldRoute) {
     // Does not apply to this page.
@@ -125,7 +156,7 @@
     }
 
     this.attemptDeepLink();
-  },
+  }
 
   /**
    * @return {boolean} Whether note taking from the lock screen is supported
@@ -136,7 +167,7 @@
     return !!this.selectedApp_ &&
         this.selectedApp_.lockScreenSupport !==
         NoteAppLockScreenSupport.NOT_SUPPORTED;
-  },
+  }
 
   /**
    * @return {boolean} Whether the selected app is disallowed to handle note
@@ -147,7 +178,7 @@
     return !!this.selectedApp_ &&
         this.selectedApp_.lockScreenSupport ===
         NoteAppLockScreenSupport.NOT_ALLOWED_BY_POLICY;
-  },
+  }
 
   /**
    * @return {boolean} Whether the selected app is enabled as a note action
@@ -158,22 +189,7 @@
     return !!this.selectedApp_ &&
         this.selectedApp_.lockScreenSupport ===
         NoteAppLockScreenSupport.ENABLED;
-  },
-
-  /** @private {?DevicePageBrowserProxy} */
-  browserProxy_: null,
-
-  /** @override */
-  created() {
-    this.browserProxy_ = DevicePageBrowserProxyImpl.getInstance();
-  },
-
-  /** @override */
-  ready() {
-    this.browserProxy_.setNoteTakingAppsUpdatedCallback(
-        this.onNoteAppsUpdated_.bind(this));
-    this.browserProxy_.requestNoteTakingApps();
-  },
+  }
 
   /**
    * Finds note app info with the provided app id.
@@ -186,7 +202,7 @@
       return app.value === id;
     }) ||
         null;
-  },
+  }
 
   /**
    * Toggles whether the selected app is enabled as a note action handler on
@@ -206,7 +222,7 @@
         this.selectedApp_.lockScreenSupport ===
         NoteAppLockScreenSupport.SUPPORTED);
     recordSettingChange();
-  },
+  }
 
   /** @private */
   onSelectedAppChanged_() {
@@ -217,7 +233,7 @@
       this.browserProxy_.setPreferredNoteTakingApp(app.value);
       recordSettingChange();
     }
-  },
+  }
 
   /**
    * @param {Array<!NoteAppInfo>} apps
@@ -229,8 +245,8 @@
     this.appChoices_ = apps;
 
     // Wait until app selection UI is updated before setting the selected app.
-    this.async(this.onSelectedAppChanged_.bind(this));
-  },
+    microTask.run(this.onSelectedAppChanged_.bind(this));
+  }
 
   /**
    * @param {Array<!NoteAppInfo>} apps
@@ -239,7 +255,7 @@
    */
   showNoApps_(apps, waitingForAndroid) {
     return apps.length === 0 && !waitingForAndroid;
-  },
+  }
 
   /**
    * @param {Array<!NoteAppInfo>} apps
@@ -248,10 +264,12 @@
    */
   showApps_(apps, waitingForAndroid) {
     return apps.length > 0 && !waitingForAndroid;
-  },
+  }
 
   /** @private */
   onFindAppsTap_() {
     this.browserProxy_.showPlayStore(FIND_MORE_APPS_URL);
-  },
-});
+  }
+}
+
+customElements.define(SettingsStylusElement.is, SettingsStylusElement);
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html
index 57640f8..0cd079c2 100644
--- a/chrome/browser/resources/settings/icons.html
+++ b/chrome/browser/resources/settings/icons.html
@@ -112,6 +112,8 @@
       <g id="devices"><path d="M5 6h16V4H5c-1.1 0-2 .9-2 2v11H1v3h11v-3H5V6zm16 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"></path></g>
       <g id="devices-off"><path d="M22 9V19L20 17V10H16V13L14 11V9C14 8.45 14.45 8 15 8H21C21.55 8 22 8.45 22 9ZM21 6V4H7L9 6H21ZM17.2 17L16 15.8L14 13.8L6.2 6L4.33 4.13L2.6 2.4L1.2 3.8L3.06 5.66C3.03 5.77 3 5.88 3 6V17H1V20H12V17H5V7.6L14 16.6V19C14 19.55 14.45 20 15 20H17.4L20.4 23L21.8 21.6L20.2 20L17.2 17Z"></path></g>
       <g id="exit-to-app"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path></g>
+      <g id="federated-identity-api"><path d="M5.85,17.1q1.275,-0.975 2.85,-1.538Q10.275,15 12,15q1.725,0 3.3,0.563 1.575,0.562 2.85,1.537 0.875,-1.025 1.363,-2.325Q20,13.475 20,12q0,-3.325 -2.337,-5.662Q15.325,4 12,4T6.338,6.338Q4,8.675 4,12q0,1.475 0.487,2.775 0.488,1.3 1.363,2.325zM12,13q-1.475,0 -2.488,-1.012Q8.5,10.975 8.5,9.5t1.012,-2.487Q10.525,6 12,6t2.488,1.013Q15.5,8.024 15.5,9.5t-1.012,2.488Q13.475,13 12,13zM12,22q-2.075,0 -3.9,-0.788 -1.825,-0.787 -3.175,-2.137 -1.35,-1.35 -2.137,-3.175Q2,14.075 2,12t0.788,-3.9q0.787,-1.825 2.137,-3.175 1.35,-1.35 3.175,-2.137Q9.925,2 12,2t3.9,0.788q1.825,0.787 3.175,2.137 1.35,1.35 2.137,3.175Q22,9.925 22,12t-0.788,3.9q-0.787,1.825 -2.137,3.175 -1.35,1.35 -3.175,2.137Q14.075,22 12,22zM12,20q1.325,0 2.5,-0.387 1.175,-0.388 2.15,-1.113 -0.975,-0.725 -2.15,-1.113Q13.325,17 12,17t-2.5,0.387q-1.175,0.388 -2.15,1.113 0.975,0.725 2.15,1.113Q10.675,20 12,20zM12,11q0.65,0 1.075,-0.425 0.425,-0.425 0.425,-1.075 0,-0.65 -0.425,-1.075Q12.65,8 12,8q-0.65,0 -1.075,0.425Q10.5,8.85 10.5,9.5q0,0.65 0.425,1.075Q11.35,11 12,11zM12,9.5zM12,18.5z"></path></g>
+      <g id="federated-identity-api-off"><path d="M14.41 9.41l.97.97s.12.02.12-.88C15.5 7.56 13.94 6 12 6c-.89 0-.88.12-.88.12l.47.47 2.82 2.82zM19.99 18c1.26-1.67 2.01-3.75 2.01-6 0-5.52-4.48-10-10-10-2.25 0-4.32.75-5.99 2.01-.01 0-.02.01-.02.01-.25.19-.49.39-.73.61-.01.01-.03.02-.04.04-.23.21-.45.43-.66.67-.01.01-.02.01-.03.02C2.96 7.13 2 9.45 2 12c0 5.52 4.48 10 10 10 2.55 0 4.87-.96 6.64-2.53l.03-.03c.23-.21.45-.43.66-.65.01-.02.03-.03.04-.05.21-.23.41-.47.6-.72l.02-.02zM12 4c4.41 0 8 3.59 8 8 0 1.7-.55 3.27-1.45 4.56l-3.72-3.72-.63-.63L9.3 7.3l-.13-.13-1.73-1.73C8.73 4.53 10.3 4 12 4zm0 16c-1.86 0-3.57-.64-4.93-1.72.43-.9 3.05-1.78 4.93-1.78s4.51.88 4.93 1.78C15.57 19.36 13.86 20 12 20zm0-5.5c-1.46 0-4.93.59-6.36 2.33C4.62 15.49 4 13.82 4 12c0-1.99.74-3.82 1.95-5.22l2.56 2.56c0 .05-.02.1-.02.15 0 1.94 1.56 3.5 3.5 3.5.05 0 .1-.01.15-.02l1.72 1.72c-.72-.12-1.4-.19-1.86-.19z"></path></g>
       <g id="file-download-off"><path d="M15.6 12.4L9 5.8V3H15V9H19L15.6 12.4ZM5 20H18.4V19.5L19 19L19.5 18.5L12.7 11.7L9 7.9L5.6 4.5L4.5 5.6L7.9 9H5L12 16L13.5 14.5L17 18H5V20Z"></path></g>
       <g id="file-editing-off"><path d="M19.5,16.67l1.09-1.09L22,17l-1.09,1.09L19.5,16.67z M17,14.17L17,13h2l0,3.17L17,14.17z M2.1,2.1L0.69,3.51l3.32,3.32L4,18 c0,1.1,0.89,2,1.99,2H12v-2H6V8.83L19.17,22H14v2h8v-2L2.1,2.1z M6.83,4H12v5h5v2h2V8l-6-6H6C5.66,2,5.34,2.09,5.06,2.24L6.83,4z"></path></g>
       <g id="hid-device"><path d="M20 6H4C2.9 6 2 6.9 2 8V16C2 17.1 2.9 18 4 18H20C21.1 18 22 17.1 22 16V8C22 6.9 21.1 6 20 6ZM11 13H9V15H7V13H5V11H7V9H9V11H11V13ZM14.5 15C13.67 15 13 14.33 13 13.5C13 12.67 13.67 12 14.5 12C15.33 12 16 12.67 16 13.5C16 14.33 15.33 15 14.5 15ZM17.5 12C16.67 12 16 11.33 16 10.5C16 9.67 16.67 9 17.5 9C18.33 9 19 9.67 19 10.5C19 11.33 18.33 12 17.5 12Z"></path></g>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 351d46a..248f9d9 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -317,6 +317,36 @@
           </category-setting-exceptions>
         </settings-subpage>
       </template>
+      <template is="dom-if" if="[[enableFederatedIdentityApiContentSetting_]]">
+        <template is="dom-if" route-path="/content/federatedIdentityApi"
+            no-search>
+          <settings-subpage
+              page-title="$i18n{siteSettingsCategoryFederatedIdentityApi}"
+              search-label="$i18n{siteSettingsAllSitesSearch}"
+              search-term="{{searchFilter_}}">
+            <div class="content-settings-header secondary">
+              $i18n{siteSettingsFederatedIdentityApiDescription}
+            </div>
+            <settings-category-default-radio-group
+                category="[[contentSettingsTypesEnum_.FEDERATED_IDENTITY_API]]"
+                allow-option-label=
+                    "$i18n{siteSettingsFederatedIdentityApiAllowed}"
+                allow-option-icon="settings:federated-identity-api"
+                block-option-label=
+                    "$i18n{siteSettingsFederatedIdentityApiBlocked}"
+                block-option-icon="settings:federated-identity-api-off">
+            </settings-category-default-radio-group>
+            <category-setting-exceptions
+                category="[[contentSettingsTypesEnum_.FEDERATED_IDENTITY_API]]"
+                allow-header=
+                    "$i18n{siteSettingsFederatedIdentityApiAllowedExceptions}"
+                block-header=
+                    "$i18n{siteSettingsFederatedIdentityApiBlockedExceptions}"
+                search-filter="[[searchFilter_]]">
+            </category-setting-exceptions>
+          </settings-subpage>
+        </template>
+      </template>
       <template is="dom-if" route-path="/content/location" no-search>
         <settings-subpage page-title="$i18n{siteSettingsCategoryLocation}"
             search-label="$i18n{siteSettingsAllSitesSearch}"
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
index a849f64..3fadced 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.ts
@@ -129,6 +129,14 @@
         }
       },
 
+      enableFederatedIdentityApiContentSetting_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean(
+              'enableFederatedIdentityApiContentSetting');
+        }
+      },
+
       enableExperimentalWebPlatformFeatures_: {
         type: Boolean,
         value() {
@@ -244,6 +252,7 @@
   private cookieSettingDescription_: string;
   private enableBlockAutoplayContentSetting_: boolean;
   private blockAutoplayStatus_: BlockAutoplayStatus;
+  private enableFederatedIdentityApiContentSetting_: boolean;
   private enablePaymentHandlerContentSetting_: boolean;
   private enableExperimentalWebPlatformFeatures_: boolean;
   private enableSecurityKeysSubpage_: boolean;
diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts
index a4a48ec1..fdba8d4 100644
--- a/chrome/browser/resources/settings/route.ts
+++ b/chrome/browser/resources/settings/route.ts
@@ -86,6 +86,10 @@
     r.SITE_SETTINGS_PAYMENT_HANDLER =
         r.SITE_SETTINGS.createChild('paymentHandler');
   }
+  if (loadTimeData.getBoolean('enableFederatedIdentityApiContentSetting')) {
+    r.SITE_SETTINGS_FEDERATED_IDENTITY_API =
+        r.SITE_SETTINGS.createChild('federatedIdentityApi');
+  }
   r.SITE_SETTINGS_VR = r.SITE_SETTINGS.createChild('vr');
   if (loadTimeData.getBoolean('enableExperimentalWebPlatformFeatures')) {
     r.SITE_SETTINGS_BLUETOOTH_SCANNING =
diff --git a/chrome/browser/resources/settings/settings_routes.ts b/chrome/browser/resources/settings/settings_routes.ts
index 44e70ccc..a990b44 100644
--- a/chrome/browser/resources/settings/settings_routes.ts
+++ b/chrome/browser/resources/settings/settings_routes.ts
@@ -59,6 +59,7 @@
   SITE_SETTINGS_CLIPBOARD: Route,
   SITE_SETTINGS_COOKIES: Route,
   SITE_SETTINGS_DATA_DETAILS: Route,
+  SITE_SETTINGS_FEDERATED_IDENTITY_API: Route,
   SITE_SETTINGS_HANDLERS: Route,
   SITE_SETTINGS_HID_DEVICES: Route,
   SITE_SETTINGS_IDLE_DETECTION: Route,
diff --git a/chrome/browser/resources/settings/site_settings/category_default_setting.ts b/chrome/browser/resources/settings/site_settings/category_default_setting.ts
index b09a0b3..3d61376 100644
--- a/chrome/browser/resources/settings/site_settings/category_default_setting.ts
+++ b/chrome/browser/resources/settings/site_settings/category_default_setting.ts
@@ -185,6 +185,7 @@
     switch (this.category) {
       case ContentSettingsTypes.ADS:
       case ContentSettingsTypes.BACKGROUND_SYNC:
+      case ContentSettingsTypes.FEDERATED_IDENTITY_API:
       case ContentSettingsTypes.IMAGES:
       case ContentSettingsTypes.JAVASCRIPT:
       case ContentSettingsTypes.MIXEDSCRIPT:
diff --git a/chrome/browser/resources/settings/site_settings/constants.ts b/chrome/browser/resources/settings/site_settings/constants.ts
index 2e34d96..38fb1216 100644
--- a/chrome/browser/resources/settings/site_settings/constants.ts
+++ b/chrome/browser/resources/settings/site_settings/constants.ts
@@ -19,6 +19,7 @@
   CAMERA = 'media-stream-camera',
   CLIPBOARD = 'clipboard',
   COOKIES = 'cookies',
+  FEDERATED_IDENTITY_API = 'federated-identity-api',
   FILE_SYSTEM_WRITE = 'file-system-write',
   GEOLOCATION = 'location',
   HID_DEVICES = 'hid-devices',
diff --git a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
index 8fc8257..20b4556 100644
--- a/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
+++ b/chrome/browser/resources/settings/site_settings/settings_category_default_radio_group.ts
@@ -129,6 +129,7 @@
     switch (this.category) {
       case ContentSettingsTypes.ADS:
       case ContentSettingsTypes.BACKGROUND_SYNC:
+      case ContentSettingsTypes.FEDERATED_IDENTITY_API:
       case ContentSettingsTypes.IMAGES:
       case ContentSettingsTypes.JAVASCRIPT:
       case ContentSettingsTypes.MIXEDSCRIPT:
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index bb2a12d..f4688ce 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -198,6 +198,11 @@
           icon="settings:insecure-content"
           label="$i18n{siteSettingsInsecureContent}">
       </site-details-permission>
+      <site-details-permission
+          category="[[contentSettingsTypesEnum_.FEDERATED_IDENTITY_API]]"
+          icon="settings:federated-identity-api"
+          label="$i18n{siteSettingsFederatedIdentityApi}">
+      </site-details-permission>
       <site-details-permission category="[[contentSettingsTypesEnum_.AR]]"
           icon="settings:vr-headset" label="$i18n{siteSettingsAr}">
       </site-details-permission>
diff --git a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.ts b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.ts
index 836805a..70011fb 100644
--- a/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.ts
+++ b/chrome/browser/resources/settings/site_settings_page/recent_site_permissions.ts
@@ -179,6 +179,8 @@
         return this.i18n('siteSettingsPaymentHandlerMidSentence');
       case ContentSettingsTypes.MIXEDSCRIPT:
         return this.i18n('siteSettingsInsecureContentMidSentence');
+      case ContentSettingsTypes.FEDERATED_IDENTITY_API:
+        return this.i18n('siteSettingsFederatedIdentityApiMidSentence');
       case ContentSettingsTypes.BLUETOOTH_SCANNING:
         return this.i18n('siteSettingsBluetoothScanningMidSentence');
       case ContentSettingsTypes.FILE_SYSTEM_WRITE:
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
index 5edd5c2..0a018930 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
@@ -184,6 +184,16 @@
       disabledLabel: 'siteSettingsInsecureContentBlock',
     },
     {
+      route: routes.SITE_SETTINGS_FEDERATED_IDENTITY_API,
+      id: Id.FEDERATED_IDENTITY_API,
+      label: 'siteSettingsFederatedIdentityApi',
+      icon: 'settings:federated-identity-api',
+      enabledLabel: 'siteSettingsFederatedIdentityApiAllowed',
+      disabledLabel: 'siteSettingsFederatedIdentityApiBlocked',
+      shouldShow: () =>
+          loadTimeData.getBoolean('enableFederatedIdentityApiContentSetting'),
+    },
+    {
       route: routes.SITE_SETTINGS_FILE_SYSTEM_WRITE,
       id: Id.FILE_SYSTEM_WRITE,
       label: 'siteSettingsFileSystemWrite',
@@ -385,6 +395,7 @@
               Id.PDF_DOCUMENTS,
               Id.PROTECTED_CONTENT,
               Id.MIXEDSCRIPT,
+              Id.FEDERATED_IDENTITY_API,
             ]),
           };
         }
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 6b3ec6ac..29b02ef 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
@@ -284,7 +284,7 @@
 
 void CollectDomainEnrollmentData(
     ClientIncidentReport_EnvironmentData_OS* os_data) {
-  os_data->set_is_enrolled_to_domain(base::IsMachineExternallyManaged());
+  os_data->set_is_enrolled_to_domain(base::IsEnterpriseDevice());
 }
 
 void CollectPlatformProcessData(
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
index 7ae4f94..17c9b40 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service_unittest.cc
@@ -46,6 +46,12 @@
 #include "base/test/test_reg_util_win.h"
 #endif
 
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+#include "chrome/browser/supervised_user/supervised_user_metrics_service_factory.h"
+#endif
+
 // A test fixture that sets up a test task runner and makes it the thread's
 // runner. The fixture implements a fake environment data collector, extension
 // data collector and a fake report uploader.
@@ -272,6 +278,14 @@
         profile_name, std::move(prefs), base::ASCIIToUTF16(profile_name),
         0,  // avatar_id (unused)
         TestingProfile::TestingFactories());
+
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+    // Disable supervised user metrics reporting, otherwise the calls to
+    // FastForwardUntilNoTasksRemain() never return.
+    SupervisedUserMetricsServiceFactory::GetForBrowserContext(profile)
+        ->Shutdown();
+#endif
+
     mock_time_task_runner_->FastForwardUntilNoTasksRemain();
 
     return profile;
diff --git a/chrome/browser/safety_check/android/BUILD.gn b/chrome/browser/safety_check/android/BUILD.gn
index d7460fe2..9c5b0d2 100644
--- a/chrome/browser/safety_check/android/BUILD.gn
+++ b/chrome/browser/safety_check/android/BUILD.gn
@@ -76,7 +76,6 @@
   sources = [ "javatests/src/org/chromium/chrome/browser/safety_check/SafetyCheckSettingsFragmentTest.java" ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base/test:test_support_java",
     "//chrome/browser/password_check:public_java",
diff --git a/chrome/browser/segmentation_platform/BUILD.gn b/chrome/browser/segmentation_platform/BUILD.gn
index ff27073..e543c1c7 100644
--- a/chrome/browser/segmentation_platform/BUILD.gn
+++ b/chrome/browser/segmentation_platform/BUILD.gn
@@ -12,7 +12,6 @@
     sources = [ "android/java/src/org/chromium/chrome/browser/segmentation_platform/SegmentationPlatformServiceFactory.java" ]
 
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
       "//chrome/browser/profiles/android:java",
diff --git a/chrome/browser/settings/BUILD.gn b/chrome/browser/settings/BUILD.gn
index baf3a8aa..0e102519 100644
--- a/chrome/browser/settings/BUILD.gn
+++ b/chrome/browser/settings/BUILD.gn
@@ -51,7 +51,6 @@
   sources = [ "android/java/src/org/chromium/chrome/browser/settings/SettingsActivityTestRule.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/android:chrome_java",
     "//chrome/browser/settings:java",
diff --git a/chrome/browser/signin/services/android/BUILD.gn b/chrome/browser/signin/services/android/BUILD.gn
index acc5e6e5..b3ef5b7c 100644
--- a/chrome/browser/signin/services/android/BUILD.gn
+++ b/chrome/browser/signin/services/android/BUILD.gn
@@ -92,7 +92,6 @@
   deps = [
     ":java",
     ":java_resources",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/speech/speech_recognition_service_browsertest.cc b/chrome/browser/speech/speech_recognition_service_browsertest.cc
index 885e241..2641fa1c 100644
--- a/chrome/browser/speech/speech_recognition_service_browsertest.cc
+++ b/chrome/browser/speech/speech_recognition_service_browsertest.cc
@@ -40,6 +40,7 @@
 #include "sandbox/policy/switches.h"
 #include "services/audio/public/cpp/fake_stream_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <windows.h>
@@ -90,7 +91,7 @@
     base::SyncSocket socket1, socket2;
     base::SyncSocket::CreatePair(&socket1, &socket2);
     std::move(created_callback)
-        .Run({base::in_place,
+        .Run({absl::in_place,
               base::ReadOnlySharedMemoryRegion::Create(kShMemSize).region,
               mojo::PlatformHandle(socket1.Take())},
              false /*initially muted*/, base::UnguessableToken::Create());
diff --git a/chrome/browser/ssl/chrome_security_blocking_page_factory.cc b/chrome/browser/ssl/chrome_security_blocking_page_factory.cc
index bb37110..24a8527 100644
--- a/chrome/browser/ssl/chrome_security_blocking_page_factory.cc
+++ b/chrome/browser/ssl/chrome_security_blocking_page_factory.cc
@@ -83,7 +83,7 @@
   }
 
 #if BUILDFLAG(IS_WIN)
-  if (base::IsMachineExternallyManaged()) {
+  if (base::IsManagedOrEnterpriseDevice()) {
     return true;
   }
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
@@ -323,7 +323,7 @@
         report->AddChromeChannel(chrome::GetChannel());
 
 #if BUILDFLAG(IS_WIN)
-        report->SetIsEnterpriseManaged(base::IsMachineExternallyManaged());
+        report->SetIsEnterpriseManaged(IsEnterpriseManaged());
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
         report->SetIsEnterpriseManaged(g_browser_process->platform_part()
                                            ->browser_policy_connector_ash()
diff --git a/chrome/browser/ssl/sct_reporting_service.cc b/chrome/browser/ssl/sct_reporting_service.cc
index f1e0061..a110da6 100644
--- a/chrome/browser/ssl/sct_reporting_service.cc
+++ b/chrome/browser/ssl/sct_reporting_service.cc
@@ -20,6 +20,7 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/network_service.mojom.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 constexpr net::NetworkTrafficAnnotationTag kSCTAuditReportTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("sct_auditing", R"(
@@ -121,7 +122,7 @@
 
 // static
 void SCTReportingService::ReconfigureAfterNetworkRestart() {
-  network::mojom::SCTAuditingConfigurationPtr configuration(base::in_place);
+  network::mojom::SCTAuditingConfigurationPtr configuration(absl::in_place);
   configuration->sampling_rate = features::kSCTAuditingSamplingRate.Get();
   configuration->log_expected_ingestion_delay =
       features::kSCTLogExpectedIngestionDelay.Get();
diff --git a/chrome/browser/subresource_filter/BUILD.gn b/chrome/browser/subresource_filter/BUILD.gn
index dd4f7e73..ca0fd0e 100644
--- a/chrome/browser/subresource_filter/BUILD.gn
+++ b/chrome/browser/subresource_filter/BUILD.gn
@@ -15,7 +15,6 @@
     testonly = true
     sources = [ "../../android/javatests/src/org/chromium/chrome/browser/subresource_filter/TestRulesetPublisher.java" ]
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
     ]
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
index 33c892d3..3176353c 100644
--- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc
+++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -87,8 +87,7 @@
 bool ChildAccountService::IsChildAccountDetectionEnabled() {
 // Child account detection is always enabled on Android and ChromeOS, and
 // disabled in other platforms.
-#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || \
-    BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
   return false;
@@ -184,7 +183,7 @@
     settings_service->SetLocalSetting(supervised_users::kGeolocationDisabled,
                                       std::make_unique<base::Value>(false));
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if !BUILDFLAG(IS_CHROMEOS)
     // This is also used by user policies (UserPolicySigninService), but since
     // child accounts can not also be Dasher accounts, there shouldn't be any
     // problems.
@@ -210,7 +209,7 @@
     settings_service->SetLocalSetting(supervised_users::kGeolocationDisabled,
                                       nullptr);
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)
+#if !BUILDFLAG(IS_CHROMEOS)
     signin_util::SetUserSignoutAllowedForProfile(profile_, true);
 #endif
 
diff --git a/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc b/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc
index c1bca61..7f6f976 100644
--- a/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc
+++ b/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc
@@ -18,7 +18,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
@@ -147,7 +146,7 @@
   }
 
   CoreAccountInfo SetPrimaryAccount() {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
     return identity_test_env_.SetPrimaryAccount(kAccountId,
                                                 signin::ConsentLevel::kSync);
 #elif BUILDFLAG(IS_ANDROID)
@@ -162,7 +161,7 @@
   }
 
   void IssueRefreshToken() {
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS)
     identity_test_env_.MakePrimaryAccountAvailable(kAccountId,
                                                    signin::ConsentLevel::kSync);
 #elif BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/supervised_user/parental_control_metrics.cc b/chrome/browser/supervised_user/parental_control_metrics.cc
new file mode 100644
index 0000000..65aba3c
--- /dev/null
+++ b/chrome/browser/supervised_user/parental_control_metrics.cc
@@ -0,0 +1,28 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/parental_control_metrics.h"
+
+#include "base/check.h"
+#include "chrome/browser/supervised_user/supervised_user_service.h"
+
+ParentalControlMetrics::ParentalControlMetrics(SupervisedUserService* service)
+    : supervised_user_service_(service) {
+  DCHECK(supervised_user_service_);
+}
+
+ParentalControlMetrics::~ParentalControlMetrics() = default;
+
+void ParentalControlMetrics::OnNewDay() {
+  // Ignores the first report during OOBE. Prefs related to web filter
+  // policy may not have been successfully sync during OOBE process, which
+  // introduces bias.
+  if (first_report_on_current_device_) {
+    first_report_on_current_device_ = false;
+  } else {
+    // Ignores reports when web filter prefs are reset to default value. It
+    // might happen during sign out.
+    supervised_user_service_->ReportNonDefaultWebFilterValue();
+  }
+}
diff --git a/chrome/browser/supervised_user/parental_control_metrics.h b/chrome/browser/supervised_user/parental_control_metrics.h
new file mode 100644
index 0000000..0942d5b3
--- /dev/null
+++ b/chrome/browser/supervised_user/parental_control_metrics.h
@@ -0,0 +1,30 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SUPERVISED_USER_PARENTAL_CONTROL_METRICS_H_
+#define CHROME_BROWSER_SUPERVISED_USER_PARENTAL_CONTROL_METRICS_H_
+
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+
+class SupervisedUserService;
+
+// A class for recording time limit metrics and web filter metrics for Family
+// Link users on Chrome browser at the beginning of the first active session
+// daily.
+class ParentalControlMetrics : public SupervisedUserMetricsService::Observer {
+ public:
+  explicit ParentalControlMetrics(SupervisedUserService* service);
+  ParentalControlMetrics(const ParentalControlMetrics&) = delete;
+  ParentalControlMetrics& operator=(const ParentalControlMetrics&) = delete;
+  ~ParentalControlMetrics() override;
+
+  // SupervisedUserMetricsService::Observer:
+  void OnNewDay() override;
+
+ private:
+  SupervisedUserService* const supervised_user_service_;
+  bool first_report_on_current_device_ = false;
+};
+
+#endif  // CHROME_BROWSER_SUPERVISED_USER_PARENTAL_CONTROL_METRICS_H_
diff --git a/chrome/browser/supervised_user/parental_control_metrics_unittest.cc b/chrome/browser/supervised_user/parental_control_metrics_unittest.cc
new file mode 100644
index 0000000..852454b
--- /dev/null
+++ b/chrome/browser/supervised_user/parental_control_metrics_unittest.cc
@@ -0,0 +1,219 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/parental_control_metrics.h"
+
+#include <memory>
+#include <string>
+
+#include "base/containers/flat_map.h"
+#include "base/run_loop.h"
+#include "base/strings/strcat.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_service.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/browser/supervised_user/supervised_user_url_filter.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/prefs/scoped_user_pref_update.h"
+#include "components/sync_preferences/pref_service_syncable.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+constexpr char kStartTime[] = "1 Jan 2020 21:15";
+constexpr char kExampleHost0[] = "http://www.example0.com";
+constexpr char kExampleURL1[] = "http://www.example1.com/123";
+
+}  // namespace
+
+class ParentalControlMetricsTest : public testing::Test {
+ public:
+  void SetUp() override {
+    base::Time start_time;
+    EXPECT_TRUE(base::Time::FromString(kStartTime, &start_time));
+    base::TimeDelta forward_by = start_time - base::Time::Now();
+    EXPECT_LT(base::TimeDelta(), forward_by);
+    task_environment_.AdvanceClock(forward_by);
+
+    // Build a child profile.
+    std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> prefs =
+        std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
+    RegisterUserProfilePrefs(prefs->registry());
+    TestingProfile::Builder profile_builder;
+    profile_builder.SetPrefService(std::move(prefs));
+    profile_builder.SetIsSupervisedProfile();
+    profile_ = profile_builder.Build();
+    EXPECT_TRUE(profile_->IsChild());
+    supervised_user_service_ =
+        SupervisedUserServiceFactory::GetForProfile(profile_.get());
+    supervised_user_service_->Init();
+    parental_control_metrics_ =
+        std::make_unique<ParentalControlMetrics>(supervised_user_service_);
+  }
+
+  void TearDown() override {
+    parental_control_metrics_.reset();
+    profile_.reset();
+  }
+
+ protected:
+  void OnNewDay() { parental_control_metrics_->OnNewDay(); }
+
+  PrefService* GetPrefs() { return profile_->GetPrefs(); }
+
+  std::unique_ptr<TestingProfile> profile_;
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+  base::HistogramTester histogram_tester_;
+
+ private:
+  std::unique_ptr<ParentalControlMetrics> parental_control_metrics_;
+  SupervisedUserService* supervised_user_service_ = nullptr;
+};
+
+TEST_F(ParentalControlMetricsTest, WebFilterTypeMetric) {
+  // Overriding the value of prefs::kSupervisedUserSafeSites and
+  // prefs::kDefaultSupervisedUserFilteringBehavior in default storage is
+  // needed, otherwise no report could be triggered policies change or
+  // OnNewDay(). Since the default values are the same of override values, the
+  // WebFilterType doesn't change and no report here.
+  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
+                         SupervisedUserURLFilter::ALLOW);
+  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, true);
+
+  // Tests daily report.
+  OnNewDay();
+  histogram_tester_.ExpectUniqueSample(
+      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::WebFilterType::kTryToBlockMatureSites,
+      /*expected_count=*/1);
+
+  // Tests filter "allow all sites".
+  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, false);
+
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::WebFilterType::kAllowAllSites,
+      /*expected_count=*/1);
+
+  // Tests filter "only allow certain sites" on Family Link app.
+  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
+                         SupervisedUserURLFilter::BLOCK);
+
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::WebFilterType::kCertainSites,
+      /*expected_count=*/1);
+
+  histogram_tester_.ExpectTotalCount(
+      SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest(),
+      /*expected_count=*/3);
+}
+
+TEST_F(ParentalControlMetricsTest, ManagedSiteListTypeMetric) {
+  // Overriding the value of prefs::kSupervisedUserSafeSites and
+  // prefs::kDefaultSupervisedUserFilteringBehavior in default storage is
+  // needed, otherwise no report could be triggered by policies change or
+  // OnNewDay(). Since the default values are the same of override values, the
+  // WebFilterType doesn't change and no report here.
+  GetPrefs()->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
+                         SupervisedUserURLFilter::ALLOW);
+  GetPrefs()->SetBoolean(prefs::kSupervisedUserSafeSites, true);
+
+  // Tests daily report.
+  OnNewDay();
+  histogram_tester_.ExpectUniqueSample(
+      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::ManagedSiteList::kEmpty,
+      /*expected_count=*/1);
+  histogram_tester_.ExpectUniqueSample(
+      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
+      /*sample=*/0, /*expected_count=*/1);
+  histogram_tester_.ExpectUniqueSample(
+      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
+      /*sample=*/0, /*expected_count=*/1);
+
+  // Blocks `kExampleHost0`.
+  {
+    DictionaryPrefUpdate hosts_update(GetPrefs(),
+                                      prefs::kSupervisedUserManualHosts);
+    base::Value* hosts = hosts_update.Get();
+    hosts->SetBoolKey(kExampleHost0, false);
+  }
+
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::ManagedSiteList::kBlockedListOnly,
+      /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
+      /*sample=*/0, /*expected_count=*/2);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
+      /*sample=*/1, /*expected_count=*/1);
+
+  // Approves `kExampleHost0`.
+  {
+    DictionaryPrefUpdate hosts_update(GetPrefs(),
+                                      prefs::kSupervisedUserManualHosts);
+    base::Value* hosts = hosts_update.Get();
+    hosts->SetBoolKey(kExampleHost0, true);
+  }
+
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::ManagedSiteList::kApprovedListOnly,
+      /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
+      /*sample=*/1, /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
+      /*sample=*/0, /*expected_count=*/2);
+
+  // Blocks `kExampleURL1`.
+  {
+    DictionaryPrefUpdate urls_update(GetPrefs(),
+                                     prefs::kSupervisedUserManualURLs);
+    base::Value* urls = urls_update.Get();
+    urls->SetBoolKey(kExampleURL1, false);
+  }
+
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
+      /*sample=*/
+      SupervisedUserURLFilter::ManagedSiteList::kBoth,
+      /*expected_count=*/1);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
+      /*sample=*/1, /*expected_count=*/2);
+  histogram_tester_.ExpectBucketCount(
+      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
+      /*sample=*/1, /*expected_count=*/2);
+
+  histogram_tester_.ExpectTotalCount(
+      SupervisedUserURLFilter::GetManagedSiteListHistogramNameForTest(),
+      /*expected_count=*/4);
+  histogram_tester_.ExpectTotalCount(
+      SupervisedUserURLFilter::GetApprovedSitesCountHistogramNameForTest(),
+      /*expected_count=*/4);
+  histogram_tester_.ExpectTotalCount(
+      SupervisedUserURLFilter::GetBlockedSitesCountHistogramNameForTest(),
+      /*expected_count=*/4);
+}
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service.cc b/chrome/browser/supervised_user/supervised_user_metrics_service.cc
new file mode 100644
index 0000000..4eb74cda
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_metrics_service.cc
@@ -0,0 +1,93 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/time/time.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/parental_control_metrics.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_context.h"
+
+namespace {
+
+constexpr base::TimeDelta kTimerInterval = base::Minutes(10);
+
+// Returns the number of days since the origin.
+int GetDayId(base::Time time) {
+  return time.LocalMidnight().since_origin().InDaysFloored();
+}
+
+}  // namespace
+
+// static
+void SupervisedUserMetricsService::RegisterProfilePrefs(
+    PrefRegistrySimple* registry) {
+  registry->RegisterIntegerPref(prefs::kSupervisedUserMetricsDayId, 0);
+}
+
+// static
+int SupervisedUserMetricsService::GetDayIdForTesting(base::Time time) {
+  return GetDayId(time);
+}
+
+SupervisedUserMetricsService::SupervisedUserMetricsService(
+    content::BrowserContext* context)
+    : pref_service_(Profile::FromBrowserContext(context)->GetPrefs()) {
+  DCHECK(pref_service_);
+
+  // Reports parental control metrics for child user only.
+  Profile* profile = Profile::FromBrowserContext(context);
+  if (profile->IsChild()) {
+    SupervisedUserService* supervised_user_service =
+        SupervisedUserServiceFactory::GetForProfile(profile);
+    supervised_user_metrics_.push_back(
+        std::make_unique<ParentalControlMetrics>(supervised_user_service));
+  }
+
+  for (auto& supervised_user_metric : supervised_user_metrics_)
+    AddObserver(supervised_user_metric.get());
+
+  CheckForNewDay();
+  // Check for a new day every |kTimerInterval| as well.
+  DLOG(WARNING) << "If your test is uses mock timers and hangs, you may need "
+                   "to call Shutdown() on SupervisedUserMetricsService.";
+  timer_.Start(FROM_HERE, kTimerInterval, this,
+               &SupervisedUserMetricsService::CheckForNewDay);
+}
+
+SupervisedUserMetricsService::~SupervisedUserMetricsService() = default;
+
+void SupervisedUserMetricsService::Shutdown() {
+  CheckForNewDay();
+  observers_.Clear();
+  supervised_user_metrics_.clear();
+  timer_.Stop();
+}
+
+void SupervisedUserMetricsService::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void SupervisedUserMetricsService::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+void SupervisedUserMetricsService::CheckForNewDay() {
+  int day_id = pref_service_->GetInteger(prefs::kSupervisedUserMetricsDayId);
+  base::Time now = base::Time::Now();
+  // The OnNewDay() event can fire sooner or later than 24 hours due to clock or
+  // time zone changes.
+  if (day_id < GetDayId(now)) {
+    for (Observer& observer : observers_)
+      observer.OnNewDay();
+    pref_service_->SetInteger(prefs::kSupervisedUserMetricsDayId,
+                              GetDayId(now));
+  }
+}
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service.h b/chrome/browser/supervised_user/supervised_user_metrics_service.h
new file mode 100644
index 0000000..1b566525
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_metrics_service.h
@@ -0,0 +1,68 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_H_
+#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "base/timer/timer.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace base {
+class Time;
+}  // namespace base
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+// Service to initialize and control metric recorders of supervised users.
+class SupervisedUserMetricsService : public KeyedService {
+ public:
+  // Interface for observing events on the SupervisedUserMetricsService.
+  class Observer : public base::CheckedObserver {
+   public:
+    // Called when we detect a new day. This event can fire sooner or later than
+    // 24 hours due to clock or time zone changes.
+    virtual void OnNewDay() {}
+  };
+
+  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
+  // Returns the day id for a given time for testing.
+  static int GetDayIdForTesting(base::Time time);
+
+  explicit SupervisedUserMetricsService(content::BrowserContext* context);
+  SupervisedUserMetricsService(const SupervisedUserMetricsService&) = delete;
+  SupervisedUserMetricsService& operator=(const SupervisedUserMetricsService&) =
+      delete;
+  ~SupervisedUserMetricsService() override;
+
+  // KeyedService:
+  void Shutdown() override;
+
+ private:
+  // Helper function to check if a new day has arrived.
+  void CheckForNewDay();
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+  PrefService* const pref_service_;
+
+  // A periodic timer that checks if a new day has arrived.
+  base::RepeatingTimer timer_;
+
+  // The |observers_| list is a superset of the |supervised_user_metrics_|.
+  base::ObserverList<Observer> observers_;
+  std::vector<std::unique_ptr<Observer>> supervised_user_metrics_;
+};
+
+#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_H_
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service_factory.cc b/chrome/browser/supervised_user/supervised_user_metrics_service_factory.cc
new file mode 100644
index 0000000..aae897c
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_metrics_service_factory.cc
@@ -0,0 +1,58 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/supervised_user_metrics_service_factory.h"
+
+#include "base/no_destructor.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "content/public/browser/browser_context.h"
+
+// static
+SupervisedUserMetricsService*
+SupervisedUserMetricsServiceFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<SupervisedUserMetricsService*>(
+      GetInstance()->GetServiceForBrowserContext(context, /*create=*/true));
+}
+
+// static
+SupervisedUserMetricsServiceFactory*
+SupervisedUserMetricsServiceFactory::GetInstance() {
+  static base::NoDestructor<SupervisedUserMetricsServiceFactory> factory;
+  return factory.get();
+}
+
+SupervisedUserMetricsServiceFactory::SupervisedUserMetricsServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "SupervisedUserMetricsServiceFactory",
+          BrowserContextDependencyManager::GetInstance()) {
+  // Used for tracking web filter metrics.
+  DependsOn(SupervisedUserServiceFactory::GetInstance());
+}
+
+SupervisedUserMetricsServiceFactory::~SupervisedUserMetricsServiceFactory() =
+    default;
+
+void SupervisedUserMetricsServiceFactory::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  SupervisedUserMetricsService::RegisterProfilePrefs(registry);
+}
+
+KeyedService* SupervisedUserMetricsServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  Profile* profile = Profile::FromBrowserContext(context);
+  if (profile->IsGuestSession() || profile->IsSystemProfile())
+    return nullptr;
+
+  return new SupervisedUserMetricsService(context);
+}
+
+bool SupervisedUserMetricsServiceFactory::ServiceIsCreatedWithBrowserContext()
+    const {
+  return true;
+}
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service_factory.h b/chrome/browser/supervised_user/supervised_user_metrics_service_factory.h
new file mode 100644
index 0000000..c409e374
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_metrics_service_factory.h
@@ -0,0 +1,52 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}  // namespace user_prefs
+
+class SupervisedUserMetricsService;
+
+// Singleton that owns SupervisedUserMetricsService object and associates
+// them with corresponding BrowserContexts. Listens for the BrowserContext's
+// destruction notification and cleans up the associated
+// SupervisedUserMetricsService.
+class SupervisedUserMetricsServiceFactory
+    : public BrowserContextKeyedServiceFactory {
+ public:
+  SupervisedUserMetricsServiceFactory(
+      const SupervisedUserMetricsServiceFactory&) = delete;
+  SupervisedUserMetricsServiceFactory& operator=(
+      const SupervisedUserMetricsServiceFactory&) = delete;
+
+  static SupervisedUserMetricsService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  static SupervisedUserMetricsServiceFactory* GetInstance();
+
+ private:
+  friend class base::NoDestructor<SupervisedUserMetricsServiceFactory>;
+
+  SupervisedUserMetricsServiceFactory();
+  ~SupervisedUserMetricsServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  void RegisterProfilePrefs(
+      user_prefs::PrefRegistrySyncable* registry) override;
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+  bool ServiceIsCreatedWithBrowserContext() const override;
+};
+
+#endif  // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_METRICS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/supervised_user/supervised_user_metrics_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_metrics_service_unittest.cc
new file mode 100644
index 0000000..b6a4522
--- /dev/null
+++ b/chrome/browser/supervised_user/supervised_user_metrics_service_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/supervised_user_metrics_service.h"
+
+#include <memory>
+
+#include "base/time/time.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+constexpr char kStartTime[] = "1 Jan 2020 21:00";
+
+}  // namespace
+
+// Tests for family user metrics service.
+class SupervisedUserMetricsServiceTest : public testing::Test {
+ public:
+  void SetUp() override {
+    base::Time start_time;
+    EXPECT_TRUE(base::Time::FromString(kStartTime, &start_time));
+    base::TimeDelta forward_by = start_time - base::Time::Now();
+    EXPECT_LT(base::TimeDelta(), forward_by);
+    task_environment_.AdvanceClock(forward_by);
+
+    supervised_user_metrics_service_ =
+        std::make_unique<SupervisedUserMetricsService>(&testing_profile_);
+  }
+
+  void TearDown() override {
+    supervised_user_metrics_service_->Shutdown();
+    supervised_user_metrics_service_.reset();
+  }
+
+ protected:
+  sync_preferences::TestingPrefServiceSyncable* GetPrefService() {
+    return testing_profile_.GetTestingPrefService();
+  }
+
+  int GetDayIdPref() {
+    return GetPrefService()->GetInteger(prefs::kSupervisedUserMetricsDayId);
+  }
+
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+ private:
+  TestingProfile testing_profile_;
+  std::unique_ptr<SupervisedUserMetricsService>
+      supervised_user_metrics_service_;
+};
+
+// Tests OnNewDay() is called after more than one day passes.
+TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterMultipleDays) {
+  task_environment_.FastForwardBy(base::Days(1) + base::Hours(1));
+  EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
+            GetDayIdPref());
+}
+
+// Tests OnNewDay() is called at midnight.
+TEST_F(SupervisedUserMetricsServiceTest, NewDayAtMidnight) {
+  task_environment_.FastForwardBy(base::Hours(3));
+  EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
+            GetDayIdPref());
+}
+
+// Tests OnNewDay() is not called before midnight.
+TEST_F(SupervisedUserMetricsServiceTest, NewDayAfterMidnight) {
+  task_environment_.FastForwardBy(base::Hours(1));
+  EXPECT_EQ(SupervisedUserMetricsService::GetDayIdForTesting(base::Time::Now()),
+            GetDayIdPref());
+}
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index d79fa20b..7095942 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -119,7 +119,6 @@
   return denylist_dir.AppendASCII(kDenylistFilename);
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 bool AreWebFilterPrefsDefault(PrefService* pref_service) {
   return pref_service
              ->FindPreference(prefs::kDefaultSupervisedUserFilteringBehavior)
@@ -128,8 +127,6 @@
              ->IsDefaultValue();
 }
 
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 }  // namespace
 
 SupervisedUserService::~SupervisedUserService() {
@@ -206,20 +203,7 @@
 }
 
 std::string SupervisedUserService::GetCustodianEmailAddress() const {
-  std::string email =
-      profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // |GetActiveUser()| can return null in unit tests.
-  if (email.empty() && !!user_manager::UserManager::Get()->GetActiveUser()) {
-    email = ash::ChromeUserManager::Get()
-                ->GetSupervisedUserManager()
-                ->GetManagerDisplayEmail(user_manager::UserManager::Get()
-                                             ->GetActiveUser()
-                                             ->GetAccountId()
-                                             .GetUserEmail());
-  }
-#endif
-  return email;
+  return profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianEmail);
 }
 
 std::string SupervisedUserService::GetCustodianObfuscatedGaiaId() const {
@@ -230,20 +214,6 @@
 std::string SupervisedUserService::GetCustodianName() const {
   std::string name =
       profile_->GetPrefs()->GetString(prefs::kSupervisedUserCustodianName);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // TODO(https://crbug.com/1218633): Check if additional work is needed for
-  // extensions in LaCrOS.
-  // |GetActiveUser()| can return null in unit tests.
-  if (name.empty() && !!user_manager::UserManager::Get()->GetActiveUser()) {
-    name = base::UTF16ToUTF8(
-        chromeos::ChromeUserManager::Get()
-            ->GetSupervisedUserManager()
-            ->GetManagerDisplayName(user_manager::UserManager::Get()
-                                        ->GetActiveUser()
-                                        ->GetAccountId()
-                                        .GetUserEmail()));
-  }
-#endif
   return name.empty() ? GetCustodianEmailAddress() : name;
 }
 
@@ -385,7 +355,6 @@
 }
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 void SupervisedUserService::ReportNonDefaultWebFilterValue() const {
   if (AreWebFilterPrefsDefault(profile_->GetPrefs()))
     return;
@@ -393,21 +362,16 @@
   url_filter_.ReportManagedSiteListMetrics();
   url_filter_.ReportWebFilterTypeMetrics();
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 void SupervisedUserService::SetActive(bool active) {
   if (active_ == active)
     return;
   active_ = active;
 
-  if (!delegate_ || !delegate_->SetActive(active_)) {
-#if BUILDFLAG(IS_ANDROID)
-    DCHECK(!active_);
-#endif
-  }
+  if (delegate_)
+    delegate_->SetActive(active_);
 
-  // Now activate/deactivate anything not handled by the delegate yet.
-
+    // Now activate/deactivate anything not handled by the delegate yet.
 #if !BUILDFLAG(IS_ANDROID)
   // Re-set the default theme to turn the SU theme on/off.
   ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile_);
@@ -459,10 +423,8 @@
     UpdateManualHosts();
     UpdateManualURLs();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
     GetURLFilter()->SetFilterInitialized(true);
     current_web_filter_type_ = url_filter_.GetWebFilterType();
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
     RefreshApprovedExtensionsFromPrefs();
@@ -530,7 +492,6 @@
   for (SupervisedUserServiceObserver& observer : observer_list_)
     observer.OnURLFilterChanged();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   SupervisedUserURLFilter::WebFilterType filter_type =
       url_filter_.GetWebFilterType();
   if (!AreWebFilterPrefsDefault(profile_->GetPrefs()) &&
@@ -538,7 +499,6 @@
     url_filter_.ReportWebFilterTypeMetrics();
     current_web_filter_type_ = filter_type;
   }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 bool SupervisedUserService::IsSafeSitesEnabled() const {
@@ -562,7 +522,6 @@
 
   UpdateAsyncUrlChecker();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   SupervisedUserURLFilter::WebFilterType filter_type =
       url_filter_.GetWebFilterType();
   if (!AreWebFilterPrefsDefault(profile_->GetPrefs()) &&
@@ -570,7 +529,6 @@
     url_filter_.ReportWebFilterTypeMetrics();
     current_web_filter_type_ = filter_type;
   }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void SupervisedUserService::UpdateAsyncUrlChecker() {
@@ -706,10 +664,8 @@
   for (SupervisedUserServiceObserver& observer : observer_list_)
     observer.OnURLFilterChanged();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!AreWebFilterPrefsDefault(profile_->GetPrefs()))
     url_filter_.ReportManagedSiteListMetrics();
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void SupervisedUserService::UpdateManualURLs() {
@@ -725,10 +681,8 @@
   for (SupervisedUserServiceObserver& observer : observer_list_)
     observer.OnURLFilterChanged();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   if (!AreWebFilterPrefsDefault(profile_->GetPrefs()))
     url_filter_.ReportManagedSiteListMetrics();
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
 void SupervisedUserService::Shutdown() {
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index 9055e61..3767161 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -230,13 +230,11 @@
   void RecordExtensionEnablementUmaMetrics(bool enabled) const;
 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   // TODO(https://crbug.com/1288986): Enable web filter metrics reporting in
   // LaCrOS.
   // Reports FamilyUser.WebFilterType and FamilyUser.ManagedSiteList
   // metrics. Ignores reporting when AreWebFilterPrefsDefault() is true.
   void ReportNonDefaultWebFilterValue() const;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
  private:
   friend class SupervisedUserServiceExtensionTestBase;
@@ -415,7 +413,6 @@
   bool signout_required_after_supervision_enabled_ = false;
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   // TODO(https://crbug.com/1288986): Enable web filter metrics reporting in
   // LaCrOS.
   // When there is change between WebFilterType::kTryToBlockMatureSites and
@@ -425,7 +422,6 @@
   // reports. Initialized in the SetActive().
   SupervisedUserURLFilter::WebFilterType current_web_filter_type_ =
       SupervisedUserURLFilter::WebFilterType::kMaxValue;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   base::WeakPtrFactory<SupervisedUserService> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc
index 5a98498..7b82cb10 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -177,29 +177,25 @@
 const char kManagedSiteListConflictHistogramName[] =
     "FamilyUser.ManagedSiteList.Conflict";
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 // UMA histogram FamilyUser.WebFilterType
 // Reports WebFilterType which indicates web filter behaviour are used for
-// current Family Link user on Chrome OS.
+// current Family Link user.
 constexpr char kWebFilterTypeHistogramName[] = "FamilyUser.WebFilterType";
 
 // UMA histogram FamilyUser.ManualSiteListType
 // Reports ManualSiteListType which indicates approved list and blocked list
-// usage for current Family Link user on Chrome OS.
+// usage for current Family Link user.
 constexpr char kManagedSiteListHistogramName[] = "FamilyUser.ManagedSiteList";
 
 // UMA histogram FamilyUser.ManagedSiteListCount.Approved
-// Reports the number of approved urls and domains for current Family Link user
-// on Chrome OS.
+// Reports the number of approved urls and domains for current Family Link user.
 constexpr char kApprovedSitesCountHistogramName[] =
     "FamilyUser.ManagedSiteListCount.Approved";
 
 // UMA histogram FamilyUser.ManagedSiteListCount.Blocked
-// Reports the number of blocked urls and domains for current Family Link user
-// on Chrome OS.
+// Reports the number of blocked urls and domains for current Family Link user.
 constexpr char kBlockedSitesCountHistogramName[] =
     "FamilyUser.ManagedSiteListCount.Blocked";
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }  // namespace
 
 SupervisedUserURLFilter::SupervisedUserURLFilter()
@@ -213,7 +209,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 // static
 const char* SupervisedUserURLFilter::GetWebFilterTypeHistogramNameForTest() {
   return kWebFilterTypeHistogramName;
@@ -236,8 +231,6 @@
   return kBlockedSitesCountHistogramName;
 }
 
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 // static
 const char*
 SupervisedUserURLFilter::GetManagedSiteListConflictHistogramNameForTest() {
@@ -569,7 +562,6 @@
   blocking_task_runner_ = task_runner;
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 SupervisedUserURLFilter::WebFilterType
 SupervisedUserURLFilter::GetWebFilterType() const {
   // If the default filtering behavior is not block, it means the web filter
@@ -640,7 +632,6 @@
 void SupervisedUserURLFilter::SetFilterInitialized(bool is_filter_initialized) {
   is_filter_initialized_ = is_filter_initialized;
 }
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 bool SupervisedUserURLFilter::RunAsyncChecker(
     const GURL& url,
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.h b/chrome/browser/supervised_user/supervised_user_url_filter.h
index 3aaa4a4..4de375f 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.h
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.h
@@ -53,8 +53,7 @@
     INVALID = 3,
   };
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // This enum describes the filter types of Chrome on Chrome OS, which is
+  // This enum describes the filter types of Chrome, which is
   // set by Family Link App or at families.google.com/families. These values
   // are logged to UMA. Entries should not be renumbered and numeric values
   // should never be reused. Please keep in sync with "FamilyLinkWebFilterType"
@@ -98,7 +97,6 @@
     // above this comment. Sync with enums.xml.
     kMaxValue = kBoth,
   };
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   using FilteringBehaviorCallback = base::OnceCallback<void(
       FilteringBehavior,
@@ -126,13 +124,10 @@
 
   ~SupervisedUserURLFilter();
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   static const char* GetWebFilterTypeHistogramNameForTest();
   static const char* GetManagedSiteListHistogramNameForTest();
   static const char* GetApprovedSitesCountHistogramNameForTest();
   static const char* GetBlockedSitesCountHistogramNameForTest();
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
   static const char* GetManagedSiteListConflictHistogramNameForTest();
 
   // Returns true if the parental allowlist/blocklist should be skipped in
@@ -234,7 +229,6 @@
   void SetBlockingTaskRunnerForTesting(
       const scoped_refptr<base::TaskRunner>& task_runner);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   WebFilterType GetWebFilterType() const;
 
   // Reports FamilyUser.WebFilterType metrics when `is_filter_initialized_` is
@@ -247,7 +241,6 @@
 
   // Set value for `is_filter_initialized_`.
   void SetFilterInitialized(bool is_filter_initialized);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
  private:
   friend class SupervisedUserURLFilterTest;
@@ -289,9 +282,7 @@
 
   SEQUENCE_CHECKER(sequence_checker_);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
   bool is_filter_initialized_ = false;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   base::WeakPtrFactory<SupervisedUserURLFilter> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
index 1b03feb5..419aaaf 100644
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModel.java
@@ -54,7 +54,7 @@
     }
 
     @Override
-    public Tab getNextTabIfClosed(int id) {
+    public Tab getNextTabIfClosed(int id, boolean uponExit) {
         return null;
     }
 
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
index f5f56cb..5c8f9c6 100644
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java
@@ -137,8 +137,8 @@
     }
 
     @Override
-    public Tab getNextTabIfClosed(int id) {
-        return mDelegateModel.getNextTabIfClosed(id);
+    public Tab getNextTabIfClosed(int id, boolean uponExit) {
+        return mDelegateModel.getNextTabIfClosed(id, uponExit);
     }
 
     @Override
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
index 41032da..9128c96 100644
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModel.java
@@ -74,9 +74,10 @@
     /**
      * Returns which tab would be selected if the specified tab {@code id} were closed.
      * @param id The ID of tab which would be closed.
+     * @param uponExit If the next tab is being selected upon exit or backgrounding of the app.
      * @return The id of the next tab that would be visible.
      */
-    public Tab getNextTabIfClosed(int id);
+    public Tab getNextTabIfClosed(int id, boolean uponExit);
 
     /**
      * Close multiple tabs on this model.
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java
index 380d008..28966523 100644
--- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java
+++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelUtils.java
@@ -186,4 +186,27 @@
         }
         return tabIds;
     }
+
+    /**
+     * Returns the most recently visited Tab in the specified TabList that is not {@code tabId}.
+     * @param model The {@link TabModel} to act on.
+     * @param tabId The ID of the {@link Tab} to skip or {@link Tab.INVALID_TAB_ID}.
+     * @return the most recently visited Tab or null if none can be found.
+     */
+    public static Tab getMostRecentTab(TabList model, int tabId) {
+        Tab mostRecentTab = null;
+        long mostRecentTabTime = 0;
+        for (int i = 0; i < model.getCount(); i++) {
+            final Tab currentTab = model.getTabAt(i);
+            if (currentTab.getId() == tabId || currentTab.isClosing()) continue;
+
+            final long currentTime = CriticalPersistedTabData.from(currentTab).getTimestampMillis();
+            if (currentTime != CriticalPersistedTabData.INVALID_TIMESTAMP
+                    && mostRecentTabTime < currentTime) {
+                mostRecentTabTime = currentTime;
+                mostRecentTab = currentTab;
+            }
+        }
+        return mostRecentTab;
+    }
 }
diff --git a/chrome/browser/touch_to_fill/android/BUILD.gn b/chrome/browser/touch_to_fill/android/BUILD.gn
index dff92dab..7c931f5 100644
--- a/chrome/browser/touch_to_fill/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/android/BUILD.gn
@@ -30,12 +30,12 @@
   sources = [
     "internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java",
     "java/src/org/chromium/chrome/browser/touch_to_fill/data/Credential.java",
+    "java/src/org/chromium/chrome/browser/touch_to_fill/data/WebAuthnCredential.java",
   ]
 }
 
 android_library("public_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//components/browser_ui/bottomsheet/android:java",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -46,6 +46,7 @@
   sources = [
     "java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java",
     "java/src/org/chromium/chrome/browser/touch_to_fill/data/Credential.java",
+    "java/src/org/chromium/chrome/browser/touch_to_fill/data/WebAuthnCredential.java",
   ]
 }
 
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
index c0731b0..4c04b671 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
@@ -9,6 +9,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.NativeMethods;
 import org.chromium.chrome.browser.touch_to_fill.data.Credential;
+import org.chromium.chrome.browser.touch_to_fill.data.WebAuthnCredential;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
 import org.chromium.ui.base.WindowAndroid;
@@ -61,6 +62,17 @@
     }
 
     @CalledByNative
+    private static WebAuthnCredential[] createWebAuthnCredentialArray(int size) {
+        return new WebAuthnCredential[size];
+    }
+
+    @CalledByNative
+    private static void insertWebAuthnCredential(
+            WebAuthnCredential[] credentials, int index, String username, String id) {
+        credentials[index] = new WebAuthnCredential(username, id);
+    }
+
+    @CalledByNative
     private void showCredentials(
             GURL url, boolean isOriginSecure, Credential[] credentials, boolean submitCredential) {
         mTouchToFillComponent.showCredentials(
@@ -87,6 +99,8 @@
     @NativeMethods
     interface Natives {
         void onCredentialSelected(long nativeTouchToFillViewImpl, Credential credential);
+        void onWebAuthnCredentialSelected(
+                long nativeTouchToFillViewImpl, WebAuthnCredential credential);
         void onManagePasswordsSelected(long nativeTouchToFillViewImpl);
         void onDismiss(long nativeTouchToFillViewImpl);
     }
diff --git a/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/data/WebAuthnCredential.java b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/data/WebAuthnCredential.java
new file mode 100644
index 0000000..2ec55fd
--- /dev/null
+++ b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/data/WebAuthnCredential.java
@@ -0,0 +1,35 @@
+// 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.touch_to_fill.data;
+
+import org.chromium.base.annotations.CalledByNative;
+
+/**
+ * This class holds the data used to represent a selectable Web Authentication credential in the
+ * Touch To Fill sheet.
+ */
+public class WebAuthnCredential {
+    private final String mUsername;
+    private final String mId;
+
+    /**
+     * @param username Username shown to the user.
+     * @param id Unique identifier for the credential.
+     */
+    public WebAuthnCredential(String username, String id) {
+        mUsername = username;
+        mId = id;
+    }
+
+    @CalledByNative
+    public String getUsername() {
+        return mUsername;
+    }
+
+    @CalledByNative
+    public String getId() {
+        return mId;
+    }
+}
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
index c631b70d..88f853a 100644
--- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
+++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
@@ -12,7 +12,9 @@
 #include "base/time/time.h"
 #include "chrome/browser/touch_to_fill/android/jni_headers/Credential_jni.h"
 #include "chrome/browser/touch_to_fill/android/jni_headers/TouchToFillBridge_jni.h"
+#include "chrome/browser/touch_to_fill/android/jni_headers/WebAuthnCredential_jni.h"
 #include "chrome/browser/touch_to_fill/touch_to_fill_controller.h"  // nogncheck
+#include "chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h"  // nogncheck
 #include "chrome/browser/ui/passwords/ui_utils.h"
 #include "components/password_manager/core/browser/origin_credential_store.h"
 #include "ui/android/view_android.h"
@@ -48,6 +50,16 @@
           Java_Credential_lastUsedMsSinceEpoch(env, credential)));
 }
 
+TouchToFillWebAuthnCredential ConvertJavaWebAuthnCredential(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& credential) {
+  return TouchToFillWebAuthnCredential(
+      ConvertJavaStringToUTF16(
+          env, Java_WebAuthnCredential_getUsername(env, credential)),
+      ConvertJavaStringToUTF8(env,
+                              Java_WebAuthnCredential_getId(env, credential)));
+}
+
 }  // namespace
 
 TouchToFillViewImpl::TouchToFillViewImpl(TouchToFillController* controller)
@@ -65,6 +77,7 @@
     const GURL& url,
     IsOriginSecure is_origin_secure,
     base::span<const password_manager::UiCredential> credentials,
+    base::span<const TouchToFillWebAuthnCredential> webauthn_credentials,
     bool trigger_submission) {
   if (!RecreateJavaObject()) {
     // It's possible that the constructor cannot access the bottom sheet clank
@@ -77,10 +90,10 @@
   // Serialize the |credentials| span into a Java array and instruct the bridge
   // to show it together with |url| to the user.
   JNIEnv* env = AttachCurrentThread();
-  auto credential_array =
+  base::android::ScopedJavaLocalRef<jobjectArray> credential_array =
       Java_TouchToFillBridge_createCredentialArray(env, credentials.size());
   for (size_t i = 0; i < credentials.size(); ++i) {
-    const auto& credential = credentials[i];
+    const password_manager::UiCredential& credential = credentials[i];
     Java_TouchToFillBridge_insertCredential(
         env, credential_array, i,
         ConvertUTF16ToJavaString(env, credential.username()),
@@ -92,6 +105,19 @@
         credential.last_used().ToJavaTime());
   }
 
+  base::android::ScopedJavaLocalRef<jobjectArray> webauthn_credential_array =
+      Java_TouchToFillBridge_createWebAuthnCredentialArray(
+          env, webauthn_credentials.size());
+  for (size_t i = 0; i < webauthn_credentials.size(); ++i) {
+    const TouchToFillWebAuthnCredential& credential = webauthn_credentials[i];
+    Java_TouchToFillBridge_insertWebAuthnCredential(
+        env, webauthn_credential_array, i,
+        ConvertUTF16ToJavaString(env, credential.username()),
+        ConvertUTF8ToJavaString(env, credential.id()));
+  }
+
+  // TODO(crbug.com/1318942): |webauthn_credentials| will be passed in a
+  // subsequent CL.
   Java_TouchToFillBridge_showCredentials(
       env, java_object_internal_, url::GURLAndroid::FromNativeGURL(env, url),
       is_origin_secure.value(), credential_array, trigger_submission);
@@ -111,6 +137,13 @@
   OnCredentialSelected(ConvertJavaCredential(env, credential));
 }
 
+void TouchToFillViewImpl::OnWebAuthnCredentialSelected(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& credential) {
+  controller_->OnWebAuthnCredentialSelected(
+      ConvertJavaWebAuthnCredential(env, credential));
+}
+
 void TouchToFillViewImpl::OnManagePasswordsSelected(JNIEnv* env) {
   controller_->OnManagePasswordsSelected();
 }
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
index 4a01e89..758957f6 100644
--- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
+++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
@@ -24,10 +24,12 @@
   ~TouchToFillViewImpl() override;
 
   // TouchToFillView:
-  void Show(const GURL& url,
-            IsOriginSecure is_origin_secure,
-            base::span<const password_manager::UiCredential> credentials,
-            bool trigger_submission) override;
+  void Show(
+      const GURL& url,
+      IsOriginSecure is_origin_secure,
+      base::span<const password_manager::UiCredential> credentials,
+      base::span<const TouchToFillWebAuthnCredential> webauthn_credentials,
+      bool trigger_submission) override;
   void OnCredentialSelected(
       const password_manager::UiCredential& credential) override;
   void OnDismiss() override;
@@ -35,6 +37,9 @@
   void OnCredentialSelected(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& credential);
+  void OnWebAuthnCredentialSelected(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& credential);
   void OnManagePasswordsSelected(JNIEnv* env);
   void OnDismiss(JNIEnv* env);
 
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
index 738ed10..d1f14a1 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/touch_to_fill/touch_to_fill_view.h"
 #include "chrome/browser/touch_to_fill/touch_to_fill_view_factory.h"
+#include "chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h"
 #include "components/device_reauth/biometric_authenticator.h"
 #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
 #include "components/password_manager/core/browser/origin_credential_store.h"
@@ -123,6 +124,7 @@
 
 void TouchToFillController::Show(
     base::span<const UiCredential> credentials,
+    base::span<TouchToFillWebAuthnCredential> webauthn_credentials,
     base::WeakPtr<PasswordManagerDriver> driver,
     SubmissionReadinessState submission_readiness) {
   DCHECK(!driver_ || driver_.get() == driver.get());
@@ -140,8 +142,8 @@
       .Record(ukm::UkmRecorder::Get());
 
   base::UmaHistogramCounts100("PasswordManager.TouchToFill.NumCredentialsShown",
-                              credentials.size());
-  if (credentials.empty()) {
+                              credentials.size() + webauthn_credentials.size());
+  if (credentials.empty() && webauthn_credentials.empty()) {
     // Ideally this should never happen. However, in case we do end up invoking
     // Show() without credentials, we should not show Touch To Fill to the user
     // and treat this case as dismissal, in order to restore the soft keyboard.
@@ -153,11 +155,14 @@
     view_ = TouchToFillViewFactory::Create(this);
 
   const GURL& url = driver_->GetLastCommittedURL();
+  // TODO(https://crbug.com/1318942): Currently WebAuthn credentials are not
+  // displayed in any particular order, and always appear after password
+  // credentials. This needs to be evaluated by UX.
   view_->Show(
       url,
       TouchToFillView::IsOriginSecure(
           network::IsOriginPotentiallyTrustworthy(url::Origin::Create(url))),
-      SortCredentials(credentials), trigger_submission_);
+      SortCredentials(credentials), webauthn_credentials, trigger_submission_);
 }
 
 void TouchToFillController::OnCredentialSelected(
@@ -184,18 +189,30 @@
                      base::Unretained(this), credential));
 }
 
+void TouchToFillController::OnWebAuthnCredentialSelected(
+    const TouchToFillWebAuthnCredential& credential) {
+  view_.reset();
+  if (!driver_)
+    return;
+
+  CleanUpDriverAndReportOutcome(TouchToFillOutcome::kWebAuthnCredentialSelected,
+                                /*show_virtual_keyboard=*/false);
+
+  password_client_->GetWebAuthnCredentialsDelegate()->SelectWebAuthnCredential(
+      credential.id());
+}
+
 void TouchToFillController::OnManagePasswordsSelected() {
   view_.reset();
   if (!driver_)
     return;
 
-  std::exchange(driver_, nullptr)
-      ->TouchToFillClosed(ShowVirtualKeyboard(false));
+  CleanUpDriverAndReportOutcome(TouchToFillOutcome::kManagePasswordsSelected,
+                                /*show_virtual_keyboard=*/false);
+
   password_client_->NavigateToManagePasswordsPage(
       password_manager::ManagePasswordsReferrer::kTouchToFill);
 
-  base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome",
-                                TouchToFillOutcome::kManagePasswordsSelected);
   ukm::builders::TouchToFill_Shown(source_id_)
       .SetUserAction(static_cast<int64_t>(UserAction::kSelectedManagePasswords))
       .Record(ukm::UkmRecorder::Get());
@@ -206,10 +223,8 @@
   if (!driver_)
     return;
 
-  std::exchange(driver_, nullptr)->TouchToFillClosed(ShowVirtualKeyboard(true));
-
-  base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome",
-                                TouchToFillOutcome::kSheetDismissed);
+  CleanUpDriverAndReportOutcome(TouchToFillOutcome::kSheetDismissed,
+                                /*show_virtual_keyboard=*/true);
   ukm::builders::TouchToFill_Shown(source_id_)
       .SetUserAction(static_cast<int64_t>(UserAction::kDismissed))
       .Record(ukm::UkmRecorder::Get());
@@ -229,10 +244,8 @@
     return;
 
   if (!auth_successful) {
-    std::exchange(driver_, nullptr)
-        ->TouchToFillClosed(ShowVirtualKeyboard(true));
-    base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome",
-                                  TouchToFillOutcome::kReauthenticationFailed);
+    CleanUpDriverAndReportOutcome(TouchToFillOutcome::kReauthenticationFailed,
+                                  /*show_virtual_keyboard=*/true);
     return;
   }
 
@@ -264,3 +277,11 @@
   base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome",
                                 TouchToFillOutcome::kCredentialFilled);
 }
+
+void TouchToFillController::CleanUpDriverAndReportOutcome(
+    TouchToFillOutcome outcome,
+    bool show_virtual_keyboard) {
+  std::exchange(driver_, nullptr)
+      ->TouchToFillClosed(ShowVirtualKeyboard(show_virtual_keyboard));
+  base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome", outcome);
+}
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller.h b/chrome/browser/touch_to_fill/touch_to_fill_controller.h
index d80f2ee3..cdb13ba 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller.h
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller.h
@@ -28,6 +28,7 @@
 }  // namespace password_manager
 
 class ChromePasswordManagerClient;
+class TouchToFillWebAuthnCredential;
 
 class TouchToFillController {
  public:
@@ -43,6 +44,7 @@
     kSelectedCredential = 0,
     kDismissed = 1,
     kSelectedManagePasswords = 2,
+    kSelectedWebAuthnCredential = 3,
   };
 
   // The final outcome that closes the Touch To Fill sheet.
@@ -55,7 +57,8 @@
     kSheetDismissed = 1,
     kReauthenticationFailed = 2,
     kManagePasswordsSelected = 3,
-    kMaxValue = kManagePasswordsSelected,
+    kWebAuthnCredentialSelected = 4,
+    kMaxValue = kWebAuthnCredentialSelected,
   };
 
   // No-op constructor for tests.
@@ -71,8 +74,10 @@
   TouchToFillController& operator=(const TouchToFillController&) = delete;
   ~TouchToFillController();
 
-  // Instructs the controller to show the provided |credentials| to the user.
+  // Instructs the controller to show the provided |credentials| and
+  // |webauthn_credentials| to the user.
   void Show(base::span<const password_manager::UiCredential> credentials,
+            base::span<TouchToFillWebAuthnCredential> webauthn_credentials,
             base::WeakPtr<password_manager::PasswordManagerDriver> driver,
             autofill::mojom::SubmissionReadinessState submission_readiness);
 
@@ -81,6 +86,11 @@
   // repeatedly.
   void OnCredentialSelected(const password_manager::UiCredential& credential);
 
+  // Informs the controller that the user has made a selection. Invokes
+  // TouchToFillDismissed() and initiates a WebAuthn sign-in.
+  void OnWebAuthnCredentialSelected(
+      const TouchToFillWebAuthnCredential& credential);
+
   // Informs the controller that the user has tapped the "Manage Passwords"
   // button. This will open the password preferences.
   void OnManagePasswordsSelected();
@@ -107,6 +117,10 @@
   // Fills the credential into the form.
   void FillCredential(const password_manager::UiCredential& credential);
 
+  // Called upon completion or dismissal to perform cleanup.
+  void CleanUpDriverAndReportOutcome(TouchToFillOutcome outcome,
+                                     bool show_virtual_keyboard);
+
   // Weak pointer to the PasswordManagerClient this class is tied to.
   raw_ptr<password_manager::PasswordManagerClient> password_client_ = nullptr;
 
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_unittest.cc
index 137e1ba..ae5320fc 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_controller_unittest.cc
+++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_unittest.cc
@@ -17,9 +17,11 @@
 #include "base/time/time.h"
 #include "base/types/pass_key.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
+#include "chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h"
 #include "components/autofill/core/common/mojom/autofill_types.mojom.h"
 #include "components/device_reauth/biometric_authenticator.h"
 #include "components/device_reauth/mock_biometric_authenticator.h"
+#include "components/password_manager/core/browser/mock_webauthn_credentials_delegate.h"
 #include "components/password_manager/core/browser/origin_credential_store.h"
 #include "components/password_manager/core/browser/stub_password_manager_client.h"
 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
@@ -65,6 +67,10 @@
               NavigateToManagePasswordsPage,
               (password_manager::ManagePasswordsReferrer),
               (override));
+  MOCK_METHOD(password_manager::WebAuthnCredentialsDelegate*,
+              GetWebAuthnCredentialsDelegate,
+              (),
+              (override));
 };
 
 struct MockPasswordManagerDriver : password_manager::StubPasswordManagerDriver {
@@ -76,11 +82,14 @@
 };
 
 struct MockTouchToFillView : TouchToFillView {
-  MOCK_METHOD(
-      void,
-      Show,
-      (const GURL&, IsOriginSecure, base::span<const UiCredential>, bool),
-      (override));
+  MOCK_METHOD(void,
+              Show,
+              (const GURL&,
+               IsOriginSecure,
+               base::span<const UiCredential>,
+               base::span<const TouchToFillWebAuthnCredential>,
+               bool),
+              (override));
   MOCK_METHOD1(OnCredentialSelected, void(const UiCredential&));
   MOCK_METHOD0(OnDismiss, void());
 };
@@ -124,6 +133,13 @@
     // By default, don't trigger a form submission.
     EXPECT_CALL(driver_, TriggerFormSubmission()).Times(0);
 
+    webauthn_credentials_delegate_ =
+        std::make_unique<password_manager::MockWebAuthnCredentialsDelegate>();
+    ON_CALL(client_, GetWebAuthnCredentialsDelegate)
+        .WillByDefault(Return(webauthn_credentials_delegate_.get()));
+    ON_CALL(*webauthn_credentials_delegate_, IsWebAuthnAutofillEnabled)
+        .WillByDefault(Return(false));
+
     scoped_feature_list_.InitAndEnableFeature(
         password_manager::features::kBiometricTouchToFill);
   }
@@ -144,6 +160,11 @@
     return touch_to_fill_controller_;
   }
 
+  password_manager::MockWebAuthnCredentialsDelegate*
+  webauthn_credentials_delegate() {
+    return webauthn_credentials_delegate_.get();
+  }
+
   base::test::ScopedFeatureList& scoped_feature_list() {
     return scoped_feature_list_;
   }
@@ -156,6 +177,8 @@
       base::MakeRefCounted<MockBiometricAuthenticator>();
   MockPasswordManagerDriver driver_;
   MockPasswordManagerClient client_;
+  std::unique_ptr<password_manager::MockWebAuthnCredentialsDelegate>
+      webauthn_credentials_delegate_;
   base::HistogramTester histogram_tester_;
   ukm::TestAutoSetUkmRecorder test_recorder_;
   TouchToFillController touch_to_fill_controller_{
@@ -172,11 +195,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/false));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   // Test that we correctly log the absence of an Android credential.
@@ -213,11 +239,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/true));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/true));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kTwoFields);
 
   EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"),
@@ -242,11 +271,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/false));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"),
@@ -275,11 +307,14 @@
 
   // As we don't know which credential will be selected, don't disable
   // submission for now.
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/true));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/true));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kTwoFields);
 
   // The user picks the credential with an empty username, submission should not
@@ -306,11 +341,14 @@
       MakeUiCredential({.username = "", .password = "p4ssw0rd"})};
 
   // Only one credential with empty username - submission is impossible.
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/false));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kTwoFields);
 
   // Filling doesn't trigger submission.
@@ -326,11 +364,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   // Test that we correctly log the absence of an Android credential.
@@ -362,11 +403,14 @@
 
   // Without |kTouchToFillPasswordSubmission|, a form that is ready for
   // submission doesn't affect UI.
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kTwoFields);
 
   EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"),
@@ -391,11 +435,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   EXPECT_CALL(driver(), FillSuggestion(_, _)).Times(0);
@@ -417,7 +464,7 @@
 TEST_F(TouchToFillControllerTest, Show_Empty) {
   EXPECT_CALL(view(), Show).Times(0);
   touch_to_fill_controller().Show(
-      {}, driver().AsWeakPtr(),
+      {}, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
   histogram_tester().ExpectUniqueSample(
       "PasswordManager.TouchToFill.NumCredentialsShown", 0, 1);
@@ -430,11 +477,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(), Show(Eq(GURL("http://example.com")),
-                           IsOriginSecure(false), ElementsAreArray(credentials),
-                           /*ready_for_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL("http://example.com")), IsOriginSecure(false),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*ready_for_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 }
 
@@ -455,11 +505,14 @@
       }),
   };
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   // Test that we correctly log the presence of an Android credential.
@@ -510,11 +563,14 @@
   });
 
   UiCredential credentials[] = {alice, bob, charlie, david};
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           testing::ElementsAre(charlie, alice, bob, david),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           testing::ElementsAre(charlie, alice, bob, david),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 }
 
@@ -522,11 +578,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(true)));
@@ -551,11 +610,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                               ElementsAreArray(credentials),
-                               /*trigger_submission=*/false));
+  EXPECT_CALL(
+      *weak_view,
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(false)));
@@ -581,11 +643,14 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/false));
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/false));
   touch_to_fill_controller().Show(
-      credentials, driver().AsWeakPtr(),
+      credentials, {}, driver().AsWeakPtr(),
       autofill::mojom::SubmissionReadinessState::kNoInformation);
 
   EXPECT_CALL(*authenticator(),
@@ -598,6 +663,38 @@
   EXPECT_CALL(*authenticator(), Cancel(BiometricAuthRequester::kTouchToFill));
 }
 
+TEST_F(TouchToFillControllerTest, ShowWebAuthnCredential) {
+  std::unique_ptr<MockTouchToFillView> mock_view =
+      std::make_unique<MockTouchToFillView>();
+  MockTouchToFillView* weak_view = mock_view.get();
+  touch_to_fill_controller().set_view(std::move(mock_view));
+
+  ON_CALL(*webauthn_credentials_delegate(), IsWebAuthnAutofillEnabled)
+      .WillByDefault(Return(true));
+
+  TouchToFillWebAuthnCredential credential(u"alice", "12345");
+  std::vector<TouchToFillWebAuthnCredential> credentials({credential});
+
+  EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+                               ElementsAreArray(std::vector<UiCredential>()),
+                               ElementsAreArray(credentials),
+                               /*trigger_submission=*/false));
+  touch_to_fill_controller().Show(
+      {}, credentials, driver().AsWeakPtr(),
+      autofill::mojom::SubmissionReadinessState::kNoInformation);
+
+  EXPECT_CALL(*webauthn_credentials_delegate(),
+              SelectWebAuthnCredential(credential.id()));
+  EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(false)));
+  touch_to_fill_controller().OnWebAuthnCredentialSelected(credentials[0]);
+  histogram_tester().ExpectUniqueSample(
+      "PasswordManager.TouchToFill.NumCredentialsShown", 1, 1);
+  histogram_tester().ExpectUniqueSample(
+      "PasswordManager.TouchToFill.Outcome",
+      TouchToFillController::TouchToFillOutcome::kWebAuthnCredentialSelected,
+      1);
+}
+
 class TouchToFillControllerTestWithSubmissionReadinessVariationTest
     : public TouchToFillControllerTest,
       public testing::WithParamInterface<SubmissionReadinessState> {};
@@ -615,10 +712,13 @@
   // If there is no field after the password, then submit the form.
   bool submission_expected =
       submission_readiness > SubmissionReadinessState::kFieldAfterPasswordField;
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/submission_expected));
-  touch_to_fill_controller().Show(credentials, driver().AsWeakPtr(),
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/submission_expected));
+  touch_to_fill_controller().Show(credentials, {}, driver().AsWeakPtr(),
                                   submission_readiness);
 
   EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(true)));
@@ -642,10 +742,13 @@
   bool submission_expected =
       submission_readiness == SubmissionReadinessState::kTwoFields;
 
-  EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                           ElementsAreArray(credentials),
-                           /*trigger_submission=*/submission_expected));
-  touch_to_fill_controller().Show(credentials, driver().AsWeakPtr(),
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/submission_expected));
+  touch_to_fill_controller().Show(credentials, {}, driver().AsWeakPtr(),
                                   submission_readiness);
 
   EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(true)));
@@ -661,10 +764,13 @@
   UiCredential credentials[] = {
       MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})};
 
-  EXPECT_CALL(view(),
-              Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
-                   ElementsAreArray(credentials), /*trigger_submission=*/_));
-  touch_to_fill_controller().Show(credentials, driver().AsWeakPtr(),
+  EXPECT_CALL(
+      view(),
+      Show(Eq(GURL(kExampleCom)), IsOriginSecure(true),
+           ElementsAreArray(credentials),
+           ElementsAreArray(std::vector<TouchToFillWebAuthnCredential>()),
+           /*trigger_submission=*/_));
+  touch_to_fill_controller().Show(credentials, {}, driver().AsWeakPtr(),
                                   submission_readiness);
 
   EXPECT_CALL(driver(), TouchToFillClosed(ShowVirtualKeyboard(true)));
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_view.h b/chrome/browser/touch_to_fill/touch_to_fill_view.h
index fd2256e2..eb40994 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_view.h
+++ b/chrome/browser/touch_to_fill/touch_to_fill_view.h
@@ -14,6 +14,8 @@
 class UiCredential;
 }
 
+class TouchToFillWebAuthnCredential;
+
 // This class represents the interface used for communicating between the Touch
 // To Fill controller with the Android frontend.
 class TouchToFillView {
@@ -35,6 +37,7 @@
       const GURL& url,
       IsOriginSecure is_origin_secure,
       base::span<const password_manager::UiCredential> credentials,
+      base::span<const TouchToFillWebAuthnCredential> webauthn_credentials,
       bool trigger_submission) = 0;
 
   // Invoked in case the user chooses an entry from the credential list
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.cc b/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.cc
new file mode 100644
index 0000000..496380ca
--- /dev/null
+++ b/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.cc
@@ -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.
+
+#include "chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h"
+
+TouchToFillWebAuthnCredential::TouchToFillWebAuthnCredential(
+    const std::u16string& username,
+    const std::string& backend_id)
+    : username_(username), backend_id_(backend_id) {}
+
+TouchToFillWebAuthnCredential::~TouchToFillWebAuthnCredential() = default;
+
+TouchToFillWebAuthnCredential::TouchToFillWebAuthnCredential(
+    const TouchToFillWebAuthnCredential&) = default;
+TouchToFillWebAuthnCredential& TouchToFillWebAuthnCredential::operator=(
+    const TouchToFillWebAuthnCredential&) = default;
+
+TouchToFillWebAuthnCredential::TouchToFillWebAuthnCredential(
+    TouchToFillWebAuthnCredential&&) = default;
+TouchToFillWebAuthnCredential& TouchToFillWebAuthnCredential::operator=(
+    TouchToFillWebAuthnCredential&&) = default;
+
+bool operator==(const TouchToFillWebAuthnCredential& lhs,
+                const TouchToFillWebAuthnCredential& rhs) {
+  auto tie = [](const TouchToFillWebAuthnCredential& cred) {
+    return std::make_tuple(std::cref(cred.username()), std::cref(cred.id()));
+  };
+
+  return tie(lhs) == tie(rhs);
+}
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h b/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.h
new file mode 100644
index 0000000..3815fa7
--- /dev/null
+++ b/chrome/browser/touch_to_fill/touch_to_fill_webauthn_credential.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 CHROME_BROWSER_TOUCH_TO_FILL_TOUCH_TO_FILL_WEBAUTHN_CREDENTIAL_H_
+#define CHROME_BROWSER_TOUCH_TO_FILL_TOUCH_TO_FILL_WEBAUTHN_CREDENTIAL_H_
+
+#include <string>
+
+// Represents a Web Authentication credential to be displayed on the
+// Touch-To-Fill sheet for user selection.
+class TouchToFillWebAuthnCredential {
+ public:
+  TouchToFillWebAuthnCredential(const std::u16string& username,
+                                const std::string& backend_id);
+  ~TouchToFillWebAuthnCredential();
+
+  TouchToFillWebAuthnCredential(const TouchToFillWebAuthnCredential&);
+  TouchToFillWebAuthnCredential& operator=(
+      const TouchToFillWebAuthnCredential&);
+
+  TouchToFillWebAuthnCredential(TouchToFillWebAuthnCredential&&);
+  TouchToFillWebAuthnCredential& operator=(TouchToFillWebAuthnCredential&&);
+
+  const std::u16string& username() const { return username_; }
+
+  const std::string& id() const { return backend_id_; }
+
+ private:
+  std::u16string username_;
+  std::string backend_id_;
+};
+
+bool operator==(const TouchToFillWebAuthnCredential& lhs,
+                const TouchToFillWebAuthnCredential& rhs);
+
+#endif  // CHROME_BROWSER_TOUCH_TO_FILL_TOUCH_TO_FILL_WEBAUTHN_CREDENTIAL_H_
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 13a61b7e..158e826 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1223,9 +1223,10 @@
       "pdf/chrome_pdf_web_contents_helper_client.cc",
       "pdf/chrome_pdf_web_contents_helper_client.h",
       "permission_bubble/permission_prompt.h",
-      "privacy_sandbox/privacy_sandbox_dialog.h",
-      "privacy_sandbox/privacy_sandbox_dialog_helper.cc",
-      "privacy_sandbox/privacy_sandbox_dialog_helper.h",
+      "privacy_sandbox/privacy_sandbox_prompt.cc",
+      "privacy_sandbox/privacy_sandbox_prompt.h",
+      "privacy_sandbox/privacy_sandbox_prompt_helper.cc",
+      "privacy_sandbox/privacy_sandbox_prompt_helper.h",
       "sad_tab.cc",
       "sad_tab.h",
       "sad_tab_helper.cc",
@@ -1674,6 +1675,8 @@
       "webui/side_panel/bookmarks/bookmarks_page_handler.h",
       "webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc",
       "webui/side_panel/bookmarks/bookmarks_side_panel_ui.h",
+      "webui/side_panel/history_clusters/history_clusters_side_panel_ui.cc",
+      "webui/side_panel/history_clusters/history_clusters_side_panel_ui.h",
       "webui/side_panel/read_anything/read_anything_page_handler.cc",
       "webui/side_panel/read_anything/read_anything_page_handler.h",
       "webui/side_panel/read_anything/read_anything_ui.cc",
@@ -3340,6 +3343,8 @@
       "views/hats/hats_next_web_dialog.h",
       "views/privacy_sandbox/privacy_sandbox_dialog_view.cc",
       "views/privacy_sandbox/privacy_sandbox_dialog_view.h",
+      "views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc",
+      "views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h",
       "views/profiles/incognito_menu_view.cc",
       "views/profiles/incognito_menu_view.h",
       "views/profiles/profile_menu_view_base.cc",
@@ -3858,7 +3863,7 @@
     # to fail on this variant. Since this target is only referenced (but not
     # compiled) on this variant, it's okay to add this "incorrect" dependency
     # to Cast Linux builds so that `gn check` passes.
-    if (toolkit_views || (is_chromecast && (is_linux || is_chromeos))) {
+    if (toolkit_views || (is_castos && (is_linux || is_chromeos))) {
       public_deps += [
         "//ui/views",
         "//ui/views/controls/webview",
@@ -4027,7 +4032,6 @@
       "send_tab_to_self/send_tab_to_self_toolbar_icon_controller_delegate.h",
       "sharing_hub/screenshot/screenshot_captured_bubble_controller.cc",
       "sharing_hub/screenshot/screenshot_captured_bubble_controller.h",
-      "sharing_hub/sharing_hub_bubble_controller.cc",
       "sharing_hub/sharing_hub_bubble_controller.h",
       "sharing_hub/sharing_hub_bubble_view.h",
 
@@ -4714,6 +4718,8 @@
       "views/side_panel/bookmarks/bookmarks_side_panel_coordinator.h",
       "views/side_panel/feed/feed_side_panel_coordinator.cc",
       "views/side_panel/feed/feed_side_panel_coordinator.h",
+      "views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc",
+      "views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h",
       "views/side_panel/read_anything/read_anything_constants.h",
       "views/side_panel/read_anything/read_anything_container_view.cc",
       "views/side_panel/read_anything/read_anything_container_view.h",
@@ -5045,7 +5051,11 @@
       ]
     }
     if (is_chromeos) {
-      sources += [ "views/status_icons/status_tray_chromeos.cc" ]
+      sources += [
+        "sharing_hub/sharing_hub_bubble_controller_chromeos_impl.cc",
+        "sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h",
+        "views/status_icons/status_tray_chromeos.cc",
+      ]
       deps += [ "//components/arc/common:arc_intent_helper_constants" ]
     }
     if (is_fuchsia) {
@@ -5141,6 +5151,8 @@
 
     if (!is_chromeos) {
       sources += [
+        "sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc",
+        "sharing_hub/sharing_hub_bubble_controller_desktop_impl.h",
         "views/frame/opaque_browser_frame_view.cc",
         "views/frame/opaque_browser_frame_view.h",
         "views/frame/opaque_browser_frame_view_layout.cc",
diff --git a/chrome/browser/ui/android/appmenu/BUILD.gn b/chrome/browser/ui/android/appmenu/BUILD.gn
index 5333a4aa..8603011 100644
--- a/chrome/browser/ui/android/appmenu/BUILD.gn
+++ b/chrome/browser/ui/android/appmenu/BUILD.gn
@@ -22,7 +22,6 @@
   ]
   deps = [
     ":java_resources",
-    "//base:base_java",
     "//chrome/browser/android/lifecycle:java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//ui/android:ui_java",
diff --git a/chrome/browser/ui/android/appmenu/test/BUILD.gn b/chrome/browser/ui/android/appmenu/test/BUILD.gn
index f99eeb8..30cf96e 100644
--- a/chrome/browser/ui/android/appmenu/test/BUILD.gn
+++ b/chrome/browser/ui/android/appmenu/test/BUILD.gn
@@ -12,7 +12,6 @@
     "java/src/org/chromium/chrome/browser/ui/appmenu/TestAppMenuObserver.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/browser/ui/android/appmenu:java",
diff --git a/chrome/browser/ui/android/autofill/internal/BUILD.gn b/chrome/browser/ui/android/autofill/internal/BUILD.gn
index 5dae98e..af5f6d5 100644
--- a/chrome/browser/ui/android/autofill/internal/BUILD.gn
+++ b/chrome/browser/ui/android/autofill/internal/BUILD.gn
@@ -66,7 +66,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/chrome/browser/ui/android/autofill/test/BUILD.gn b/chrome/browser/ui/android/autofill/test/BUILD.gn
index b4e7452..2240eb6 100644
--- a/chrome/browser/ui/android/autofill/test/BUILD.gn
+++ b/chrome/browser/ui/android/autofill/test/BUILD.gn
@@ -15,7 +15,6 @@
   ]
   sources = [ "java/src/org/chromium/chrome/browser/ui/autofill/FakeModalDialogManager.java" ]
   deps = [
-    "//base:base_java",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
diff --git a/chrome/browser/ui/android/logo/BUILD.gn b/chrome/browser/ui/android/logo/BUILD.gn
index d7183ff..2e80cffc 100644
--- a/chrome/browser/ui/android/logo/BUILD.gn
+++ b/chrome/browser/ui/android/logo/BUILD.gn
@@ -61,7 +61,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//chrome/browser/search_engines/android:java",
     "//chrome/test/android:chrome_java_test_support",
diff --git a/chrome/browser/ui/android/management/BUILD.gn b/chrome/browser/ui/android/management/BUILD.gn
index b7d5734..f2b242ef 100644
--- a/chrome/browser/ui/android/management/BUILD.gn
+++ b/chrome/browser/ui/android/management/BUILD.gn
@@ -15,7 +15,6 @@
   ]
   deps = [
     ":java_resources",
-    "//base:base_java",
     "//chrome/browser/enterprise/util:java",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/tab:java",
diff --git a/chrome/browser/ui/android/multiwindow/BUILD.gn b/chrome/browser/ui/android/multiwindow/BUILD.gn
index e543cb4..8342691 100644
--- a/chrome/browser/ui/android/multiwindow/BUILD.gn
+++ b/chrome/browser/ui/android/multiwindow/BUILD.gn
@@ -106,7 +106,6 @@
 
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/browser/flags:java",
diff --git a/chrome/browser/ui/android/webid/BUILD.gn b/chrome/browser/ui/android/webid/BUILD.gn
index 4b483dd..7db653b 100644
--- a/chrome/browser/ui/android/webid/BUILD.gn
+++ b/chrome/browser/ui/android/webid/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("public_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//components/browser_ui/bottomsheet/android:java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
index 5ddc9c6..3fe07fc 100644
--- a/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/app_search_provider_unittest.cc
@@ -175,9 +175,10 @@
   void CreateSearch() {
     clock_.SetNow(kTestCurrentTime);
     search_controller_ = std::make_unique<TestSearchController>();
-    app_search_ = std::make_unique<AppSearchProvider>(
+    auto app_search = std::make_unique<AppSearchProvider>(
         profile_.get(), nullptr, &clock_, model_updater_.get());
-    app_search_->set_controller(search_controller_.get());
+    app_search_ = app_search.get();
+    search_controller_->AddProvider(0, std::move(app_search));
   }
 
   void CreateSearchWithContinueReading() {
@@ -194,7 +195,7 @@
   }
 
   std::string RunQuery(const std::string& query) {
-    app_search_->Start(base::UTF8ToUTF16(query));
+    search_controller_->StartSearch(base::UTF8ToUTF16(query));
 
     // Sort results by relevance.
     std::vector<ChromeSearchResult*> sorted_results;
@@ -221,7 +222,7 @@
   // container based on index flags instead of relevance, use this methodology
   // to generate list of test results.
   std::string RunQueryNotSortingByRelevance(const std::string& query) {
-    app_search_->Start(base::UTF8ToUTF16(query));
+    search_controller_->StartSearch(base::UTF8ToUTF16(query));
 
     std::vector<ChromeSearchResult*> non_relevance_results;
     std::vector<ChromeSearchResult*> priority_results;
@@ -329,7 +330,7 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<FakeAppListModelUpdater> model_updater_;
   std::unique_ptr<TestSearchController> search_controller_;
-  std::unique_ptr<AppSearchProvider> app_search_;
+  AppSearchProvider* app_search_ = nullptr;
   std::unique_ptr<::test::TestAppListControllerDelegate> controller_;
   ArcAppTest arc_test_;
 
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
index a804731..084fb36 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcuts_search_provider_unittest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_test.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
+#include "chrome/browser/ui/app_list/search/test/test_search_controller.h"
 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -109,13 +110,18 @@
   const size_t kMaxResults = launchable ? 4 : 0;
   constexpr char16_t kQuery[] = u"shortlabel";
 
+  TestSearchController search_controller;
   auto provider = std::make_unique<ArcAppShortcutsSearchProvider>(
       kMaxResults, profile(), controller_.get());
-  EXPECT_TRUE(provider->results().empty());
+  ArcAppShortcutsSearchProvider* provider_ptr = provider.get();
+  search_controller.AddProvider(0, std::move(provider));
+  EXPECT_TRUE(search_controller.last_results().empty());
   arc::IconDecodeRequest::DisableSafeDecodingForTesting();
 
-  provider->Start(kQuery);
-  const auto& results = provider->results();
+  search_controller.StartSearch(kQuery);
+  const auto& results = app_list_features::IsCategoricalSearchEnabled()
+                            ? search_controller.last_results()
+                            : provider_ptr->results();
   EXPECT_EQ(kMaxResults, results.size());
   // Verify search results.
   for (size_t i = 0; i < results.size(); ++i) {
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
index 77dacde4..3eb95ed 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
@@ -120,6 +120,7 @@
     arc::ArcPlayStoreSearchRequestState state,
     std::vector<arc::mojom::AppDiscoveryResultPtr> results) {
   if (state != arc::ArcPlayStoreSearchRequestState::SUCCESS) {
+    ClearResults();
     DCHECK(
         state ==
             arc::ArcPlayStoreSearchRequestState::PHONESKY_RESULT_INVALID_DATA ||
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc
index cf45671a..b08b382 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc
@@ -9,11 +9,13 @@
 #include <utility>
 
 #include "ash/components/arc/app/arc_playstore_search_request_state.h"
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/chromeos/arc/icon_decode_request.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/ui/app_list/app_list_test_util.h"
@@ -28,9 +30,15 @@
 
 namespace app_list {
 
-class ArcPlayStoreSearchProviderTest : public AppListTestBase {
+// Parameterized by feature ProductivityLauncher.
+class ArcPlayStoreSearchProviderTest
+    : public AppListTestBase,
+      public ::testing::WithParamInterface<bool> {
  public:
-  ArcPlayStoreSearchProviderTest() = default;
+  ArcPlayStoreSearchProviderTest() {
+    feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
+                                       GetParam());
+  }
 
   ArcPlayStoreSearchProviderTest(const ArcPlayStoreSearchProviderTest&) =
       delete;
@@ -55,12 +63,13 @@
  protected:
   void CreateSearch(int max_results) {
     search_controller_ = std::make_unique<TestSearchController>();
-    provider_ = std::make_unique<ArcPlayStoreSearchProvider>(
+    auto provider = std::make_unique<ArcPlayStoreSearchProvider>(
         max_results, profile_.get(), controller_.get());
-    provider_->set_controller(search_controller_.get());
+    provider_ = provider.get();
+    search_controller_->AddProvider(0, std::move(provider));
   }
 
-  ArcPlayStoreSearchProvider* provider() { return provider_.get(); }
+  ArcPlayStoreSearchProvider* provider() { return provider_; }
 
   const SearchProvider::Results& LastResults() {
     if (app_list_features::IsCategoricalSearchEnabled()) {
@@ -70,6 +79,10 @@
     }
   }
 
+  void StartSearch(const std::u16string& query) {
+    search_controller_->StartSearch(query);
+  }
+
   scoped_refptr<const extensions::Extension> CreateExtension(
       const std::string& id) {
     return extensions::ExtensionBuilder("test").SetID(id).Build();
@@ -80,13 +93,18 @@
   }
 
  private:
+  base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<::test::TestAppListControllerDelegate> controller_;
   std::unique_ptr<TestSearchController> search_controller_;
-  std::unique_ptr<ArcPlayStoreSearchProvider> provider_;
+  ArcPlayStoreSearchProvider* provider_ = nullptr;
   ArcAppTest arc_test_;
 };
 
-TEST_F(ArcPlayStoreSearchProviderTest, Basic) {
+INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
+                         ArcPlayStoreSearchProviderTest,
+                         testing::Bool());
+
+TEST_P(ArcPlayStoreSearchProviderTest, Basic) {
   constexpr size_t kMaxResults = 12;
   constexpr char16_t kQuery[] = u"Play App";
 
@@ -97,7 +115,7 @@
   AddExtension(CreateExtension(extension_misc::kGmailAppId).get());
 
   // Check that the result size of a query doesn't exceed the |kMaxResults|.
-  provider()->Start(kQuery);
+  StartSearch(kQuery);
   const SearchProvider::Results& results = LastResults();
   ASSERT_GT(results.size(), 0u);
   // Play Store returns |kMaxResults| results, but the first one (GMail) already
@@ -123,7 +141,7 @@
 // non empty result list and PHONESKY_RESULT_INVALID_DATA status code (which can
 // happen if the Play Store returns a list of results that contains some invalid
 // items).
-TEST_F(ArcPlayStoreSearchProviderTest, PartiallyFailedQuery) {
+TEST_P(ArcPlayStoreSearchProviderTest, PartiallyFailedQuery) {
   constexpr size_t kMaxResults = 12;
 
   CreateSearch(kMaxResults);
@@ -137,7 +155,7 @@
       base::NumberToString16(static_cast<int>(
           arc::ArcPlayStoreSearchRequestState::PHONESKY_RESULT_INVALID_DATA));
 
-  provider()->Start(kQuery);
+  StartSearch(kQuery);
 
   const SearchProvider::Results& results = LastResults();
   ASSERT_GT(results.size(), 0u);
@@ -163,7 +181,7 @@
 
 // Tests that the search provider can handle Play Store suggestions without
 // rating and formatted price.
-TEST_F(ArcPlayStoreSearchProviderTest, ResultsWithoutPriceAndRating) {
+TEST_P(ArcPlayStoreSearchProviderTest, ResultsWithoutPriceAndRating) {
   constexpr size_t kMaxResults = 12;
 
   CreateSearch(kMaxResults);
@@ -174,7 +192,7 @@
 
   const std::u16string kQuery = u"QueryWithoutRatingAndPrice";
 
-  provider()->Start(kQuery);
+  StartSearch(kQuery);
 
   const SearchProvider::Results& results = LastResults();
   ASSERT_GT(results.size(), 0u);
@@ -198,7 +216,7 @@
 }
 
 // Tests that results without icon are ignored.
-TEST_F(ArcPlayStoreSearchProviderTest, IgnoreResultsWithoutIcon) {
+TEST_P(ArcPlayStoreSearchProviderTest, IgnoreResultsWithoutIcon) {
   constexpr size_t kMaxResults = 12;
 
   CreateSearch(kMaxResults);
@@ -209,7 +227,7 @@
 
   const std::u16string kQuery = u"QueryWithSomeResultsMissingIcon";
 
-  provider()->Start(kQuery);
+  StartSearch(kQuery);
 
   const SearchProvider::Results& results = LastResults();
   ASSERT_GT(results.size(), 0u);
@@ -235,7 +253,7 @@
   }
 }
 
-TEST_F(ArcPlayStoreSearchProviderTest, FailedQuery) {
+TEST_P(ArcPlayStoreSearchProviderTest, FailedQuery) {
   constexpr size_t kMaxResults = 12;
   constexpr char16_t kQuery[] = u"Play App";
 
@@ -245,7 +263,7 @@
 
   // Test for empty queries.
   // Create a non-empty query.
-  provider()->Start(kQuery);
+  StartSearch(kQuery);
   EXPECT_GT(LastResults().size(), 0u);
 
   // Test for queries with a failure state code.
@@ -273,12 +291,12 @@
       "Missing entries");
   for (const auto& error_state : kErrorStates) {
     // Create a non-empty query.
-    provider()->Start(kQuery);
+    StartSearch(kQuery);
     EXPECT_GT(LastResults().size(), 0u);
 
     // Fabricate a failing query and it should clear the result list.
-    provider()->Start(kFailedQueryPrefix +
-                      base::NumberToString16(static_cast<int>(error_state)));
+    StartSearch(kFailedQueryPrefix +
+                base::NumberToString16(static_cast<int>(error_state)));
     EXPECT_EQ(0u, LastResults().size());
   }
 }
diff --git a/chrome/browser/ui/app_list/search/assistant_text_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/assistant_text_search_provider_unittest.cc
index c2f353a..441523a 100644
--- a/chrome/browser/ui/app_list/search/assistant_text_search_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/assistant_text_search_provider_unittest.cc
@@ -31,7 +31,9 @@
   AssistantTextSearchProviderTest() {
     feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
                                        GetParam());
-    search_provider_.set_controller(&search_controller_);
+    auto search_provider = std::make_unique<AssistantTextSearchProvider>();
+    search_provider_ = search_provider.get();
+    search_controller_.AddProvider(0, std::move(search_provider));
   }
   AssistantTextSearchProviderTest(const AssistantTextSearchProviderTest&) =
       delete;
@@ -40,11 +42,9 @@
   ~AssistantTextSearchProviderTest() override = default;
 
   void SendText(const std::string& text) {
-    search_provider_.Start(base::UTF8ToUTF16(text));
+    search_controller_.StartSearch(base::UTF8ToUTF16(text));
   }
 
-  AssistantTextSearchProvider& search_provider() { return search_provider_; }
-
   ash::MockAssistantState& assistant_state() { return assistant_state_; }
 
   testing::NiceMock<ash::MockAssistantController>& assistant_controller() {
@@ -55,7 +55,7 @@
     if (app_list_features::IsCategoricalSearchEnabled()) {
       return search_controller_.last_results();
     } else {
-      return search_provider_.results();
+      return search_provider_->results();
     }
   }
 
@@ -76,7 +76,7 @@
   ash::MockAssistantState assistant_state_;
   testing::NiceMock<ash::MockAssistantController> assistant_controller_;
   TestSearchController search_controller_;
-  AssistantTextSearchProvider search_provider_;
+  AssistantTextSearchProvider* search_provider_ = nullptr;
 };
 
 INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
diff --git a/chrome/browser/ui/app_list/search/common/icon_constants.cc b/chrome/browser/ui/app_list/search/common/icon_constants.cc
index 48cb5c4..0488d41f 100644
--- a/chrome/browser/ui/app_list/search/common/icon_constants.cc
+++ b/chrome/browser/ui/app_list/search/common/icon_constants.cc
@@ -28,8 +28,10 @@
 }
 
 SkColor GetGenericIconColor() {
-  if (ash::features::IsProductivityLauncherEnabled()) {
-    return ash::ColorProvider::Get()->GetContentLayerColor(
+  // May be null in tests.
+  ash::ColorProvider* const color_provider = ash::ColorProvider::Get();
+  if (color_provider && ash::features::IsProductivityLauncherEnabled()) {
+    return color_provider->GetContentLayerColor(
         ash::ColorProvider::ContentLayerType::kButtonIconColor);
   }
   return kOmniboxGenericIconColor;
diff --git a/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc b/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc
index 60a7fba..af18d1e 100644
--- a/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/files/zero_state_file_provider_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/public/cpp/test/test_app_list_color_provider.h"
 #include "base/files/file_path.h"
@@ -16,6 +17,7 @@
 #include "base/test/task_environment.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
+#include "chrome/browser/ui/app_list/search/test/test_search_controller.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -34,14 +36,26 @@
 
 }  // namespace
 
-class ZeroStateFileProviderTest : public testing::Test {
+// Parameterized by feature ProductivityLauncher.
+class ZeroStateFileProviderTest : public testing::Test,
+                                  public ::testing::WithParamInterface<bool> {
  protected:
+  ZeroStateFileProviderTest() {
+    feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
+                                       GetParam());
+  }
+  ~ZeroStateFileProviderTest() override = default;
+
   void SetUp() override {
-    profile_ = std::make_unique<TestingProfile>();
-    provider_ = std::make_unique<ZeroStateFileProvider>(profile_.get());
     app_list_color_provider_ =
         std::make_unique<ash::TestAppListColorProvider>();
 
+    profile_ = std::make_unique<TestingProfile>();
+
+    auto provider = std::make_unique<ZeroStateFileProvider>(profile_.get());
+    provider_ = provider.get();
+    search_controller_.AddProvider(0, std::move(provider));
+
     Wait();
   }
 
@@ -64,25 +78,47 @@
     return e;
   }
 
+  void StartSearch(const std::u16string& query) {
+    search_controller_.StartSearch(query);
+  }
+
+  void StartZeroStateSearch() {
+    search_controller_.StartZeroState(base::DoNothing(), base::TimeDelta());
+  }
+
+  const SearchProvider::Results& LastResults() {
+    if (app_list_features::IsCategoricalSearchEnabled()) {
+      return search_controller_.last_results();
+    }
+
+    return provider_->results();
+  }
+
   void Wait() { task_environment_.RunUntilIdle(); }
 
   content::BrowserTaskEnvironment task_environment_;
-  base::test::ScopedFeatureList scoped_feature_list_;
+  base::test::ScopedFeatureList feature_list_;
 
   std::unique_ptr<Profile> profile_;
-  std::unique_ptr<ZeroStateFileProvider> provider_;
+  TestSearchController search_controller_;
+  ZeroStateFileProvider* provider_ = nullptr;
   std::unique_ptr<ash::TestAppListColorProvider> app_list_color_provider_;
 };
 
-TEST_F(ZeroStateFileProviderTest, NoResultsWithQuery) {
-  provider_->Start(u"query");
+INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
+                         ZeroStateFileProviderTest,
+                         testing::Bool());
+
+TEST_P(ZeroStateFileProviderTest, NoResultsWithQuery) {
+  StartSearch(u"query");
   Wait();
-  EXPECT_TRUE(provider_->results().empty());
+  EXPECT_TRUE(LastResults().empty());
 }
 
-TEST_F(ZeroStateFileProviderTest, ResultsProvided) {
+TEST_P(ZeroStateFileProviderTest, ResultsProvided) {
   // Disable flag.
-  scoped_feature_list_.InitWithFeatures(
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures(
       {}, {app_list_features::kEnableSuggestedLocalFiles});
 
   WriteFile("exists_1.txt");
@@ -93,17 +129,17 @@
       {OpenEvent("exists_1.txt"), OpenEvent("exists_2.png")});
   provider_->OnFilesOpened({OpenEvent("nonexistant.txt")});
 
-  provider_->StartZeroState();
+  StartZeroStateSearch();
   Wait();
 
-  EXPECT_THAT(
-      provider_->results(),
-      UnorderedElementsAre(Title("exists_1.txt"), Title("exists_2.png")));
+  EXPECT_THAT(LastResults(), UnorderedElementsAre(Title("exists_1.txt"),
+                                                  Title("exists_2.png")));
 }
 
-TEST_F(ZeroStateFileProviderTest, OldFilesNotReturned) {
+TEST_P(ZeroStateFileProviderTest, OldFilesNotReturned) {
   // Disable flag.
-  scoped_feature_list_.InitWithFeatures(
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures(
       {}, {app_list_features::kEnableSuggestedLocalFiles});
 
   WriteFile("new.txt");
@@ -113,10 +149,10 @@
 
   provider_->OnFilesOpened({OpenEvent("new.txt"), OpenEvent("old.png")});
 
-  provider_->StartZeroState();
+  StartZeroStateSearch();
   Wait();
 
-  EXPECT_THAT(provider_->results(), UnorderedElementsAre(Title("new.txt")));
+  EXPECT_THAT(LastResults(), UnorderedElementsAre(Title("new.txt")));
 }
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc b/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
index cbf12999..137ebfa4 100644
--- a/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/games/game_provider_unittest.cc
@@ -4,9 +4,11 @@
 
 #include "chrome/browser/ui/app_list/search/games/game_provider.h"
 
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
 #include "base/files/file_path.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/apps/app_discovery_service/app_discovery_service.h"
 #include "chrome/browser/apps/app_discovery_service/app_discovery_service_factory.h"
@@ -41,15 +43,24 @@
 
 }  // namespace
 
-class GameProviderTest : public testing::Test {
+// Parameterized by feature ProductivityLauncher.
+class GameProviderTest : public testing::Test,
+                         public testing::WithParamInterface<bool> {
+ public:
+  GameProviderTest() {
+    feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
+                                       GetParam());
+  }
+
  protected:
   void SetUp() override {
     profile_ = std::make_unique<TestingProfile>();
-    provider_ =
+    auto provider =
         std::make_unique<GameProvider>(profile_.get(), &list_controller_);
+    provider_ = provider.get();
 
     search_controller_ = std::make_unique<TestSearchController>();
-    provider_->set_controller(search_controller_.get());
+    search_controller_->AddProvider(0, std::move(provider));
   }
 
   const SearchProvider::Results& LastResults() {
@@ -70,24 +81,33 @@
 
   void Wait() { task_environment_.RunUntilIdle(); }
 
+  void StartSearch(const std::u16string& query) {
+    search_controller_->StartSearch(query);
+  }
+
+  base::test::ScopedFeatureList feature_list_;
   content::BrowserTaskEnvironment task_environment_;
   ::test::TestAppListControllerDelegate list_controller_;
   std::unique_ptr<TestSearchController> search_controller_;
   std::unique_ptr<Profile> profile_;
 
-  std::unique_ptr<GameProvider> provider_;
+  GameProvider* provider_ = nullptr;
 };
 
+INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
+                         GameProviderTest,
+                         testing::Bool());
+
 // TODO(crbug.com/1305880): Enable this test once the app discovery service
 // backend has been implemented.
-TEST_F(GameProviderTest, DISABLED_SearchResultsMatchQuery) {
+TEST_P(GameProviderTest, DISABLED_SearchResultsMatchQuery) {
   SetUpTestingIndex();
 
-  provider_->Start(u"first");
+  StartSearch(u"first");
   Wait();
   EXPECT_THAT(LastResults(), ElementsAre(Title("First Title")));
 
-  provider_->Start(u"title");
+  StartSearch(u"title");
   Wait();
   EXPECT_THAT(LastResults(),
               UnorderedElementsAre(Title("First Title"), Title("Second Title"),
diff --git a/chrome/browser/ui/app_list/search/help_app_zero_state_provider_unittest.cc b/chrome/browser/ui/app_list/search/help_app_zero_state_provider_unittest.cc
index 93c349a..c49ef68 100644
--- a/chrome/browser/ui/app_list/search/help_app_zero_state_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/help_app_zero_state_provider_unittest.cc
@@ -86,9 +86,10 @@
           std::make_unique<AppListNotifierImplOld>(&app_list_controller_);
     }
 
-    provider_ = std::make_unique<HelpAppZeroStateProvider>(
+    auto provider = std::make_unique<HelpAppZeroStateProvider>(
         profile(), app_list_notifier_.get());
-    provider_->set_controller(&search_controller_);
+    provider_ = provider.get();
+    search_controller_.AddProvider(0, std::move(provider));
   }
 
   ash::SearchResultDisplayType GetExpectedReleaseNotesDisplayType() {
@@ -101,13 +102,17 @@
                       : IDS_HELP_APP_WHATS_NEW_SUGGESTION_CHIP;
   }
 
+  void StartZeroStateSearch() {
+    search_controller_.StartZeroState(base::DoNothing(), base::TimeDelta());
+  }
+
   const app_list::Results& GetLatestResults() {
     // When productivity launcher (and thus categorical search) is enabled,
     // results are managed by the search controller instead of individual search
     // providers.
     if (GetParam())
       return search_controller_.last_results();
-    return provider()->results();
+    return provider_->results();
   }
 
   ::test::TestAppListController* app_list_controller() {
@@ -116,13 +121,11 @@
 
   ash::AppListNotifier* app_list_notifier() { return app_list_notifier_.get(); }
 
-  HelpAppZeroStateProvider* provider() { return provider_.get(); }
-
  private:
   ::test::TestAppListController app_list_controller_;
   std::unique_ptr<ash::AppListNotifier> app_list_notifier_;
   TestSearchController search_controller_;
-  std::unique_ptr<HelpAppZeroStateProvider> provider_;
+  HelpAppZeroStateProvider* provider_ = nullptr;
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
@@ -138,7 +141,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   EXPECT_TRUE(GetLatestResults().empty());
 }
@@ -150,7 +153,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   ASSERT_EQ(GetParam() ? 0u : 1u, GetLatestResults().size());
   if (GetParam())
@@ -167,7 +170,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   ASSERT_EQ(1u, GetLatestResults().size());
   ChromeSearchResult* result = GetLatestResults().at(0).get();
@@ -181,7 +184,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   ASSERT_EQ(1u, GetLatestResults().size());
 
@@ -199,7 +202,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   if (GetParam()) {
     EXPECT_EQ(0u, GetLatestResults().size());
@@ -232,7 +235,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   ASSERT_EQ(1u, GetLatestResults().size());
 
@@ -271,7 +274,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kDiscoverTabSuggestionChipTimesLeftToShow, 3);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   if (GetParam()) {
     EXPECT_EQ(0u, GetLatestResults().size());
@@ -291,7 +294,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 3);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   ChromeSearchResult* result = GetLatestResults().at(0).get();
   result->Open(/*event_flags=*/0);
@@ -325,7 +328,7 @@
   profile()->GetPrefs()->SetInteger(
       prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0);
 
-  provider()->StartZeroState();
+  StartZeroStateSearch();
 
   EXPECT_TRUE(GetLatestResults().empty());
 }
diff --git a/chrome/browser/ui/app_list/search/keyboard_shortcut_provider_unittest.cc b/chrome/browser/ui/app_list/search/keyboard_shortcut_provider_unittest.cc
index 687a10c0..2ffef32 100644
--- a/chrome/browser/ui/app_list/search/keyboard_shortcut_provider_unittest.cc
+++ b/chrome/browser/ui/app_list/search/keyboard_shortcut_provider_unittest.cc
@@ -4,7 +4,9 @@
 
 #include "chrome/browser/ui/app_list/search/keyboard_shortcut_provider.h"
 
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
 #include "chrome/browser/ui/app_list/search/test/test_search_controller.h"
 #include "chrome/test/base/testing_profile.h"
@@ -15,7 +17,16 @@
 
 namespace app_list {
 
-class KeyboardShortcutProviderTest : public testing::Test {
+// Parameterized by feature ProductivityLauncher.
+class KeyboardShortcutProviderTest
+    : public testing::Test,
+      public ::testing::WithParamInterface<bool> {
+ public:
+  KeyboardShortcutProviderTest() {
+    feature_list_.InitWithFeatureState(ash::features::kProductivityLauncher,
+                                       GetParam());
+  }
+
  protected:
   void SetUp() override {
     // A DCHECK inside a KSV metadata utility function relies on device lists
@@ -24,8 +35,10 @@
 
     profile_ = std::make_unique<TestingProfile>();
     search_controller_ = std::make_unique<TestSearchController>();
-    provider_ = std::make_unique<KeyboardShortcutProvider>(profile_.get());
-    provider_->set_controller(search_controller_.get());
+    auto provider = std::make_unique<KeyboardShortcutProvider>(profile_.get());
+    provider_ = provider.get();
+    search_controller_->AddProvider(0, std::move(provider));
+
     Wait();
   }
 
@@ -39,19 +52,28 @@
     }
   }
 
+  void StartSearch(const std::u16string& query) {
+    search_controller_->StartSearch(query);
+  }
+
+  base::test::ScopedFeatureList feature_list_;
   content::BrowserTaskEnvironment task_environment_;
 
   std::unique_ptr<Profile> profile_;
   std::unique_ptr<TestSearchController> search_controller_;
-  std::unique_ptr<KeyboardShortcutProvider> provider_;
+  KeyboardShortcutProvider* provider_ = nullptr;
 };
 
+INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
+                         KeyboardShortcutProviderTest,
+                         testing::Bool());
+
 // Make search queries which yield shortcut results with shortcut key
 // combinations of differing length and format. Check that the top result has a
 // high relevance score, and correctly set title and accessible name.
-TEST_F(KeyboardShortcutProviderTest, Search) {
+TEST_P(KeyboardShortcutProviderTest, Search) {
   // Result format: Single Key
-  provider_->Start(u"overview mode");
+  StartSearch(u"overview mode");
   Wait();
 
   ASSERT_FALSE(results().empty());
@@ -61,7 +83,7 @@
             u"Overview mode, Shortcuts, Overview mode key");
 
   // Result format: Modifier + Key
-  provider_->Start(u"lock");
+  StartSearch(u"lock");
   Wait();
 
   ASSERT_FALSE(results().empty());
@@ -71,7 +93,7 @@
             u"Lock screen, Shortcuts, Search+ l");
 
   // Result format: Modifier1 + Modifier2 + Key
-  provider_->Start(u"previous tab");
+  StartSearch(u"previous tab");
   Wait();
 
   ASSERT_FALSE(results().empty());
@@ -81,7 +103,7 @@
             u"Go to previous tab, Shortcuts, Ctrl+ Shift+ Tab");
 
   // Result format: Modifier1 + Key1 or Modifier2 + Key2
-  provider_->Start(u"focus address");
+  StartSearch(u"focus address");
   Wait();
 
   ASSERT_FALSE(results().empty());
@@ -91,7 +113,7 @@
             u"Focus address bar, Shortcuts, Ctrl+ l or Alt+ d");
 
   // Result format: Custom template string which embeds a Modifier and a Key.
-  provider_->Start(u"switch quickly between windows");
+  StartSearch(u"switch quickly between windows");
   Wait();
 
   ASSERT_FALSE(results().empty());
@@ -103,7 +125,7 @@
       u"until you get to the window you want to open, then release.");
 
   // Result format: Special case result for Take screenshot/recording.
-  provider_->Start(u"take screenshot");
+  StartSearch(u"take screenshot");
   Wait();
 
   ASSERT_FALSE(results().empty());
diff --git a/chrome/browser/ui/app_list/search/mixer_unittest.cc b/chrome/browser/ui/app_list/search/mixer_unittest.cc
index 2d473ea..4722e1c 100644
--- a/chrome/browser/ui/app_list/search/mixer_unittest.cc
+++ b/chrome/browser/ui/app_list/search/mixer_unittest.cc
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "ash/public/cpp/app_list/app_list_metrics.h"
 #include "ash/public/cpp/app_list/app_list_types.h"
@@ -136,7 +137,10 @@
 
 class MixerTest : public testing::Test {
  public:
-  MixerTest() {}
+  MixerTest() {
+    scoped_feature_list_.InitAndDisableFeature(
+        ash::features::kProductivityLauncher);
+  }
 
   MixerTest(const MixerTest&) = delete;
   MixerTest& operator=(const MixerTest&) = delete;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
index 5021295..2f2a31ad 100644
--- a/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
+++ b/chrome/browser/ui/app_list/search/search_controller_impl_new.cc
@@ -42,42 +42,9 @@
 namespace app_list {
 namespace {
 
-bool IsPartOfContinueSection(ProviderType type) {
-  switch (type) {
-    case ash::AppListSearchResultType::kZeroStateFile:
-    case ash::AppListSearchResultType::kZeroStateDrive:
-    case ash::AppListSearchResultType::kZeroStateHelpApp:
-      return true;
-    case ash::AppListSearchResultType::kUnknown:
-    case ash::AppListSearchResultType::kInstalledApp:
-    case ash::AppListSearchResultType::kPlayStoreApp:
-    case ash::AppListSearchResultType::kInstantApp:
-    case ash::AppListSearchResultType::kInternalApp:
-    case ash::AppListSearchResultType::kOmnibox:
-    case ash::AppListSearchResultType::kLauncher:
-    case ash::AppListSearchResultType::kAnswerCard:
-    case ash::AppListSearchResultType::kPlayStoreReinstallApp:
-    case ash::AppListSearchResultType::kArcAppShortcut:
-    case ash::AppListSearchResultType::kFileChip:
-    case ash::AppListSearchResultType::kDriveChip:
-    case ash::AppListSearchResultType::kAssistantChip:
-    case ash::AppListSearchResultType::kOsSettings:
-    case ash::AppListSearchResultType::kInternalPrivacyInfo:
-    case ash::AppListSearchResultType::kAssistantText:
-    case ash::AppListSearchResultType::kHelpApp:
-    case ash::AppListSearchResultType::kFileSearch:
-    case ash::AppListSearchResultType::kDriveSearch:
-    case ash::AppListSearchResultType::kKeyboardShortcut:
-    case ash::AppListSearchResultType::kOpenTab:
-    case ash::AppListSearchResultType::kGames:
-    case ash::AppListSearchResultType::kPersonalization:
-      return false;
-  }
-}
-
 void ClearAllResultsExceptContinue(ResultsMap& results) {
   for (auto it = results.begin(); it != results.end();) {
-    if (!IsPartOfContinueSection(it->first)) {
+    if (!ash::IsContinueSectionResultType(it->first)) {
       it = results.erase(it);
     } else {
       ++it;
diff --git a/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc
index 97cd453f..1326d5e 100644
--- a/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc
+++ b/chrome/browser/ui/app_list/search/search_controller_impl_unittest.cc
@@ -7,7 +7,9 @@
 #include <memory>
 #include <vector>
 
+#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/test/shell_test_api.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
 #include "chrome/browser/ui/app_list/search/search_controller.h"
 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
@@ -36,19 +38,27 @@
 
 class SearchControllerImplTest : public ChromeAshTestBase {
  public:
-  SearchControllerImplTest() = default;
+  SearchControllerImplTest() {
+    scoped_feature_list_.InitAndDisableFeature(
+        ash::features::kProductivityLauncher);
+  }
   SearchControllerImplTest(const SearchControllerImplTest&) = delete;
   SearchControllerImplTest& operator=(const SearchControllerImplTest&) = delete;
   ~SearchControllerImplTest() override = default;
 
-  SearchController& search_controller() { return search_controller_; }
+  void SetUp() override {
+    ChromeAshTestBase::SetUp();
+    search_controller_ = std::make_unique<SearchControllerImpl>(
+        /*model_updater=*/nullptr, &list_controller_, /*profile=*/nullptr,
+        /*notifier=*/nullptr);
+  }
+  SearchController& search_controller() { return *search_controller_; }
   TestAppListControllerDelegate& list_controller() { return list_controller_; }
 
  private:
+  base::test::ScopedFeatureList scoped_feature_list_;
   TestAppListControllerDelegate list_controller_;
-  SearchControllerImpl search_controller_{
-      /*model_updater=*/nullptr, &list_controller_, /*profile=*/nullptr,
-      /*notifier=*/nullptr};
+  std::unique_ptr<SearchControllerImpl> search_controller_;
 };
 
 // Tests -----------------------------------------------------------------------
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.cc b/chrome/browser/ui/app_list/search/test/test_search_controller.cc
index e6fe341..af1a775 100644
--- a/chrome/browser/ui/app_list/search/test/test_search_controller.cc
+++ b/chrome/browser/ui/app_list/search/test/test_search_controller.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/app_list/search/test/test_search_controller.h"
 
+#include "ash/public/cpp/app_list/app_list_features.h"
+#include "ash/public/cpp/app_list/app_list_types.h"
 #include "chrome/browser/ui/app_list/search/search_provider.h"
 
 namespace app_list {
@@ -11,10 +13,26 @@
 TestSearchController::TestSearchController() = default;
 TestSearchController::~TestSearchController() = default;
 
-void TestSearchController::StartSearch(const std::u16string& query) {}
+void TestSearchController::StartSearch(const std::u16string& query) {
+  // The search controller used when categorical search is enabled clears all
+  // results when starging another search query - simulate this behavior in
+  // tests when categorical search is enabled.
+  if (!ash::IsContinueSectionResultType(provider_->ResultType()) &&
+      app_list_features::IsCategoricalSearchEnabled()) {
+    last_results_.clear();
+  }
+  provider_->Start(query);
+}
 
 void TestSearchController::StartZeroState(base::OnceClosure on_done,
-                                          base::TimeDelta timeout) {}
+                                          base::TimeDelta timeout) {
+  // The search controller used when categorical search is enabled clears all
+  // results when starging another search query - simulate this behavior in
+  // tests when categorical search is enabled.
+  if (app_list_features::IsCategoricalSearchEnabled())
+    last_results_.clear();
+  provider_->StartZeroState();
+}
 
 void TestSearchController::ViewClosing() {}
 
@@ -31,7 +49,11 @@
 
 void TestSearchController::AddProvider(
     size_t group_id,
-    std::unique_ptr<SearchProvider> provider) {}
+    std::unique_ptr<SearchProvider> provider) {
+  DCHECK(!provider_);
+  provider_ = std::move(provider);
+  provider_->set_controller(this);
+}
 
 void TestSearchController::SetResults(const SearchProvider* provider,
                                       Results results) {
diff --git a/chrome/browser/ui/app_list/search/test/test_search_controller.h b/chrome/browser/ui/app_list/search/test/test_search_controller.h
index 6176112..79b1267 100644
--- a/chrome/browser/ui/app_list/search/test/test_search_controller.h
+++ b/chrome/browser/ui/app_list/search/test/test_search_controller.h
@@ -55,6 +55,8 @@
   void disable_ranking_for_test() override;
 
  private:
+  std::unique_ptr<SearchProvider> provider_;
+
   Results last_results_;
 };
 
diff --git a/chrome/browser/ui/ash/projector/pending_screencast_manager_browsertest.cc b/chrome/browser/ui/ash/projector/pending_screencast_manager_browsertest.cc
index 48e52d19..cdf323c3 100644
--- a/chrome/browser/ui/ash/projector/pending_screencast_manager_browsertest.cc
+++ b/chrome/browser/ui/ash/projector/pending_screencast_manager_browsertest.cc
@@ -30,6 +30,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace ash {
 
@@ -162,7 +163,7 @@
                             int64_t total_bytes,
                             int64_t transferred_bytes) {
     syncing_status.item_events.emplace_back(
-        base::in_place, /*stable_id=*/1, /*group_id=*/1, path,
+        absl::in_place, /*stable_id=*/1, /*group_id=*/1, path,
         total_bytes == transferred_bytes
             ? drivefs::mojom::ItemEvent::State::kCompleted
             : drivefs::mojom::ItemEvent::State::kInProgress,
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
index dd602c4..1b482e4 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -77,7 +77,6 @@
 class MockAutofillDriver : public ContentAutofillDriver {
  public:
   MockAutofillDriver(content::RenderFrameHost* rfh,
-                     MockAutofillClient* client,
                      ContentAutofillRouter* router)
       : ContentAutofillDriver(rfh, router) {}
 
@@ -93,7 +92,8 @@
   MockBrowserAutofillManager(AutofillDriver* driver, MockAutofillClient* client)
       : BrowserAutofillManager(driver,
                                client,
-                               client->GetPersonalDataManager()) {}
+                               "en-US",
+                               EnableDownloadManager(false)) {}
   MockBrowserAutofillManager(MockBrowserAutofillManager&) = delete;
   MockBrowserAutofillManager& operator=(MockBrowserAutofillManager&) = delete;
   ~MockBrowserAutofillManager() override = default;
@@ -324,8 +324,7 @@
   CreateExternalDelegate() override {
     autofill_router_ = std::make_unique<ContentAutofillRouter>();
     autofill_driver_ = std::make_unique<NiceMock<MockAutofillDriver>>(
-        web_contents()->GetMainFrame(), autofill_client_.get(),
-        autofill_router_.get());
+        web_contents()->GetMainFrame(), autofill_router_.get());
     autofill_driver_->set_autofill_manager(
         std::make_unique<MockBrowserAutofillManager>(autofill_driver_.get(),
                                                      autofill_client_.get()));
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 221fc4e3..829b5a0 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -434,7 +434,7 @@
   virtual send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble(
       content::WebContents* contents) = 0;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   // Returns the PageActionIconView for the Sharing Hub.
   virtual views::Button* GetSharingHubIconButton() = 0;
 #else
@@ -442,7 +442,7 @@
   // of user action.
   virtual sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents) = 0;
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
   // Shows the translate bubble.
   //
diff --git a/chrome/browser/ui/color/BUILD.gn b/chrome/browser/ui/color/BUILD.gn
index 21b95173..ebc0b2e 100644
--- a/chrome/browser/ui/color/BUILD.gn
+++ b/chrome/browser/ui/color/BUILD.gn
@@ -62,7 +62,7 @@
   }
 }
 
-if (!is_ios && !is_android && !is_chromecast) {
+if (!is_ios && !is_android && !is_castos) {
   executable("dump_colors") {
     testonly = true
 
diff --git a/chrome/browser/ui/media_router/media_route_starter_unittest.cc b/chrome/browser/ui/media_router/media_route_starter_unittest.cc
index 5b79593..94cac18 100644
--- a/chrome/browser/ui/media_router/media_route_starter_unittest.cc
+++ b/chrome/browser/ui/media_router/media_route_starter_unittest.cc
@@ -152,6 +152,7 @@
     DestroyMediaRouteStarter();
     profile_manager_->DeleteAllTestingProfiles();
     profile_manager_.reset();
+    WebContentsPresentationManager::SetTestInstance(nullptr);
     ChromeRenderViewHostTestHarness::TearDown();
   }
 
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h
deleted file mode 100644
index ceade3b0..0000000
--- a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h
+++ /dev/null
@@ -1,18 +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.
-
-#ifndef CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_H_
-#define CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_H_
-
-#include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
-
-class Browser;
-
-// Creates and shows a dialog for |browser| displaying the Privacy Sandbox
-// notice or consent to the user. Specific implementations are responsible for
-// altering the content as appropriate based on |dialog_type|.
-void ShowPrivacySandboxDialog(Browser* browser,
-                              PrivacySandboxService::DialogType dialog_type);
-
-#endif  // CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_H_
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.cc b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.cc
new file mode 100644
index 0000000..5e60b13
--- /dev/null
+++ b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.cc
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
+
+#include "components/privacy_sandbox/privacy_sandbox_features.h"
+
+void ShowPrivacySandboxPrompt(Browser* browser,
+                              PrivacySandboxService::DialogType dialog_type) {
+  if (privacy_sandbox::kPrivacySandboxSettings3NewNotice.Get() &&
+      dialog_type == PrivacySandboxService::DialogType::kNotice) {
+    ShowPrivacySandboxNoticeBubble(browser);
+  } else {
+    ShowPrivacySandboxDialog(browser, dialog_type);
+  }
+}
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h
new file mode 100644
index 0000000..b5d3371
--- /dev/null
+++ b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h
@@ -0,0 +1,27 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_H_
+#define CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_H_
+
+#include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
+
+class Browser;
+
+// Creates and shows a dialog or bubble for |browser| displaying the Privacy
+// Sandbox notice or consent to the user.
+void ShowPrivacySandboxPrompt(Browser* browser,
+                              PrivacySandboxService::DialogType dialog_type);
+
+// Creates and shows a dialog for |browser| displaying the Privacy Sandbox
+// notice or consent to the user. Specific implementations are responsible for
+// altering the content as appropriate based on |dialog_type|.
+void ShowPrivacySandboxDialog(Browser* browser,
+                              PrivacySandboxService::DialogType dialog_type);
+
+// Creates and shows a bubble for |browser| displaying the Privacy Sandbox
+// notice the user.
+void ShowPrivacySandboxNoticeBubble(Browser* browser);
+
+#endif  // CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_H_
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.cc b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc
similarity index 84%
rename from chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.cc
rename to chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc
index 2fc7e61..d450442 100644
--- a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.cc
+++ b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.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/ui/privacy_sandbox/privacy_sandbox_dialog_helper.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h"
 
 #include "base/hash/hash.h"
 #include "base/metrics/histogram_functions.h"
@@ -12,7 +12,7 @@
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
@@ -35,14 +35,14 @@
 
 }  // namespace
 
-PrivacySandboxDialogHelper::~PrivacySandboxDialogHelper() = default;
+PrivacySandboxPromptHelper::~PrivacySandboxPromptHelper() = default;
 
-PrivacySandboxDialogHelper::PrivacySandboxDialogHelper(
+PrivacySandboxPromptHelper::PrivacySandboxPromptHelper(
     content::WebContents* web_contents)
     : WebContentsObserver(web_contents),
-      content::WebContentsUserData<PrivacySandboxDialogHelper>(*web_contents) {}
+      content::WebContentsUserData<PrivacySandboxPromptHelper>(*web_contents) {}
 
-void PrivacySandboxDialogHelper::DidFinishNavigation(
+void PrivacySandboxPromptHelper::DidFinishNavigation(
     content::NavigationHandle* navigation_handle) {
   if (!ProfileRequiresDialog(profile()))
     return;
@@ -89,17 +89,17 @@
       browser->tab_strip_model()->GetIndexOfWebContents(
           navigation_handle->GetWebContents()));
 
-  ShowPrivacySandboxDialog(browser, GetRequiredDialogType(profile()));
+  ShowPrivacySandboxPrompt(browser, GetRequiredDialogType(profile()));
 }
 
 // static
-bool PrivacySandboxDialogHelper::ProfileRequiresDialog(Profile* profile) {
+bool PrivacySandboxPromptHelper::ProfileRequiresDialog(Profile* profile) {
   return GetRequiredDialogType(profile) !=
          PrivacySandboxService::DialogType::kNone;
 }
 
-Profile* PrivacySandboxDialogHelper::profile() {
+Profile* PrivacySandboxPromptHelper::profile() {
   return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
 }
 
-WEB_CONTENTS_USER_DATA_KEY_IMPL(PrivacySandboxDialogHelper);
+WEB_CONTENTS_USER_DATA_KEY_IMPL(PrivacySandboxPromptHelper);
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.h b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h
similarity index 61%
rename from chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.h
rename to chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h
index 4bb1f6c8..b439a3f1 100644
--- a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.h
+++ b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_HELPER_H_
-#define CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_HELPER_H_
+#ifndef CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_HELPER_H_
+#define CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_HELPER_H_
 
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -15,27 +15,27 @@
 class Profile;
 
 // Helper class which watches |web_contents| to determine whether there is an
-// appropriate opportunity to show the PrivacySandboxDialog. Consults with the
+// appropriate opportunity to show the PrivacySandboxPrompt. Consults with the
 // PrivacySandboxService to determine what type of dialog, if any, to show.
 // When an appropriate time is determined, calls Show() directly to the
-// PrivacySandboxDialog.
-class PrivacySandboxDialogHelper
+// PrivacySandboxPrompt.
+class PrivacySandboxPromptHelper
     : public content::WebContentsObserver,
-      public content::WebContentsUserData<PrivacySandboxDialogHelper> {
+      public content::WebContentsUserData<PrivacySandboxPromptHelper> {
  public:
-  PrivacySandboxDialogHelper(const PrivacySandboxDialogHelper&) = delete;
-  PrivacySandboxDialogHelper& operator=(const PrivacySandboxDialogHelper&) =
+  PrivacySandboxPromptHelper(const PrivacySandboxPromptHelper&) = delete;
+  PrivacySandboxPromptHelper& operator=(const PrivacySandboxPromptHelper&) =
       delete;
-  ~PrivacySandboxDialogHelper() override;
+  ~PrivacySandboxPromptHelper() override;
 
   // Returns whether |profile| needs to be shown a Privacy Sandbox dialog. If
   // this returns false, there is no need to create this helper.
   static bool ProfileRequiresDialog(Profile* profile);
 
  private:
-  friend class content::WebContentsUserData<PrivacySandboxDialogHelper>;
+  friend class content::WebContentsUserData<PrivacySandboxPromptHelper>;
 
-  explicit PrivacySandboxDialogHelper(content::WebContents* web_contents);
+  explicit PrivacySandboxPromptHelper(content::WebContents* web_contents);
 
   // contents::WebContentsObserver:
   void DidFinishNavigation(
@@ -46,4 +46,4 @@
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
-#endif  // CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_DIALOG_HELPER_H_
+#endif  // CHROME_BROWSER_UI_PRIVACY_SANDBOX_PRIVACY_SANDBOX_PROMPT_HELPER_H_
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
index 17f4ad3..7d2f28c 100644
--- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
+++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
@@ -79,8 +79,9 @@
 // Spacing between labels in the horizontal elements view.
 constexpr int kLabelSpacingDip = 2;
 
-// Settings button.
-constexpr int kSettingsButtonMarginDip = 4;
+// Buttons view.
+constexpr int kButtonsViewMarginDip = 4;
+constexpr int kDogfoodButtonSizeDip = 20;
 constexpr int kSettingsButtonSizeDip = 14;
 constexpr int kSettingsButtonBorderDip = 3;
 
@@ -397,6 +398,14 @@
             vector_icons::kSettingsOutlineIcon, kSettingsButtonSizeDip,
             GetColorProvider()->GetColor(ui::kColorIconSecondary)));
   }
+
+  if (dogfood_feedback_button_) {
+    dogfood_feedback_button_->SetImage(
+        views::Button::ButtonState::STATE_NORMAL,
+        gfx::CreateVectorIcon(
+            vector_icons::kDogfoodIcon, kDogfoodButtonSizeDip,
+            GetColorProvider()->GetColor(ui::kColorIconSecondary)));
+  }
 }
 
 views::FocusTraversable* QuickAnswersView::GetPaneFocusTraversable() {
@@ -539,13 +548,24 @@
 }
 
 void QuickAnswersView::AddSettingsButton() {
-  auto* settings_view = AddChildView(std::make_unique<views::View>());
+  auto* buttons_view = AddChildView(std::make_unique<views::View>());
   auto* layout =
-      settings_view->SetLayoutManager(std::make_unique<views::FlexLayout>());
-  layout->SetOrientation(views::LayoutOrientation::kVertical)
-      .SetInteriorMargin(gfx::Insets(kSettingsButtonMarginDip))
-      .SetCrossAxisAlignment(views::LayoutAlignment::kEnd);
-  settings_button_ = settings_view->AddChildView(
+      buttons_view->SetLayoutManager(std::make_unique<views::FlexLayout>());
+  layout->SetOrientation(views::LayoutOrientation::kHorizontal)
+      .SetInteriorMargin(gfx::Insets(kButtonsViewMarginDip))
+      .SetMainAxisAlignment(views::LayoutAlignment::kEnd)
+      .SetCrossAxisAlignment(views::LayoutAlignment::kStart);
+
+  if (is_internal_) {
+    dogfood_feedback_button_ = buttons_view->AddChildView(
+        std::make_unique<views::ImageButton>(base::BindRepeating(
+            &QuickAnswersUiController::OnReportQueryButtonPressed,
+            controller_)));
+    dogfood_feedback_button_->SetTooltipText(l10n_util::GetStringUTF16(
+        IDS_ASH_QUICK_ANSWERS_SETTINGS_BUTTON_TOOLTIP_TEXT));
+  }
+
+  settings_button_ = buttons_view->AddChildView(
       std::make_unique<views::ImageButton>(base::BindRepeating(
           &QuickAnswersUiController::OnSettingsButtonPressed, controller_)));
   settings_button_->SetTooltipText(l10n_util::GetStringUTF16(
@@ -709,6 +729,8 @@
   // retry-label, and so is not included when this is the case.
   if (!retry_label_)
     focusable_views.push_back(this);
+  if (dogfood_feedback_button_ && dogfood_feedback_button_->GetVisible())
+    focusable_views.push_back(dogfood_feedback_button_);
   if (settings_button_ && settings_button_->GetVisible())
     focusable_views.push_back(settings_button_);
   if (phonetics_audio_button_ && phonetics_audio_button_->GetVisible())
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.h b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h
index d1359cb0..fd7db59 100644
--- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.h
+++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h
@@ -92,6 +92,7 @@
   views::View* report_query_view_ = nullptr;
   views::Label* first_answer_label_ = nullptr;
   views::LabelButton* retry_label_ = nullptr;
+  views::ImageButton* dogfood_feedback_button_ = nullptr;
   views::ImageButton* settings_button_ = nullptr;
   views::ImageButton* phonetics_audio_button_ = nullptr;
 
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc
index 91280477..90ccbd8 100644
--- a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc
+++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.cc
@@ -5,6 +5,7 @@
 
 #include <vector>
 
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/send_tab_to_self/desktop_notification_handler.h"
 #include "chrome/browser/sharing_hub/sharing_hub_features.h"
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
deleted file mode 100644
index 5bb0014..0000000
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/user_metrics.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/favicon/favicon_utils.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/share/share_features.h"
-#include "chrome/browser/share/share_metrics.h"
-#include "chrome/browser/sharing_hub/sharing_hub_features.h"
-#include "chrome/browser/sharing_hub/sharing_hub_model.h"
-#include "chrome/browser/sharing_hub/sharing_hub_service.h"
-#include "chrome/browser/sharing_hub/sharing_hub_service_factory.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h"
-#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.h"
-#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_view.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/services/app_service/public/cpp/intent_util.h"
-#include "content/public/browser/web_contents.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/views/controls/button/button.h"
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chrome/browser/sharesheet/sharesheet_metrics.h"
-#include "chrome/browser/sharesheet/sharesheet_service.h"
-#include "chrome/browser/sharesheet/sharesheet_service_factory.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-namespace sharing_hub {
-
-namespace {
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-// Result of the CrOS sharesheet, i.e. whether the user selects a share target
-// after opening the sharesheet.
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused. Keep in sync with
-// SharingHubSharesheetResult in src/tools/metrics/histograms/enums.xml.
-enum class SharingHubSharesheetResult {
-  SUCCESS = 0,
-  CANCELED = 1,
-  kMaxValue = CANCELED,
-};
-
-const char kSharesheetResult[] =
-    "Sharing.SharingHubDesktop.CrOSSharesheetResult";
-
-SharingHubSharesheetResult GetSharesheetResultHistogram(
-    sharesheet::SharesheetResult result) {
-  switch (result) {
-    case sharesheet::SharesheetResult::kSuccess:
-      return SharingHubSharesheetResult::SUCCESS;
-    case sharesheet::SharesheetResult::kCancel:
-    case sharesheet::SharesheetResult::kErrorAlreadyOpen:
-    case sharesheet::SharesheetResult::kErrorWindowClosed:
-      return SharingHubSharesheetResult::CANCELED;
-  }
-}
-
-void LogCrOSSharesheetResult(sharesheet::SharesheetResult result) {
-  UMA_HISTOGRAM_ENUMERATION(kSharesheetResult,
-                            GetSharesheetResultHistogram(result));
-}
-#endif
-
-}  // namespace
-
-SharingHubBubbleController::~SharingHubBubbleController() {
-  if (sharing_hub_bubble_view_) {
-    sharing_hub_bubble_view_->Hide();
-  }
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (bubble_showing_) {
-    bubble_showing_ = false;
-    // Close any remnant Sharesheet dialog.
-    if (web_contents_containing_window_) {
-      CloseSharesheet();
-    }
-
-    // We must deselect the icon manually since the Sharesheet will not be able
-    // to invoke OnSharesheetClosed() at this point.
-    DeselectIcon();
-  }
-#endif
-}
-
-// static
-SharingHubBubbleController*
-SharingHubBubbleController::CreateOrGetFromWebContents(
-    content::WebContents* web_contents) {
-  SharingHubBubbleController::CreateForWebContents(web_contents);
-  SharingHubBubbleController* controller =
-      SharingHubBubbleController::FromWebContents(web_contents);
-  return controller;
-}
-
-void SharingHubBubbleController::HideBubble() {
-  if (sharing_hub_bubble_view_) {
-    sharing_hub_bubble_view_->Hide();
-    sharing_hub_bubble_view_ = nullptr;
-  }
-}
-
-void SharingHubBubbleController::ShowBubble() {
-  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Ignore subsequent calls to open the Sharesheet if it already is open. This
-  // is especially for the Nearby Share dialog, where clicking outside of it
-  // will not dismiss the dialog.
-  if (bubble_showing_)
-    return;
-  bubble_showing_ = true;
-  ShowSharesheet(browser->window()->GetSharingHubIconButton());
-#else
-  sharing_hub_bubble_view_ =
-      browser->window()->ShowSharingHubBubble(web_contents());
-#endif
-
-  share::LogShareSourceDesktop(share::ShareSourceDesktop::kOmniboxSharingHub);
-}
-
-SharingHubBubbleView* SharingHubBubbleController::sharing_hub_bubble_view()
-    const {
-  return sharing_hub_bubble_view_;
-}
-
-std::u16string SharingHubBubbleController::GetWindowTitle() const {
-  return l10n_util::GetStringUTF16(IDS_SHARING_HUB_TITLE);
-}
-
-Profile* SharingHubBubbleController::GetProfile() const {
-  return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
-}
-
-bool SharingHubBubbleController::ShouldOfferOmniboxIcon() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  return !GetProfile()->IsIncognitoProfile() && !GetProfile()->IsGuestSession();
-#else
-  return SharingHubOmniboxEnabled(GetWebContents().GetBrowserContext());
-#endif
-}
-
-std::vector<SharingHubAction>
-SharingHubBubbleController::GetFirstPartyActions() {
-  std::vector<SharingHubAction> actions;
-
-  SharingHubModel* model = GetSharingHubModel();
-  if (model)
-    model->GetFirstPartyActionList(&GetWebContents(), &actions);
-
-  return actions;
-}
-
-std::vector<SharingHubAction>
-SharingHubBubbleController::GetThirdPartyActions() {
-  std::vector<SharingHubAction> actions;
-
-  SharingHubModel* model = GetSharingHubModel();
-  if (model)
-    model->GetThirdPartyActionList(&actions);
-
-  return actions;
-}
-
-bool SharingHubBubbleController::ShouldUsePreview() {
-  return share::GetDesktopSharePreviewVariant() !=
-         share::DesktopSharePreviewVariant::kDisabled;
-}
-
-std::u16string SharingHubBubbleController::GetPreviewTitle() {
-  // TODO(https://crbug.com/1312524): get passed this state from the omnibox
-  // instead.
-  return GetWebContents().GetTitle();
-}
-
-GURL SharingHubBubbleController::GetPreviewUrl() {
-  // TODO(https://crbug.com/1312524): get passed this state from the omnibox
-  // instead.
-  return GetWebContents().GetVisibleURL();
-}
-
-ui::ImageModel SharingHubBubbleController::GetPreviewImage() {
-  return ui::ImageModel::FromImage(favicon::GetDefaultFavicon());
-}
-
-base::CallbackListSubscription
-SharingHubBubbleController::RegisterPreviewImageChangedCallback(
-    PreviewImageChangedCallback callback) {
-  return preview_image_changed_callbacks_.Add(callback);
-}
-
-void SharingHubBubbleController::OnActionSelected(
-    int command_id,
-    bool is_first_party,
-    std::string feature_name_for_metrics) {
-  Browser* browser = chrome::FindBrowserWithWebContents(&GetWebContents());
-  // Can be null in tests.
-  if (!browser)
-    return;
-
-  if (is_first_party) {
-    base::RecordComputedAction(feature_name_for_metrics);
-
-    // Show a back button for 1P dialogs anchored to the sharing hub icon.
-    if (command_id == IDC_QRCODE_GENERATOR) {
-      qrcode_generator::QRCodeGeneratorBubbleController* qrcode_controller =
-          qrcode_generator::QRCodeGeneratorBubbleController::Get(
-              &GetWebContents());
-      qrcode_controller->ShowBubble(GetWebContents().GetLastCommittedURL(),
-                                    true);
-    } else if (command_id == IDC_SEND_TAB_TO_SELF) {
-      send_tab_to_self::SendTabToSelfBubbleController*
-          send_tab_to_self_controller =
-              send_tab_to_self::SendTabToSelfBubbleController::
-                  CreateOrGetFromWebContents(&GetWebContents());
-      send_tab_to_self_controller->ShowBubble(true);
-    } else {
-      chrome::ExecuteCommand(browser, command_id);
-    }
-  } else {
-    SharingHubModel* model = GetSharingHubModel();
-    DCHECK(model);
-    model->ExecuteThirdPartyAction(&GetWebContents(), command_id);
-  }
-}
-
-void SharingHubBubbleController::OnBubbleClosed() {
-  sharing_hub_bubble_view_ = nullptr;
-}
-
-SharingHubModel* SharingHubBubbleController::GetSharingHubModel() {
-  if (!sharing_hub_model_) {
-    SharingHubService* const service =
-        SharingHubServiceFactory::GetForProfile(GetProfile());
-    if (!service)
-      return nullptr;
-    sharing_hub_model_ = service->GetSharingHubModel();
-  }
-  return sharing_hub_model_;
-}
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-sharesheet::SharesheetService*
-SharingHubBubbleController::GetSharesheetService() {
-  if (!sharesheet_service_) {
-    Profile* const profile =
-        Profile::FromBrowserContext(GetWebContents().GetBrowserContext());
-    DCHECK(profile);
-
-    sharesheet_service_ =
-        sharesheet::SharesheetServiceFactory::GetForProfile(profile);
-  }
-
-  return sharesheet_service_;
-}
-
-void SharingHubBubbleController::ShowSharesheet(
-    views::Button* highlighted_button) {
-  DCHECK(highlighted_button);
-  highlighted_button_tracker_.SetView(highlighted_button);
-
-  sharesheet::SharesheetService* sharesheet_service = GetSharesheetService();
-  if (!sharesheet_service)
-    return;
-
-  apps::mojom::IntentPtr intent = apps_util::CreateShareIntentFromText(
-      GetWebContents().GetLastCommittedURL().spec(),
-      base::UTF16ToUTF8(GetWebContents().GetTitle()));
-  sharesheet_service->ShowBubble(
-      &GetWebContents(), std::move(intent),
-      sharesheet::LaunchSource::kOmniboxShare,
-      base::BindOnce(&SharingHubBubbleController::OnShareDelivered,
-                     AsWeakPtr()),
-      base::BindOnce(&SharingHubBubbleController::OnSharesheetClosed,
-                     AsWeakPtr()));
-
-  // Save the window in order to close the sharesheet if the tab is closed. This
-  // will return the incorrect window if called later.
-  web_contents_containing_window_ = GetWebContents().GetTopLevelNativeWindow();
-}
-
-void SharingHubBubbleController::CloseSharesheet() {
-  sharesheet::SharesheetService* sharesheet_service = GetSharesheetService();
-  if (!sharesheet_service)
-    return;
-
-  sharesheet::SharesheetController* sharesheet_controller =
-      sharesheet_service->GetSharesheetController(
-          web_contents_containing_window_);
-  if (!sharesheet_controller)
-    return;
-
-  sharesheet_controller->CloseBubble(sharesheet::SharesheetResult::kCancel);
-
-  // OnSharesheetClosed() is not guaranteed to be called by the
-  // SharesheetController (specifically for the case where this is invoked by
-  // our destructor). Hence, we must explicitly set this null here.
-  web_contents_containing_window_ = nullptr;
-}
-
-void SharingHubBubbleController::OnShareDelivered(
-    sharesheet::SharesheetResult result) {
-  LogCrOSSharesheetResult(result);
-}
-
-void SharingHubBubbleController::OnSharesheetClosed(
-    views::Widget::ClosedReason reason) {
-  bubble_showing_ = false;
-  web_contents_containing_window_ = nullptr;
-  // Deselect the omnibox icon now that the sharesheet is closed.
-  DeselectIcon();
-}
-
-void SharingHubBubbleController::DeselectIcon() {
-  if (!highlighted_button_tracker_.view())
-    return;
-
-  views::Button* button =
-      views::Button::AsButton(highlighted_button_tracker_.view());
-  if (button)
-    button->SetHighlighted(false);
-}
-
-void SharingHubBubbleController::OnVisibilityChanged(
-    content::Visibility visibility) {
-  // Cancel the current share attempt if the user switches to a different tab in
-  // the window. Switching windows is permitted since a sharesheet is tied to
-  // the native window.
-  if (bubble_showing_ && visibility == content::Visibility::HIDDEN) {
-    CloseSharesheet();
-  }
-}
-#endif
-
-SharingHubBubbleController::SharingHubBubbleController(
-    content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents),
-      content::WebContentsUserData<SharingHubBubbleController>(*web_contents) {}
-
-WEB_CONTENTS_USER_DATA_KEY_IMPL(SharingHubBubbleController);
-
-}  // namespace sharing_hub
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
index d987cd8..05cc9106 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h
@@ -5,134 +5,34 @@
 #ifndef CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_H_
 #define CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_H_
 
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "build/chromeos_buildflags.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_user_data.h"
-#include "ui/base/models/image_model.h"
-#include "ui/views/view_tracker.h"
-#include "ui/views/widget/widget.h"
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chrome/browser/sharesheet/sharesheet_types.h"
-#include "chromeos/components/sharesheet/constants.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-class Profile;
-
 namespace content {
 class WebContents;
 }  // namespace content
 
-namespace views {
-class Button;
-}  // namespace views
-
-namespace sharesheet {
-class SharesheetService;
-}  // namespace sharesheet
-
 namespace sharing_hub {
 
 class SharingHubBubbleView;
-class SharingHubModel;
-struct SharingHubAction;
 
-// Controller component of the Sharing Hub dialog bubble.
-// Responsible for showing and hiding an owned bubble.
-class SharingHubBubbleController
-    : public content::WebContentsObserver,
-      public content::WebContentsUserData<SharingHubBubbleController>,
-      public base::SupportsWeakPtr<SharingHubBubbleController> {
+// Interface for the controller component of the sharing dialog bubble. Controls
+// the Sharing Hub (Windows/Mac/Linux) or the Sharesheet (CrOS) depending on
+// platform.
+// Responsible for showing and hiding an associated dialog bubble.
+class SharingHubBubbleController {
  public:
-  using PreviewImageChangedCallback =
-      base::RepeatingCallback<void(ui::ImageModel)>;
-
-  SharingHubBubbleController(const SharingHubBubbleController&) = delete;
-  SharingHubBubbleController& operator=(const SharingHubBubbleController&) =
-      delete;
-
-  ~SharingHubBubbleController() override;
-
   static SharingHubBubbleController* CreateOrGetFromWebContents(
       content::WebContents* web_contents);
 
-  // Hides the Sharing Hub bubble.
-  void HideBubble();
-  // Displays the Sharing Hub bubble.
-  void ShowBubble();
+  // Hides the sharing bubble.
+  virtual void HideBubble() = 0;
+  // Displays the sharing bubble.
+  virtual void ShowBubble() = 0;
 
   // Returns nullptr if no bubble is currently shown.
-  SharingHubBubbleView* sharing_hub_bubble_view() const;
-  // Returns the title of the Sharing Hub bubble.
-  std::u16string GetWindowTitle() const;
-  // Returns the current profile.
-  Profile* GetProfile() const;
+  virtual SharingHubBubbleView* sharing_hub_bubble_view() const = 0;
   // Returns true if the omnibox icon should be shown.
-  bool ShouldOfferOmniboxIcon();
-
-  // Returns the list of Sharing Hub first party actions.
-  virtual std::vector<SharingHubAction> GetFirstPartyActions();
-  // Returns the list of Sharing Hub third party actions.
-  virtual std::vector<SharingHubAction> GetThirdPartyActions();
-
-  virtual bool ShouldUsePreview();
-  virtual std::u16string GetPreviewTitle();
-  virtual GURL GetPreviewUrl();
-  virtual ui::ImageModel GetPreviewImage();
-
-  base::CallbackListSubscription RegisterPreviewImageChangedCallback(
-      PreviewImageChangedCallback callback);
-
-  // Handles when the user clicks on a Sharing Hub action. If this is a first
-  // party action, executes the appropriate browser command. If this is a third
-  // party action, navigates to an external webpage.
-  virtual void OnActionSelected(int command_id,
-                                bool is_first_party,
-                                std::string feature_name_for_metrics);
-  // Handler for when the bubble is closed.
-  void OnBubbleClosed();
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // content::WebContentsObserver:
-  void OnVisibilityChanged(content::Visibility visibility) override;
-#endif
-
- protected:
-  explicit SharingHubBubbleController(content::WebContents* web_contents);
-
- private:
-  friend class content::WebContentsUserData<SharingHubBubbleController>;
-
-  SharingHubModel* GetSharingHubModel();
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  sharesheet::SharesheetService* GetSharesheetService();
-  void ShowSharesheet(views::Button* highlighted_button);
-  void CloseSharesheet();
-  void OnShareDelivered(sharesheet::SharesheetResult result);
-  void OnSharesheetClosed(views::Widget::ClosedReason reason);
-
-  void DeselectIcon();
-
-  views::ViewTracker highlighted_button_tracker_;
-  sharesheet::SharesheetService* sharesheet_service_ = nullptr;
-  gfx::NativeWindow web_contents_containing_window_ = nullptr;
-  bool bubble_showing_ = false;
-#endif
-
-  // Weak reference. Will be nullptr if no bubble is currently shown.
-  raw_ptr<SharingHubBubbleView> sharing_hub_bubble_view_ = nullptr;
-  // Cached reference to the model.
-  raw_ptr<SharingHubModel> sharing_hub_model_ = nullptr;
-
-  base::RepeatingCallbackList<void(ui::ImageModel)>
-      preview_image_changed_callbacks_;
-
-  WEB_CONTENTS_USER_DATA_KEY_DECL();
+  virtual bool ShouldOfferOmniboxIcon() = 0;
 };
 
 }  // namespace sharing_hub
 
-#endif  // CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_H_
+#endif  // CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_INTERFACE_H_
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_browsertest.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_ash_browsertest.cc
similarity index 76%
rename from chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_browsertest.cc
rename to chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_ash_browsertest.cc
index 391a0f9c..fd1452e 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_ash_browsertest.cc
@@ -4,13 +4,17 @@
 
 #include "chrome/browser/sharesheet/sharesheet_service.h"
 #include "chrome/browser/sharesheet/sharesheet_service_factory.h"
+#include "chrome/browser/sharesheet/sharesheet_ui_delegate.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/page_action/page_action_icon_type.h"
-#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/test/browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using testing::_;
+
 namespace {
 
 class SharingHubBubbleControllerChromeOsBrowserTest
@@ -33,18 +37,16 @@
   // Open the sharesheet using the sharing hub controller.
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  sharing_hub::SharingHubBubbleController::CreateOrGetFromWebContents(
-      web_contents)
-      ->ShowBubble();
-
-  // Wait until the sharesheet is fully opened.
-  base::RunLoop().RunUntilIdle();
+  sharing_hub::SharingHubBubbleControllerChromeOsImpl::
+      CreateOrGetFromWebContents(web_contents)
+          ->ShowBubble();
 
   // Verify that the sharesheet is open.
-  sharesheet::SharesheetController* controller =
-      sharesheet_service->GetSharesheetController(
+  sharesheet::SharesheetUiDelegate* bubble_delegate =
+      sharesheet_service->GetUiDelegateForTesting(
           web_contents_containing_window_);
-  ASSERT_TRUE(controller->IsBubbleVisible());
+  EXPECT_NE(bubble_delegate, nullptr);
+  ASSERT_TRUE(bubble_delegate->IsBubbleVisible());
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.cc
new file mode 100644
index 0000000..cdd1adf
--- /dev/null
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.cc
@@ -0,0 +1,293 @@
+// 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/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/chromeos_buildflags.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/share/share_metrics.h"
+#include "chrome/browser/sharesheet/sharesheet_metrics.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/views/controls/button/button.h"
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/sharesheet/sharesheet_service.h"
+#include "chrome/browser/sharesheet/sharesheet_service_factory.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chrome/browser/ui/lacros/window_utility.h"
+#include "chromeos/crosapi/mojom/app_service_types.mojom.h"
+#include "chromeos/crosapi/mojom/sharesheet.mojom.h"
+#include "chromeos/crosapi/mojom/sharesheet_mojom_traits.h"
+#include "chromeos/lacros/lacros_service.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+namespace sharing_hub {
+
+namespace {
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+crosapi::mojom::IntentPtr CreateCrosapiShareIntent(
+    const std::string& share_text,
+    const std::string& share_title) {
+  crosapi::mojom::IntentPtr intent = crosapi::mojom::Intent::New();
+  intent->action = apps_util::kIntentActionSend;
+  intent->mime_type = "text/plain";
+  intent->share_text = share_text;
+  if (!share_title.empty())
+    intent->share_title = share_title;
+  return intent;
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+// Result of the CrOS Sharesheet, i.e. whether the user selects a share target
+// after opening the Sharesheet.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. Keep in sync with
+// SharingHubSharesheetResult in src/tools/metrics/histograms/enums.xml.
+enum class SharingHubSharesheetResult {
+  SUCCESS = 0,
+  CANCELED = 1,
+  kMaxValue = CANCELED,
+};
+
+const char kSharesheetResult[] =
+    "Sharing.SharingHubDesktop.CrOSSharesheetResult";
+
+SharingHubSharesheetResult GetSharesheetResultHistogram(
+    sharesheet::SharesheetResult result) {
+  switch (result) {
+    case sharesheet::SharesheetResult::kSuccess:
+      return SharingHubSharesheetResult::SUCCESS;
+    case sharesheet::SharesheetResult::kCancel:
+    case sharesheet::SharesheetResult::kErrorAlreadyOpen:
+    case sharesheet::SharesheetResult::kErrorWindowClosed:
+      return SharingHubSharesheetResult::CANCELED;
+  }
+}
+
+void LogCrOSSharesheetResult(sharesheet::SharesheetResult result) {
+  UMA_HISTOGRAM_ENUMERATION(kSharesheetResult,
+                            GetSharesheetResultHistogram(result));
+}
+
+}  // namespace
+
+// static
+SharingHubBubbleController*
+SharingHubBubbleController::CreateOrGetFromWebContents(
+    content::WebContents* web_contents) {
+  SharingHubBubbleControllerChromeOsImpl::CreateForWebContents(web_contents);
+  SharingHubBubbleControllerChromeOsImpl* controller =
+      SharingHubBubbleControllerChromeOsImpl::FromWebContents(web_contents);
+  return controller;
+}
+
+SharingHubBubbleControllerChromeOsImpl::
+    ~SharingHubBubbleControllerChromeOsImpl() {
+  if (bubble_showing_) {
+    bubble_showing_ = false;
+    // Close any remnant Sharesheet dialog.
+    CloseSharesheet();
+
+    // We must deselect the icon manually since the Sharesheet will not be able
+    // to invoke OnSharesheetClosed() at this point.
+    DeselectIcon();
+  }
+}
+
+void SharingHubBubbleControllerChromeOsImpl::HideBubble() {
+  if (bubble_showing_) {
+    CloseSharesheet();
+  }
+}
+
+void SharingHubBubbleControllerChromeOsImpl::ShowBubble() {
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+
+  // Ignore subsequent calls to open the Sharesheet if it already is open. This
+  // is especially for the Nearby Share dialog, where clicking outside of it
+  // will not dismiss the dialog.
+  if (bubble_showing_)
+    return;
+  bubble_showing_ = true;
+  ShowSharesheet(browser->window()->GetSharingHubIconButton());
+
+  share::LogShareSourceDesktop(share::ShareSourceDesktop::kOmniboxSharingHub);
+}
+
+SharingHubBubbleView*
+SharingHubBubbleControllerChromeOsImpl::sharing_hub_bubble_view() const {
+  return nullptr;
+}
+
+bool SharingHubBubbleControllerChromeOsImpl::ShouldOfferOmniboxIcon() {
+  return !GetProfile()->IsIncognitoProfile() && !GetProfile()->IsGuestSession();
+}
+
+Profile* SharingHubBubbleControllerChromeOsImpl::GetProfile() const {
+  return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+}
+
+void SharingHubBubbleControllerChromeOsImpl::OnVisibilityChanged(
+    content::Visibility visibility) {
+  // Cancel the current share attempt if the user switches to a different tab in
+  // the window. Switching windows is permitted since a Sharesheet is tied to
+  // the native window.
+  if (bubble_showing_ && visibility == content::Visibility::HIDDEN) {
+    CloseSharesheet();
+  }
+}
+
+void SharingHubBubbleControllerChromeOsImpl::ShowSharesheet(
+    views::Button* highlighted_button) {
+  DCHECK(highlighted_button);
+  highlighted_button_tracker_.SetView(highlighted_button);
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  ShowSharesheetAsh();
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+  ShowSharesheetLacros();
+#endif
+
+  // Save the window in order to close the Sharesheet if the tab is closed. This
+  // will return the incorrect window if called later.
+  parent_window_ = GetWebContents().GetTopLevelNativeWindow();
+  parent_window_tracker_ = NativeWindowTracker::Create(parent_window_);
+}
+
+void SharingHubBubbleControllerChromeOsImpl::CloseSharesheet() {
+  if (parent_window_ && !parent_window_tracker_->WasNativeWindowClosed()) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    CloseSharesheetAsh();
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+    CloseSharesheetLacros();
+#endif
+  }
+
+  // OnSharesheetClosed() is not guaranteed to be called by the
+  // SharesheetController (specifically for the case where this is invoked by
+  // our destructor). Hence, we must explicitly set this null here.
+  parent_window_ = nullptr;
+  parent_window_tracker_ = nullptr;
+}
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+sharesheet::SharesheetService*
+SharingHubBubbleControllerChromeOsImpl::GetSharesheetService() {
+  Profile* const profile =
+      Profile::FromBrowserContext(GetWebContents().GetBrowserContext());
+  if (!profile)
+    return nullptr;
+
+  return sharesheet::SharesheetServiceFactory::GetForProfile(profile);
+}
+
+void SharingHubBubbleControllerChromeOsImpl::ShowSharesheetAsh() {
+  sharesheet::SharesheetService* sharesheet_service = GetSharesheetService();
+  if (!sharesheet_service)
+    return;
+
+  apps::mojom::IntentPtr intent = apps_util::CreateShareIntentFromText(
+      GetWebContents().GetLastCommittedURL().spec(),
+      base::UTF16ToUTF8(GetWebContents().GetTitle()));
+  sharesheet_service->ShowBubble(
+      &GetWebContents(), std::move(intent),
+      sharesheet::LaunchSource::kOmniboxShare,
+      base::BindOnce(&SharingHubBubbleControllerChromeOsImpl::OnShareDelivered,
+                     AsWeakPtr()),
+      base::BindOnce(
+          &SharingHubBubbleControllerChromeOsImpl::OnSharesheetClosed,
+          AsWeakPtr()));
+}
+
+void SharingHubBubbleControllerChromeOsImpl::CloseSharesheetAsh() {
+  sharesheet::SharesheetService* sharesheet_service = GetSharesheetService();
+  if (!sharesheet_service)
+    return;
+
+  sharesheet::SharesheetController* sharesheet_controller =
+      sharesheet_service->GetSharesheetController(parent_window_);
+  if (!sharesheet_controller)
+    return;
+
+  sharesheet_controller->CloseBubble(sharesheet::SharesheetResult::kCancel);
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+void SharingHubBubbleControllerChromeOsImpl::ShowSharesheetLacros() {
+  auto* const service = chromeos::LacrosService::Get();
+  if (!service || !service->IsAvailable<crosapi::mojom::Sharesheet>())
+    return;
+
+  crosapi::mojom::IntentPtr intent =
+      CreateCrosapiShareIntent(GetWebContents().GetLastCommittedURL().spec(),
+                               base::UTF16ToUTF8(GetWebContents().GetTitle()));
+
+  service->GetRemote<crosapi::mojom::Sharesheet>()->ShowBubbleWithOnClosed(
+      lacros_window_utility::GetRootWindowUniqueId(
+          GetWebContents().GetTopLevelNativeWindow()),
+      sharesheet::LaunchSource::kOmniboxShare, std::move(intent),
+      base::BindOnce(
+          &SharingHubBubbleControllerChromeOsImpl::OnSharesheetClosedLacros,
+          AsWeakPtr()));
+}
+
+void SharingHubBubbleControllerChromeOsImpl::CloseSharesheetLacros() {
+  auto* const service = chromeos::LacrosService::Get();
+  if (!service || !service->IsAvailable<crosapi::mojom::Sharesheet>())
+    return;
+
+  service->GetRemote<crosapi::mojom::Sharesheet>()->CloseBubble(
+      lacros_window_utility::GetRootWindowUniqueId(parent_window_));
+}
+
+void SharingHubBubbleControllerChromeOsImpl::OnSharesheetClosedLacros() {
+  OnSharesheetClosed(views::Widget::ClosedReason::kUnspecified);
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+void SharingHubBubbleControllerChromeOsImpl::OnShareDelivered(
+    sharesheet::SharesheetResult result) {
+  LogCrOSSharesheetResult(result);
+}
+
+void SharingHubBubbleControllerChromeOsImpl::OnSharesheetClosed(
+    views::Widget::ClosedReason reason) {
+  bubble_showing_ = false;
+  parent_window_ = nullptr;
+  parent_window_tracker_ = nullptr;
+  // Deselect the omnibox icon now that the Sharesheet is closed.
+  DeselectIcon();
+}
+
+void SharingHubBubbleControllerChromeOsImpl::DeselectIcon() {
+  if (!highlighted_button_tracker_.view())
+    return;
+
+  views::Button* button =
+      views::Button::AsButton(highlighted_button_tracker_.view());
+  if (button)
+    button->SetHighlighted(false);
+}
+
+SharingHubBubbleControllerChromeOsImpl::SharingHubBubbleControllerChromeOsImpl(
+    content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
+      content::WebContentsUserData<SharingHubBubbleControllerChromeOsImpl>(
+          *web_contents) {}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(SharingHubBubbleControllerChromeOsImpl);
+
+}  // namespace sharing_hub
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h
new file mode 100644
index 0000000..de4f327
--- /dev/null
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h
@@ -0,0 +1,106 @@
+// 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_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_CHROMEOS_IMPL_H_
+#define CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_CHROMEOS_IMPL_H_
+
+#include "base/memory/weak_ptr.h"
+#include "build/chromeos_buildflags.h"
+#include "chrome/browser/ui/native_window_tracker.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "ui/views/view_tracker.h"
+#include "ui/views/widget/widget.h"
+
+#include "chrome/browser/sharesheet/sharesheet_types.h"
+#include "chromeos/components/sharesheet/constants.h"
+
+class Profile;
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+namespace views {
+class Button;
+}  // namespace views
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+namespace sharesheet {
+class SharesheetService;
+}  // namespace sharesheet
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+namespace sharing_hub {
+
+class SharingHubBubbleView;
+
+// Controller component of the omnibox entry point for the Sharesheet dialog.
+// Responsible for showing and hiding the Sharesheet.
+class SharingHubBubbleControllerChromeOsImpl
+    : public SharingHubBubbleController,
+      public content::WebContentsObserver,
+      public content::WebContentsUserData<
+          SharingHubBubbleControllerChromeOsImpl>,
+      public base::SupportsWeakPtr<SharingHubBubbleControllerChromeOsImpl> {
+ public:
+  SharingHubBubbleControllerChromeOsImpl(
+      const SharingHubBubbleControllerChromeOsImpl&) = delete;
+  SharingHubBubbleControllerChromeOsImpl& operator=(
+      const SharingHubBubbleControllerChromeOsImpl&) = delete;
+
+  ~SharingHubBubbleControllerChromeOsImpl() override;
+
+  // SharingHubBubbleController:
+  void HideBubble() override;
+  void ShowBubble() override;
+  SharingHubBubbleView* sharing_hub_bubble_view() const override;
+  bool ShouldOfferOmniboxIcon() override;
+
+  // Returns the current profile.
+  Profile* GetProfile() const;
+
+  // content::WebContentsObserver:
+  void OnVisibilityChanged(content::Visibility visibility) override;
+
+ protected:
+  explicit SharingHubBubbleControllerChromeOsImpl(
+      content::WebContents* web_contents);
+
+ private:
+  friend class content::WebContentsUserData<
+      SharingHubBubbleControllerChromeOsImpl>;
+
+  void ShowSharesheet(views::Button* highlighted_button);
+  void CloseSharesheet();
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  sharesheet::SharesheetService* GetSharesheetService();
+  void ShowSharesheetAsh();
+  void CloseSharesheetAsh();
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  void ShowSharesheetLacros();
+  void CloseSharesheetLacros();
+  void OnSharesheetClosedLacros();
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+  void OnShareDelivered(sharesheet::SharesheetResult result);
+  void OnSharesheetClosed(views::Widget::ClosedReason reason);
+
+  void DeselectIcon();
+
+  views::ViewTracker highlighted_button_tracker_;
+  gfx::NativeWindow parent_window_ = nullptr;
+  std::unique_ptr<NativeWindowTracker> parent_window_tracker_ = nullptr;
+  bool bubble_showing_ = false;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+}  // namespace sharing_hub
+
+#endif  // CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_CHROMEOS_IMPL_H_
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_lacros_browsertest.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_lacros_browsertest.cc
new file mode 100644
index 0000000..692f4a3
--- /dev/null
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_lacros_browsertest.cc
@@ -0,0 +1,111 @@
+// 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/ui/browser.h"
+#include "chrome/browser/ui/lacros/window_utility.h"
+#include "chrome/browser/ui/page_action/page_action_icon_type.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_impl.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/crosapi/mojom/app_service_types.mojom.h"
+#include "chromeos/crosapi/mojom/sharesheet.mojom.h"
+#include "chromeos/crosapi/mojom/sharesheet_mojom_traits.h"
+#include "chromeos/lacros/lacros_service.h"
+#include "content/public/test/browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace {
+
+class FakeSharesheet : public crosapi::mojom::Sharesheet {
+ public:
+  FakeSharesheet() = default;
+  FakeSharesheet(const FakeSharesheet&) = delete;
+  FakeSharesheet& operator=(const FakeSharesheet&) = delete;
+  ~FakeSharesheet() override = default;
+
+ private:
+  // crosapi::mojom::Sharesheet:
+  void ShowBubble(
+      const std::string& window_id,
+      sharesheet::LaunchSource source,
+      crosapi::mojom::IntentPtr intent,
+      crosapi::mojom::Sharesheet::ShowBubbleCallback callback) override {}
+  void ShowBubbleWithOnClosed(
+      const std::string& window_id,
+      sharesheet::LaunchSource source,
+      crosapi::mojom::IntentPtr intent,
+      crosapi::mojom::Sharesheet::ShowBubbleWithOnClosedCallback callback)
+      override {
+    show_bubble_called = true;
+  }
+  void CloseBubble(const std::string& window_id) override {
+    close_bubble_called = true;
+  }
+
+ public:
+  bool show_bubble_called = false;
+  bool close_bubble_called = false;
+};
+
+class SharingHubBubbleControllerChromeOsBrowserTest
+    : public InProcessBrowserTest {
+ public:
+  SharingHubBubbleControllerChromeOsBrowserTest() = default;
+  ~SharingHubBubbleControllerChromeOsBrowserTest() override = default;
+
+  // Lacros tests may be run with an old version of ash-chrome where the lacros
+  // service or the sharesheet interface are not available.
+  bool IsServiceAvailable() {
+    auto* const service = chromeos::LacrosService::Get();
+    return service && service->IsAvailable<crosapi::mojom::Sharesheet>();
+  }
+
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+
+    // If the lacros service or the sharesheet interface are not
+    // available on this version of ash-chrome, this test suite will no-op.
+    if (!IsServiceAvailable())
+      return;
+
+    // Replace the production sharesheet with a fake for testing.
+    mojo::Remote<crosapi::mojom::Sharesheet>& remote =
+        chromeos::LacrosService::Get()->GetRemote<crosapi::mojom::Sharesheet>();
+    remote.reset();
+    receiver_.Bind(remote.BindNewPipeAndPassReceiver());
+  }
+
+ protected:
+  FakeSharesheet service_;
+  mojo::Receiver<crosapi::mojom::Sharesheet> receiver_{&service_};
+};
+
+IN_PROC_BROWSER_TEST_F(SharingHubBubbleControllerChromeOsBrowserTest,
+                       OpenSharesheet_Lacros) {
+  auto* const service = chromeos::LacrosService::Get();
+  if (!service || !service->IsAvailable<crosapi::mojom::Sharesheet>())
+    return;
+
+  // Open the sharesheet using the sharing hub controller.
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  sharing_hub::SharingHubBubbleControllerChromeOsImpl::
+      CreateOrGetFromWebContents(web_contents)
+          ->ShowBubble();
+
+  // Verify that the sharesheet was opened.
+  EXPECT_TRUE(service_.show_bubble_called);
+
+  // Close the sharesheet using the sharing hub controller.
+  sharing_hub::SharingHubBubbleControllerChromeOsImpl::
+      CreateOrGetFromWebContents(web_contents)
+          ->HideBubble();
+
+  // Verify that the sharesheet was closed.
+  EXPECT_TRUE(service_.close_bubble_called);
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc
new file mode 100644
index 0000000..aa9e1894
--- /dev/null
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.cc
@@ -0,0 +1,189 @@
+// 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/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h"
+
+#include "base/metrics/user_metrics.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/favicon/favicon_utils.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/share/share_features.h"
+#include "chrome/browser/share/share_metrics.h"
+#include "chrome/browser/sharing_hub/sharing_hub_features.h"
+#include "chrome/browser/sharing_hub/sharing_hub_model.h"
+#include "chrome/browser/sharing_hub/sharing_hub_service.h"
+#include "chrome/browser/sharing_hub/sharing_hub_service_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h"
+#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_view.h"
+#include "chrome/grit/generated_resources.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace sharing_hub {
+
+// static
+// SharingHubBubbleController:
+SharingHubBubbleController*
+SharingHubBubbleController::CreateOrGetFromWebContents(
+    content::WebContents* web_contents) {
+  SharingHubBubbleControllerDesktopImpl::CreateForWebContents(web_contents);
+  SharingHubBubbleControllerDesktopImpl* controller =
+      SharingHubBubbleControllerDesktopImpl::FromWebContents(web_contents);
+  return controller;
+}
+
+SharingHubBubbleControllerDesktopImpl::
+    ~SharingHubBubbleControllerDesktopImpl() {
+  if (sharing_hub_bubble_view_) {
+    sharing_hub_bubble_view_->Hide();
+  }
+}
+
+void SharingHubBubbleControllerDesktopImpl::HideBubble() {
+  if (sharing_hub_bubble_view_) {
+    sharing_hub_bubble_view_->Hide();
+    sharing_hub_bubble_view_ = nullptr;
+  }
+}
+
+void SharingHubBubbleControllerDesktopImpl::ShowBubble() {
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+
+  sharing_hub_bubble_view_ =
+      browser->window()->ShowSharingHubBubble(web_contents());
+
+  share::LogShareSourceDesktop(share::ShareSourceDesktop::kOmniboxSharingHub);
+}
+
+SharingHubBubbleView*
+SharingHubBubbleControllerDesktopImpl::sharing_hub_bubble_view() const {
+  return sharing_hub_bubble_view_;
+}
+
+bool SharingHubBubbleControllerDesktopImpl::ShouldOfferOmniboxIcon() {
+  return SharingHubOmniboxEnabled(GetWebContents().GetBrowserContext());
+}
+
+std::u16string SharingHubBubbleControllerDesktopImpl::GetWindowTitle() const {
+  return l10n_util::GetStringUTF16(IDS_SHARING_HUB_TITLE);
+}
+
+Profile* SharingHubBubbleControllerDesktopImpl::GetProfile() const {
+  return Profile::FromBrowserContext(web_contents()->GetBrowserContext());
+}
+
+std::vector<SharingHubAction>
+SharingHubBubbleControllerDesktopImpl::GetFirstPartyActions() {
+  std::vector<SharingHubAction> actions;
+
+  SharingHubModel* model = GetSharingHubModel();
+  if (model)
+    model->GetFirstPartyActionList(&GetWebContents(), &actions);
+
+  return actions;
+}
+
+std::vector<SharingHubAction>
+SharingHubBubbleControllerDesktopImpl::GetThirdPartyActions() {
+  std::vector<SharingHubAction> actions;
+
+  SharingHubModel* model = GetSharingHubModel();
+  if (model)
+    model->GetThirdPartyActionList(&actions);
+
+  return actions;
+}
+
+bool SharingHubBubbleControllerDesktopImpl::ShouldUsePreview() {
+  return share::GetDesktopSharePreviewVariant() !=
+         share::DesktopSharePreviewVariant::kDisabled;
+}
+
+std::u16string SharingHubBubbleControllerDesktopImpl::GetPreviewTitle() {
+  // TODO(https://crbug.com/1312524): get passed this state from the omnibox
+  // instead.
+  return GetWebContents().GetTitle();
+}
+
+GURL SharingHubBubbleControllerDesktopImpl::GetPreviewUrl() {
+  // TODO(https://crbug.com/1312524): get passed this state from the omnibox
+  // instead.
+  return GetWebContents().GetVisibleURL();
+}
+
+ui::ImageModel SharingHubBubbleControllerDesktopImpl::GetPreviewImage() {
+  return ui::ImageModel::FromImage(favicon::GetDefaultFavicon());
+}
+
+base::CallbackListSubscription
+SharingHubBubbleControllerDesktopImpl::RegisterPreviewImageChangedCallback(
+    PreviewImageChangedCallback callback) {
+  return preview_image_changed_callbacks_.Add(callback);
+}
+
+void SharingHubBubbleControllerDesktopImpl::OnActionSelected(
+    int command_id,
+    bool is_first_party,
+    std::string feature_name_for_metrics) {
+  Browser* browser = chrome::FindBrowserWithWebContents(&GetWebContents());
+  // Can be null in tests.
+  if (!browser)
+    return;
+
+  if (is_first_party) {
+    base::RecordComputedAction(feature_name_for_metrics);
+
+    // Show a back button for 1P dialogs anchored to the sharing hub icon.
+    if (command_id == IDC_QRCODE_GENERATOR) {
+      qrcode_generator::QRCodeGeneratorBubbleController* qrcode_controller =
+          qrcode_generator::QRCodeGeneratorBubbleController::Get(
+              &GetWebContents());
+      qrcode_controller->ShowBubble(GetWebContents().GetLastCommittedURL(),
+                                    true);
+    } else if (command_id == IDC_SEND_TAB_TO_SELF) {
+      send_tab_to_self::SendTabToSelfBubbleController*
+          send_tab_to_self_controller =
+              send_tab_to_self::SendTabToSelfBubbleController::
+                  CreateOrGetFromWebContents(&GetWebContents());
+      send_tab_to_self_controller->ShowBubble(true);
+    } else {
+      chrome::ExecuteCommand(browser, command_id);
+    }
+  } else {
+    SharingHubModel* model = GetSharingHubModel();
+    DCHECK(model);
+    model->ExecuteThirdPartyAction(&GetWebContents(), command_id);
+  }
+}
+
+void SharingHubBubbleControllerDesktopImpl::OnBubbleClosed() {
+  sharing_hub_bubble_view_ = nullptr;
+}
+
+SharingHubModel* SharingHubBubbleControllerDesktopImpl::GetSharingHubModel() {
+  if (!sharing_hub_model_) {
+    SharingHubService* const service =
+        SharingHubServiceFactory::GetForProfile(GetProfile());
+    if (!service)
+      return nullptr;
+    sharing_hub_model_ = service->GetSharingHubModel();
+  }
+  return sharing_hub_model_;
+}
+
+SharingHubBubbleControllerDesktopImpl::SharingHubBubbleControllerDesktopImpl(
+    content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
+      content::WebContentsUserData<SharingHubBubbleControllerDesktopImpl>(
+          *web_contents) {}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(SharingHubBubbleControllerDesktopImpl);
+
+}  // namespace sharing_hub
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h
new file mode 100644
index 0000000..465128f
--- /dev/null
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h
@@ -0,0 +1,104 @@
+// 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_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_DESKTOP_IMPL_H_
+#define CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_DESKTOP_IMPL_H_
+
+#include "base/callback.h"
+#include "base/callback_list.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "ui/base/models/image_model.h"
+
+class Profile;
+
+namespace content {
+class WebContents;
+}  // namespace content
+
+namespace sharing_hub {
+
+class SharingHubBubbleView;
+class SharingHubModel;
+struct SharingHubAction;
+
+// Controller component of the Sharing Hub dialog bubble.
+// Responsible for showing and hiding an owned bubble.
+class SharingHubBubbleControllerDesktopImpl
+    : public SharingHubBubbleController,
+      public content::WebContentsObserver,
+      public content::WebContentsUserData<
+          SharingHubBubbleControllerDesktopImpl>,
+      public base::SupportsWeakPtr<SharingHubBubbleControllerDesktopImpl> {
+ public:
+  using PreviewImageChangedCallback =
+      base::RepeatingCallback<void(ui::ImageModel)>;
+
+  SharingHubBubbleControllerDesktopImpl(
+      const SharingHubBubbleControllerDesktopImpl&) = delete;
+  SharingHubBubbleControllerDesktopImpl& operator=(
+      const SharingHubBubbleControllerDesktopImpl&) = delete;
+
+  ~SharingHubBubbleControllerDesktopImpl() override;
+
+  // SharingHubBubbleController:
+  void HideBubble() override;
+  void ShowBubble() override;
+  SharingHubBubbleView* sharing_hub_bubble_view() const override;
+  bool ShouldOfferOmniboxIcon() override;
+
+  // Returns the title of the Sharing Hub bubble.
+  std::u16string GetWindowTitle() const;
+  // Returns the current profile.
+  Profile* GetProfile() const;
+
+  // Returns the list of Sharing Hub first party actions.
+  virtual std::vector<SharingHubAction> GetFirstPartyActions();
+  // Returns the list of Sharing Hub third party actions.
+  virtual std::vector<SharingHubAction> GetThirdPartyActions();
+
+  virtual bool ShouldUsePreview();
+  virtual std::u16string GetPreviewTitle();
+  virtual GURL GetPreviewUrl();
+  virtual ui::ImageModel GetPreviewImage();
+
+  base::CallbackListSubscription RegisterPreviewImageChangedCallback(
+      PreviewImageChangedCallback callback);
+
+  // Handles when the user clicks on a Sharing Hub action. If this is a first
+  // party action, executes the appropriate browser command. If this is a third
+  // party action, navigates to an external webpage.
+  virtual void OnActionSelected(int command_id,
+                                bool is_first_party,
+                                std::string feature_name_for_metrics);
+  // Handler for when the bubble is closed.
+  void OnBubbleClosed();
+
+ protected:
+  explicit SharingHubBubbleControllerDesktopImpl(
+      content::WebContents* web_contents);
+
+ private:
+  friend class content::WebContentsUserData<
+      SharingHubBubbleControllerDesktopImpl>;
+
+  SharingHubModel* GetSharingHubModel();
+
+  // Weak reference. Will be nullptr if no bubble is currently shown.
+  raw_ptr<SharingHubBubbleView> sharing_hub_bubble_view_ = nullptr;
+  // Cached reference to the model.
+  raw_ptr<SharingHubModel> sharing_hub_model_ = nullptr;
+
+  base::RepeatingCallbackList<void(ui::ImageModel)>
+      preview_image_changed_callbacks_;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+}  // namespace sharing_hub
+
+#endif  // CHROME_BROWSER_UI_SHARING_HUB_SHARING_HUB_BUBBLE_CONTROLLER_DESKTOP_IMPL_H_
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc
index 3358627..b82d72b4 100644
--- a/chrome/browser/ui/startup/startup_browser_creator.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -294,6 +294,13 @@
     return false;
   }
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  if (profile->IsGuestSession()) {
+    DCHECK_NE(profile_info.mode, StartupProfileMode::kProfilePicker);
+    return true;
+  }
+#endif
+
   // Guest or system profiles are not available unless a separate process
   // already has a window open for the profile.
   return (!profile->IsGuestSession() && !profile->IsSystemProfile()) ||
@@ -1466,6 +1473,14 @@
             StartupProfileMode::kBrowserWindow};
   }
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  if (chromeos::LacrosService::Get()->init_params()->session_type ==
+      crosapi::mojom::SessionType::kGuestSession) {
+    return {ProfileManager::GetGuestProfilePath(),
+            StartupProfileMode::kBrowserWindow};
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   if (command_line.HasSwitch(switches::kProfileDirectory)) {
     return {user_data_dir.Append(
                 command_line.GetSwitchValuePath(switches::kProfileDirectory)),
@@ -1514,6 +1529,12 @@
   // NOTE: GetProfile() does synchronous file I/O on the main thread.
   Profile* profile = profile_manager->GetProfile(path_info.path);
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  if (profile->IsGuestSession()) {
+    return {profile, StartupProfileMode::kBrowserWindow};
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // There are several cases where we should show the profile picker:
   // - if there is no entry in profile attributes storage, which means that the
   //   profile is deleted,
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
index c3e250f3..5d2f446 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -4165,4 +4165,43 @@
   EXPECT_TRUE(ProfilePicker::IsOpen());
 }
 
+class StartupBrowserCreatorLacrosGuestSessionTest
+    : public InProcessBrowserTest {
+ public:
+  StartupBrowserCreatorLacrosGuestSessionTest() = default;
+
+  void CreatedBrowserMainParts(
+      content::BrowserMainParts* browser_main_parts) override {
+    crosapi::mojom::BrowserInitParamsPtr init_params =
+        crosapi::mojom::BrowserInitParams::New();
+    init_params->session_type = crosapi::mojom::SessionType::kGuestSession;
+    chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
+
+    InProcessBrowserTest::CreatedBrowserMainParts(browser_main_parts);
+  }
+};
+
+// Checks that a browser window with new tab is open in Guest session.
+IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorLacrosGuestSessionTest, Startup) {
+  base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
+  command_line.AppendSwitch(::switches::kIncognito);
+  StartupBrowserCreatorImpl launch(base::FilePath(), command_line,
+                                   chrome::startup::IsFirstRun::kNo);
+  launch.Launch(browser()->profile(), chrome::startup::IsProcessStartup::kYes,
+                nullptr);
+
+  // A new browser window should be open.
+  Browser* new_browser = FindOneOtherBrowser(browser());
+  EXPECT_TRUE(new_browser);
+  EXPECT_TRUE(new_browser->profile()->IsGuestSession());
+
+  // The new browser should have exactly one tab (new tab url).
+  TabStripModel* tab_strip = new_browser->tab_strip_model();
+  EXPECT_TRUE(tab_strip);
+  ASSERT_EQ(1, tab_strip->count());
+  EXPECT_EQ(
+      chrome::kChromeUINewTabURL,
+      tab_strip->GetWebContentsAt(0)->GetVisibleURL().possibly_invalid_spec());
+}
+
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index 52e7c84..6a8cf5c 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -89,7 +89,7 @@
 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
 #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
 #include "chrome/browser/ui/prefs/prefs_tab_helper.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog_helper.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h"
 #include "chrome/browser/ui/recently_audible_helper.h"
 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
@@ -491,8 +491,8 @@
     LastTabStandingTrackerTabHelper::CreateForWebContents(web_contents);
   }
   ManagePasswordsUIController::CreateForWebContents(web_contents);
-  if (PrivacySandboxDialogHelper::ProfileRequiresDialog(profile))
-    PrivacySandboxDialogHelper::CreateForWebContents(web_contents);
+  if (PrivacySandboxPromptHelper::ProfileRequiresDialog(profile))
+    PrivacySandboxPromptHelper::CreateForWebContents(web_contents);
   SadTabHelper::CreateForWebContents(web_contents);
   SearchTabHelper::CreateForWebContents(web_contents);
   SyncEncryptionKeysTabHelper::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.cc
index b96eef22..f4153d21 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.cc
@@ -81,6 +81,21 @@
     observer.SavedTabGroupClosed(index);
 }
 
+void SavedTabGroupModel::Move(tab_groups::TabGroupId tab_group_id,
+                              int new_index) {
+  DCHECK_GE(new_index, 0);
+  int index = GetIndexOf(tab_group_id);
+  if (index < 0)
+    return;
+
+  SavedTabGroup group = saved_tab_groups_[index];
+  saved_tab_groups_.erase(saved_tab_groups_.begin() + index);
+  saved_tab_groups_.emplace(saved_tab_groups_.begin() + new_index, group);
+
+  for (auto& observer : observers_)
+    observer.SavedTabGroupMoved(saved_tab_groups_[new_index], index, new_index);
+}
+
 void SavedTabGroupModel::AddObserver(SavedTabGroupModelObserver* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.h
index e4931e07..ea2e12a9 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model.h
@@ -53,6 +53,11 @@
   // Notify Observers that a saved tab group was removed from the tabstrip.
   void GroupClosed(tab_groups::TabGroupId tab_group_id);
 
+  // Changes the index of a given tab group by id. The new index provided is the
+  // expected index after the group is removed.
+  void Move(tab_groups::TabGroupId tab_group_id, int new_index);
+
+  // Add/Remove observers for this model.
   void AddObserver(SavedTabGroupModelObserver* observer);
   void RemoveObserver(SavedTabGroupModelObserver* observer);
 
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_observer.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_observer.h
index db66872..3df4d898 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_observer.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_observer.h
@@ -25,7 +25,9 @@
   virtual void SavedTabGroupUpdated(const SavedTabGroup& group, int index) = 0;
 
   // Called when the order of saved tab groups in the bookmark bar are changed
-  virtual void SavedTabGroupMoved(const SavedTabGroup& group) = 0;
+  virtual void SavedTabGroupMoved(const SavedTabGroup& group,
+                                  int old_index,
+                                  int new_index) = 0;
 
   // Called when a saved tab group is removed from a tabstrip.
   virtual void SavedTabGroupClosed(int index) = 0;
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_unittest.cc
index 5a77476..c82a900 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_unittest.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_model_unittest.cc
@@ -43,8 +43,19 @@
     retrieved_index_ = index;
   }
 
-  void SavedTabGroupMoved(const SavedTabGroup& group) override {
+  void SavedTabGroupMoved(const SavedTabGroup& group,
+                          int old_index,
+                          int new_index) override {
     retrieved_group_.emplace_back(group);
+    retrieved_old_index_ = old_index;
+    retrieved_new_index_ = new_index;
+  }
+
+  void ClearSignals() {
+    retrieved_group_.clear();
+    retrieved_index_ = -1;
+    retrieved_old_index_ = -1;
+    retrieved_new_index_ = -1;
   }
 
   void SavedTabGroupClosed(int index) override { retrieved_index_ = index; }
@@ -84,6 +95,8 @@
   std::unique_ptr<SavedTabGroupModel> saved_tab_group_model_;
   std::vector<SavedTabGroup> retrieved_group_;
   int retrieved_index_ = -1;
+  int retrieved_old_index_ = -1;
+  int retrieved_new_index_ = -1;
   std::string base_path_ = "file:///c:/tmp/";
 };
 
@@ -310,6 +323,14 @@
   EXPECT_EQ(group->color, random_color);
 }
 
+TEST_F(SavedTabGroupModelTest, MoveElement) {
+  EXPECT_EQ(1, saved_tab_group_model_->GetIndexOf(id_2_));
+  saved_tab_group_model_->Move(id_2_, 2);
+  EXPECT_EQ(2, saved_tab_group_model_->GetIndexOf(id_2_));
+  saved_tab_group_model_->Move(id_2_, 0);
+  EXPECT_EQ(0, saved_tab_group_model_->GetIndexOf(id_2_));
+}
+
 // Tests that SavedTabGroupModelObserver::Added passes the correct element from
 // the model.
 TEST_F(SavedTabGroupModelObserverTest, AddElement) {
@@ -394,3 +415,33 @@
   EXPECT_NE(index, retrieved_index_);
   EXPECT_EQ(-1, retrieved_index_);
 }
+
+// Tests that SavedTabGroupModelObserver::Moved passes the correct
+// element from the model.
+TEST_F(SavedTabGroupModelObserverTest, MoveElement) {
+  SavedTabGroup stg_1(tab_groups::TabGroupId::GenerateNew(),
+                      std::u16string(u"stg_1"),
+                      tab_groups::TabGroupColorId::kGrey, {});
+  SavedTabGroup stg_2(tab_groups::TabGroupId::GenerateNew(),
+                      std::u16string(u"stg_2"),
+                      tab_groups::TabGroupColorId::kGrey, {});
+  SavedTabGroup stg_3(tab_groups::TabGroupId::GenerateNew(),
+                      std::u16string(u"stg_3"),
+                      tab_groups::TabGroupColorId::kGrey, {});
+
+  saved_tab_group_model_->Add(stg_1);
+  saved_tab_group_model_->Add(stg_2);
+  saved_tab_group_model_->Add(stg_3);
+
+  ClearSignals();
+
+  saved_tab_group_model_->Move(stg_2.group_id, 2);
+
+  const int index = retrieved_group_.size() - 1;
+  ASSERT_GE(index, 0);
+
+  SavedTabGroup received_group = retrieved_group_[index];
+  EXPECT_EQ(stg_2.group_id, received_group.group_id);
+  EXPECT_EQ(1, retrieved_old_index_);
+  EXPECT_EQ(2, retrieved_new_index_);
+}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 92bd43e..a9f419a 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -1291,7 +1291,9 @@
   drop_weak_ptr_factory_.InvalidateWeakPtrs();
 }
 
-void BookmarkBarView::SavedTabGroupMoved(const SavedTabGroup& group) {
+void BookmarkBarView::SavedTabGroupMoved(const SavedTabGroup& group,
+                                         int old_index,
+                                         int new_index) {
   // TODO(dljames): Find the current index for [group] in [tab_group_buttons_].
   // Find the new index for [ group ] in [saved_tab_group_model_]. Swap
   // from current -> new.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index ea75d27..1c56fd6 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -221,7 +221,9 @@
   void SavedTabGroupAdded(const SavedTabGroup& group, int index) override;
   void SavedTabGroupRemoved(int index) override;
   void SavedTabGroupUpdated(const SavedTabGroup& group, int index) override;
-  void SavedTabGroupMoved(const SavedTabGroup& group) override;
+  void SavedTabGroupMoved(const SavedTabGroup& group,
+                          int old_index,
+                          int new_index) override;
   void SavedTabGroupClosed(int index) override;
 
   void SavedTabGroupAddedImpl(const SavedTabGroup& group, int index);
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
index a286ad9b..096fae6 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.cc
@@ -52,6 +52,7 @@
                                           int index) {
   AddTabGroupButton(group, index);
 }
+
 void SavedTabGroupBar::SavedTabGroupRemoved(int index) {
   RemoveTabGroupButton(index);
 }
@@ -62,7 +63,11 @@
   AddTabGroupButton(group, index);
 }
 
-void SavedTabGroupBar::SavedTabGroupMoved(const SavedTabGroup& group) {}
+void SavedTabGroupBar::SavedTabGroupMoved(const SavedTabGroup& group,
+                                          int old_index,
+                                          int new_index) {
+  ReorderChildView(children().at(old_index), new_index);
+}
 
 // TODO dpenning: Support the state of the SavedTabGroup open in a tab strip
 // changing.
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
index 660e1c2..bc4faf3 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar.h
@@ -43,7 +43,9 @@
   void SavedTabGroupAdded(const SavedTabGroup& group, int index) override;
   void SavedTabGroupRemoved(int index) override;
   void SavedTabGroupUpdated(const SavedTabGroup& group, int index) override;
-  void SavedTabGroupMoved(const SavedTabGroup& group) override;
+  void SavedTabGroupMoved(const SavedTabGroup& group,
+                          int old_index,
+                          int new_index) override;
   void SavedTabGroupClosed(int index) override;
 
  private:
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
index 9665666..7bcf092 100644
--- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
+++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_bar_unittest.cc
@@ -102,3 +102,18 @@
   EXPECT_EQ(new_button_1->GetText(), kNewTitle);
   EXPECT_EQ(new_button_1->tab_group_color_id(), kNewColor);
 }
+
+TEST_F(SavedTabGroupBarUnitTest, MoveButtonFromModelMove) {
+  saved_tab_group_model()->Add(kSavedTabGroup1);
+  saved_tab_group_model()->Add(kSavedTabGroup2);
+
+  const auto& button_list = saved_tab_group_bar()->children();
+  views::View* button_1 = button_list[0];
+
+  // move the tab and expect the one that was moved to be in the expected
+  // position.
+  saved_tab_group_model()->Move(kSavedTabGroup1.group_id, 1);
+  EXPECT_EQ(2u, saved_tab_group_bar()->children().size());
+  EXPECT_NE(button_1, saved_tab_group_bar()->children()[0]);
+  EXPECT_EQ(button_1, saved_tab_group_bar()->children()[1]);
+}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index ca22c595..87227072 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2378,7 +2378,7 @@
   return bubble;
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
 views::Button* BrowserView::GetSharingHubIconButton() {
   return toolbar_button_provider()->GetPageActionIconView(
       PageActionIconType::kSharingHub);
@@ -2401,7 +2401,7 @@
 
   return bubble;
 }
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 ShowTranslateBubbleResult BrowserView::ShowTranslateBubble(
     content::WebContents* web_contents,
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index edb58f65..8de565d 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -502,12 +502,12 @@
       bool show_back_button) override;
   send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble(
       content::WebContents* contents) override;
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   views::Button* GetSharingHubIconButton() override;
 #else
   sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents) override;
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
index f35cb305..7070060 100644
--- a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
+++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
@@ -160,6 +160,7 @@
         form.password_value, views::style::CONTEXT_DIALOG_BODY_TEXT,
         STYLE_SECONDARY_MONOSPACED);
     label->SetObscured(true);
+    label->SetElideBehavior(gfx::TRUNCATE);
   } else {
     label = std::make_unique<views::Label>(
         l10n_util::GetStringFUTF16(IDS_PASSWORDS_VIA_FEDERATION,
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
index 452ef31..9b04983 100644
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view.cc
@@ -8,7 +8,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
 #include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
 #include "chrome/browser/ui/views/frame/app_menu_button.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc
index 10fad7139..c179d1e 100644
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -53,7 +53,7 @@
     views::NamedWidgetShownWaiter waiter(
         views::test::AnyWidgetTestPasskey{},
         PrivacySandboxDialogView::kViewClassName);
-    ShowPrivacySandboxDialog(browser(), dialog_type);
+    ShowPrivacySandboxPrompt(browser(), dialog_type);
     waiter.WaitIfNeededAndGet();
 
     base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_interactive_ui_test.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_interactive_ui_test.cc
index c00ff2d..be92119 100644
--- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_interactive_ui_test.cc
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_interactive_ui_test.cc
@@ -7,7 +7,7 @@
 #include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_dialog.h"
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -70,7 +70,7 @@
   views::NamedWidgetShownWaiter waiter(
       views::test::AnyWidgetTestPasskey{},
       PrivacySandboxDialogView::kViewClassName);
-  ShowPrivacySandboxDialog(browser(),
+  ShowPrivacySandboxPrompt(browser(),
                            PrivacySandboxService::DialogType::kNotice);
   auto* dialog = waiter.WaitIfNeededAndGet();
   EXPECT_TRUE(dialog);
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc
new file mode 100644
index 0000000..78cc227
--- /dev/null
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.cc
@@ -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.
+
+#include "chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h"
+
+#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/views/layout/fill_layout.h"
+
+// static
+void ShowPrivacySandboxNoticeBubble(Browser* browser) {
+  // TODO(crbug.com/1321587): Create BubbleDialogDelegate and show bubble.
+}
+
+PrivacySandboxNoticeBubbleView::PrivacySandboxNoticeBubbleView(Browser* browser)
+    : browser_(browser) {
+  // TODO(crbug.com/1321587): Implement view.
+  SetUseDefaultFillLayout(true);
+}
+
+BEGIN_METADATA(PrivacySandboxNoticeBubbleView, views::View)
+END_METADATA
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h
new file mode 100644
index 0000000..68b8e3e
--- /dev/null
+++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_notice_bubble_view.h
@@ -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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
+
+#include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/views/view.h"
+
+class Browser;
+
+// Content view of PrivacySandboxDialog notice UI. The bubble is anchored to
+// three-dot menu. It contains image, title, description and action buttons.
+class PrivacySandboxNoticeBubbleView : public views::View {
+ public:
+  METADATA_HEADER(PrivacySandboxNoticeBubbleView);
+  explicit PrivacySandboxNoticeBubbleView(Browser* browser);
+
+ private:
+  raw_ptr<Browser> browser_;
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_NOTICE_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
index d8bdf11..ca0a528 100644
--- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
+++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/share/share_metrics.h"
 #include "chrome/browser/sharing_hub/sharing_hub_model.h"
-#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h"
+#include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller_desktop_impl.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/chrome_typography.h"
 #include "chrome/browser/ui/views/sharing_hub/preview_view.h"
@@ -40,15 +40,16 @@
 SharingHubBubbleViewImpl::SharingHubBubbleViewImpl(
     views::View* anchor_view,
     content::WebContents* web_contents)
-    : LocationBarBubbleDelegateView(anchor_view, web_contents),
-      controller_(
-          SharingHubBubbleController::CreateOrGetFromWebContents(web_contents)
-              ->AsWeakPtr()) {
+    : LocationBarBubbleDelegateView(anchor_view, web_contents) {
   SetButtons(ui::DIALOG_BUTTON_NONE);
   set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric(
       views::DISTANCE_BUBBLE_PREFERRED_WIDTH));
   SetEnableArrowKeyTraversal(true);
-  DCHECK(controller_);
+
+  SharingHubBubbleControllerDesktopImpl* controller =
+      static_cast<SharingHubBubbleControllerDesktopImpl*>(
+          SharingHubBubbleController::CreateOrGetFromWebContents(web_contents));
+  controller_ = controller->AsWeakPtr();
 }
 
 SharingHubBubbleViewImpl::~SharingHubBubbleViewImpl() = default;
diff --git a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
index 60003ab..4a699911 100644
--- a/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
+++ b/chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h
@@ -21,7 +21,7 @@
 
 namespace sharing_hub {
 
-class SharingHubBubbleController;
+class SharingHubBubbleControllerDesktopImpl;
 class SharingHubBubbleActionButton;
 struct SharingHubAction;
 
@@ -80,7 +80,7 @@
   // the bubble during the window close path, since the bubble will be closed
   // asynchronously during browser window teardown but the controller will be
   // destroyed synchronously.
-  base::WeakPtr<SharingHubBubbleController> controller_;
+  base::WeakPtr<SharingHubBubbleControllerDesktopImpl> controller_;
 
   // ScrollView containing the list of share/save actions.
   raw_ptr<views::ScrollView> scroll_view_ = nullptr;
diff --git a/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc
new file mode 100644
index 0000000..1bd99ac
--- /dev/null
+++ b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.cc
@@ -0,0 +1,50 @@
+// 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/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
+
+#include "base/callback.h"
+#include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
+#include "chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h"
+#include "chrome/common/webui_url_constants.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/image_model.h"
+
+HistoryClustersSidePanelCoordinator::HistoryClustersSidePanelCoordinator(
+    Browser* browser)
+    : BrowserUserData<HistoryClustersSidePanelCoordinator>(*browser) {}
+
+HistoryClustersSidePanelCoordinator::~HistoryClustersSidePanelCoordinator() =
+    default;
+
+void HistoryClustersSidePanelCoordinator::CreateAndRegisterEntry(
+    SidePanelRegistry* global_registry) {
+  global_registry->Register(std::make_unique<SidePanelEntry>(
+      SidePanelEntry::Id::kHistoryClusters,
+      l10n_util::GetStringUTF16(IDS_HISTORY_CLUSTERS_JOURNEYS_TAB_LABEL),
+      ui::ImageModel::FromVectorIcon(kJourneysIcon, ui::kColorIcon),
+      base::BindRepeating(
+          &HistoryClustersSidePanelCoordinator::CreateHistoryClustersWebView,
+          base::Unretained(this))));
+}
+
+std::unique_ptr<views::View>
+HistoryClustersSidePanelCoordinator::CreateHistoryClustersWebView() {
+  return std::make_unique<SidePanelWebUIViewT<HistoryClustersSidePanelUI>>(
+      &GetBrowser(), base::RepeatingClosure(), base::RepeatingClosure(),
+      std::make_unique<BubbleContentsWrapperT<HistoryClustersSidePanelUI>>(
+          GURL(chrome::kChromeUIHistoryClustersSidePanelURL),
+          GetBrowser().profile(), IDS_HISTORY_CLUSTERS_JOURNEYS_TAB_LABEL,
+          /*webui_resizes_host=*/false,
+          /*esc_closes_ui=*/false));
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(HistoryClustersSidePanelCoordinator);
diff --git a/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h
new file mode 100644
index 0000000..7ab47d4
--- /dev/null
+++ b/chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h
@@ -0,0 +1,41 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_COORDINATOR_H_
+#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_COORDINATOR_H_
+
+#include <memory>
+
+#include "chrome/browser/ui/browser_user_data.h"
+
+class Browser;
+class SidePanelRegistry;
+
+namespace views {
+class View;
+}
+
+// HistoryClustersSidePanelCoordinator handles the creation and registration of
+// the history clusters SidePanelEntry.
+class HistoryClustersSidePanelCoordinator
+    : public BrowserUserData<HistoryClustersSidePanelCoordinator> {
+ public:
+  explicit HistoryClustersSidePanelCoordinator(Browser* browser);
+  HistoryClustersSidePanelCoordinator(
+      const HistoryClustersSidePanelCoordinator&) = delete;
+  HistoryClustersSidePanelCoordinator& operator=(
+      const HistoryClustersSidePanelCoordinator&) = delete;
+  ~HistoryClustersSidePanelCoordinator() override;
+
+  void CreateAndRegisterEntry(SidePanelRegistry* global_registry);
+
+ private:
+  friend class BrowserUserData<HistoryClustersSidePanelCoordinator>;
+
+  std::unique_ptr<views::View> CreateHistoryClustersWebView();
+
+  BROWSER_USER_DATA_KEY_DECL();
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_COORDINATOR_H_
diff --git a/chrome/browser/ui/views/side_panel/side_panel_entry.h b/chrome/browser/ui/views/side_panel/side_panel_entry.h
index dc21301e..126e6a7 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_entry.h
+++ b/chrome/browser/ui/views/side_panel/side_panel_entry.h
@@ -24,6 +24,7 @@
     // Global Entries
     kReadingList,
     kBookmarks,
+    kHistoryClusters,
     kReadAnything,
     kUserNote,
     kFeed,
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.cc b/chrome/browser/ui/views/side_panel/side_panel_util.cc
index ae9790f..8b334421f 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_util.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_util.cc
@@ -5,8 +5,10 @@
 #include "chrome/browser/ui/views/side_panel/side_panel_util.h"
 
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/side_panel/bookmarks/bookmarks_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/feed/feed_side_panel_coordinator.h"
+#include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/reading_list/reading_list_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
@@ -26,6 +28,12 @@
   BookmarksSidePanelCoordinator::GetOrCreateForBrowser(browser)
       ->CreateAndRegisterEntry(global_registry);
 
+  // Add history clusters.
+  if (base::FeatureList::IsEnabled(features::kSidePanelJourneys)) {
+    HistoryClustersSidePanelCoordinator::GetOrCreateForBrowser(browser)
+        ->CreateAndRegisterEntry(global_registry);
+  }
+
   // Add read anything.
   if (features::IsReadAnythingEnabled()) {
     ReadAnythingCoordinator::GetOrCreateForBrowser(browser)
diff --git a/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc b/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
index 38001248..4c17d2c 100644
--- a/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
+++ b/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
@@ -11,13 +11,13 @@
 #include <vector>
 
 #include "base/containers/flat_map.h"
-#include "base/template_util.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "components/services/app_service/public/cpp/app_update.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "components/services/app_service/public/cpp/preferred_app.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 AppServiceInternalsPageHandlerImpl::AppServiceInternalsPageHandlerImpl(
     Profile* profile)
@@ -42,7 +42,7 @@
         std::stringstream debug_info;
         debug_info << update;
 
-        result.emplace_back(base::in_place, update.AppId(), update.Name(),
+        result.emplace_back(absl::in_place, update.AppId(), update.Name(),
                             debug_info.str());
       });
 
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 72bee1a..9674d3af 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -155,6 +155,7 @@
 #include "chrome/browser/ui/webui/settings/settings_ui.h"
 #include "chrome/browser/ui/webui/settings/settings_utils.h"
 #include "chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.h"
+#include "chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h"
 #include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_ui.h"
 #include "chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.h"
 #include "chrome/browser/ui/webui/signin/sync_confirmation_ui.h"
@@ -866,6 +867,10 @@
     return &NewWebUI<ReadingListUI>;
   if (url.host_piece() == chrome::kChromeUIBookmarksSidePanelHost)
     return &NewWebUI<BookmarksSidePanelUI>;
+  if (base::FeatureList::IsEnabled(features::kSidePanelJourneys)) {
+    if (url.host_piece() == chrome::kChromeUIHistoryClustersSidePanelHost)
+      return &NewWebUI<HistoryClustersSidePanelUI>;
+  }
   if (features::IsReadAnythingEnabled()) {
     if (url.host_piece() == chrome::kChromeUIReadAnythingSidePanelHost)
       return &NewWebUI<ReadAnythingUI>;
diff --git a/chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.cc
index 8157e4c..3550b06 100644
--- a/chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/update_required_screen_handler.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/values.h"
+#include "build/branding_buildflags.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
 #include "chrome/browser/ash/login/screens/update_required_screen.h"
 #include "chrome/grit/chromium_strings.h"
@@ -79,6 +80,14 @@
                IDS_UPDATE_REQUIRED_EOL_DELETE_USERS_DATA_CONFIRM);
   builder->Add("eolDeleteUsersDataCancel",
                IDS_UPDATE_REQUIRED_EOL_DELETE_USERS_DATA_CANCEL);
+
+#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  builder->Add("cancelUpdateHint", IDS_UPDATE_CANCEL);
+  builder->Add("cancelledUpdateMessage", IDS_UPDATE_CANCELLED);
+#else
+  builder->Add("cancelUpdateHint", IDS_EMPTY_STRING);
+  builder->Add("cancelledUpdateMessage", IDS_EMPTY_STRING);
+#endif
 }
 
 void UpdateRequiredScreenHandler::InitializeDeprecated() {
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
index 89eef97c..ba77fe5 100644
--- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
@@ -8,7 +8,6 @@
 
 #include "ash/constants/ash_features.h"
 #include "base/values.h"
-#include "build/branding_buildflags.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
 #include "chrome/browser/ash/login/screens/update_screen.h"
 #include "chrome/grit/chromium_strings.h"
@@ -143,14 +142,6 @@
   builder->Add("slideUnselectedButtonLabel",
                IDS_UPDATE_UNSELECTED_BUTTON_LABEL);
 
-#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
-  builder->Add("cancelUpdateHint", IDS_UPDATE_CANCEL);
-  builder->Add("cancelledUpdateMessage", IDS_UPDATE_CANCELLED);
-#else
-  builder->Add("cancelUpdateHint", IDS_EMPTY_STRING);
-  builder->Add("cancelledUpdateMessage", IDS_EMPTY_STRING);
-#endif
-
   builder->Add("updateOverCellularPromptTitle",
                IDS_UPDATE_OVER_CELLULAR_PROMPT_TITLE);
   builder->Add("updateOverCellularPromptMessage",
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters.mojom b/chrome/browser/ui/webui/history_clusters/history_clusters.mojom
index c2fe150..1726e12 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters.mojom
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters.mojom
@@ -131,10 +131,6 @@
   // The ClustersBrowserProxy singleton calls this when it's first initialized.
   SetPage(pending_remote<Page> page);
 
-  // Notifies the native handler whether the History Clusters Page is selected.
-  // Called when the WebUI page is loaded, and when the user switches tabs.
-  NotifyHistoryClustersSelected(bool history_clusters_selected);
-
   // Toggles the visibility of the History Clusters. The returned Promise echos
   // the given value for `visible`. The page uses the returned value to update
   // its state once the request is fulfilled by the browser.
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
index af0b0df..f2b8b5c 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -15,7 +15,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
-#include "base/timer/elapsed_timer.h"
 #include "chrome/browser/history_clusters/history_clusters_metrics_logger.h"
 #include "chrome/browser/history_clusters/history_clusters_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -222,18 +221,6 @@
   return result_mojom;
 }
 
-// An internal only class used to track WebUI lifetime.
-class HistoryClustersHandler::ScopedElapsedTimer {
- public:
-  ~ScopedElapsedTimer() {
-    base::UmaHistogramLongTimes100("History.Clusters.WebUISessionDuration",
-                                   timer_.Elapsed());
-  }
-
- private:
-  base::ElapsedTimer timer_;
-};
-
 HistoryClustersHandler::HistoryClustersHandler(
     mojo::PendingReceiver<mojom::PageHandler> pending_page_handler,
     Profile* profile,
@@ -264,17 +251,6 @@
   std::move(callback).Run(visible);
 }
 
-void HistoryClustersHandler::NotifyHistoryClustersSelected(
-    bool history_clusters_selected) {
-  if (history_clusters_selected) {
-    if (!webui_session_duration_) {
-      webui_session_duration_ = std::make_unique<ScopedElapsedTimer>();
-    }
-  } else {
-    webui_session_duration_.reset();
-  }
-}
-
 void HistoryClustersHandler::StartQueryClusters(const std::string& query) {
   if (!query.empty()) {
     // If the query string is not empty, we assume that this clusters query
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
index bc15bcf..6b986a68 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -59,7 +59,6 @@
   void SetPage(mojo::PendingRemote<mojom::Page> pending_page) override;
   void ToggleVisibility(bool visible,
                         ToggleVisibilityCallback callback) override;
-  void NotifyHistoryClustersSelected(bool history_clusters_selected) override;
   void StartQueryClusters(const std::string& query) override;
   void LoadMoreClusters(const std::string& query) override;
   void RemoveVisits(std::vector<mojom::URLVisitPtr> visits,
@@ -70,9 +69,6 @@
   void OnDebugMessage(const std::string& message) override;
 
  private:
-  // An internal only class used to track WebUI lifetime.
-  class ScopedElapsedTimer;
-
   // Called with the result of querying clusters. Subsequently, `query_result`
   // is sent to the JS to update the UI.
   void OnClustersQueryResult(mojom::QueryResultPtr query_result);
@@ -96,11 +92,6 @@
   // Encapsulates the currently loaded clusters state on the page.
   std::unique_ptr<QueryClustersState> query_clusters_state_;
 
-  // A page lifetime timer used to record how long the user spends on the WebUI.
-  // This is specifically not constructed in the class constructor because the
-  // user may be looking at a different tab.
-  std::unique_ptr<ScopedElapsedTimer> webui_session_duration_;
-
   base::WeakPtrFactory<HistoryClustersHandler> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/webui/profile_internals/profile_internals_handler.cc b/chrome/browser/ui/webui/profile_internals/profile_internals_handler.cc
index 97b72a7..0d51b88 100644
--- a/chrome/browser/ui/webui/profile_internals/profile_internals_handler.cc
+++ b/chrome/browser/ui/webui/profile_internals/profile_internals_handler.cc
@@ -5,9 +5,46 @@
 #include "chrome/browser/ui/webui/profile_internals/profile_internals_handler.h"
 
 #include "base/bind.h"
+#include "base/json/values_util.h"
 #include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_attributes_entry.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "components/signin/public/identity_manager/account_info.h"
 #include "content/public/browser/web_ui.h"
 
+namespace {
+
+base::Value CreateProfileEntry(const ProfileAttributesEntry* entry) {
+  base::Value profile_entry(base::Value::Type::DICTIONARY);
+  profile_entry.SetKey("profilePath", base::FilePathToValue(entry->GetPath()));
+  profile_entry.SetStringKey("localProfileName", entry->GetLocalProfileName());
+  std::string signin_state;
+  switch (entry->GetSigninState()) {
+    case SigninState::kNotSignedIn:
+      signin_state = "Not signed in";
+      break;
+    case SigninState::kSignedInWithUnconsentedPrimaryAccount:
+      signin_state = "Signed in with unconsented primary account";
+      break;
+    case SigninState::kSignedInWithConsentedPrimaryAccount:
+      signin_state = "Signed in with consented primary account";
+      break;
+  }
+  profile_entry.SetStringKey("signinState", signin_state);
+  profile_entry.SetBoolKey("signinRequired", entry->IsSigninRequired());
+  // GAIA full name/user name can be empty, if the profile is not signed in to
+  // chrome.
+  profile_entry.SetStringKey("gaiaName", entry->GetGAIAName());
+  profile_entry.SetStringKey("gaiaId", entry->GetGAIAId());
+  profile_entry.SetStringKey("userName", entry->GetUserName());
+  profile_entry.SetStringKey("hostedDomain", entry->GetHostedDomain());
+  return profile_entry;
+}
+
+}  // namespace
+
 ProfileInternalsHandler::ProfileInternalsHandler() = default;
 
 ProfileInternalsHandler::~ProfileInternalsHandler() = default;
@@ -15,15 +52,30 @@
 void ProfileInternalsHandler::RegisterMessages() {
   web_ui()->RegisterMessageCallback(
       "getProfilesList",
-      base::BindRepeating(&ProfileInternalsHandler::HandleProfilesChanged,
+      base::BindRepeating(&ProfileInternalsHandler::HandleGetProfilesList,
                           base::Unretained(this)));
 }
 
-void ProfileInternalsHandler::HandleProfilesChanged(
+void ProfileInternalsHandler::HandleGetProfilesList(
     const base::Value::List& args) {
   AllowJavascript();
-
   CHECK_EQ(0u, args.size());
-  base::Value v("Under construction.");
-  FireWebUIListener("profiles-changed", v);
+  PushProfilesList();
+}
+
+void ProfileInternalsHandler::PushProfilesList() {
+  DCHECK(IsJavascriptAllowed());
+  FireWebUIListener("profiles-list-changed", GetProfilesList());
+}
+
+base::Value ProfileInternalsHandler::GetProfilesList() {
+  base::Value profiles_list(base::Value::Type::LIST);
+  std::vector<ProfileAttributesEntry*> entries =
+      g_browser_process->profile_manager()
+          ->GetProfileAttributesStorage()
+          .GetAllProfilesAttributesSortedByLocalProfilName();
+  for (const ProfileAttributesEntry* entry : entries) {
+    profiles_list.Append(CreateProfileEntry(entry));
+  }
+  return profiles_list;
 }
diff --git a/chrome/browser/ui/webui/profile_internals/profile_internals_handler.h b/chrome/browser/ui/webui/profile_internals/profile_internals_handler.h
index 963d65f..97d937c 100644
--- a/chrome/browser/ui/webui/profile_internals/profile_internals_handler.h
+++ b/chrome/browser/ui/webui/profile_internals/profile_internals_handler.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_PROFILE_INTERNALS_PROFILE_INTERNALS_HANDLER_H_
 
 #include "base/values.h"
+#include "chrome/browser/profiles/profile_attributes_entry.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
 // Handles actions on Profile Internals debug page.
@@ -22,7 +23,12 @@
   void RegisterMessages() override;
 
  private:
-  void HandleProfilesChanged(const base::Value::List& args);
+  void HandleGetProfilesList(const base::Value::List& args);
+
+  void PushProfilesList();
+
+  // Returns the list of profiles ordered by the local profile name.
+  base::Value GetProfilesList();
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_PROFILE_INTERNALS_PROFILE_INTERNALS_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 88420130..7a63cdf 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2141,6 +2141,8 @@
     {"cookiesManageSiteSpecificExceptions",
      IDS_SETTINGS_COOKIES_SITE_SPECIFIC_EXCEPTIONS},
     {"siteSettingsCategoryCookies", IDS_SITE_SETTINGS_TYPE_COOKIES},
+    {"siteSettingsCategoryFederatedIdentityApi",
+     IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API},
     {"siteSettingsCategoryHandlers", IDS_SITE_SETTINGS_TYPE_HANDLERS},
     {"siteSettingsCategoryImages", IDS_SITE_SETTINGS_TYPE_IMAGES},
     {"siteSettingsCategoryInsecureContent",
@@ -2584,6 +2586,20 @@
      IDS_SETTINGS_SITE_SETTINGS_DEVICE_USE_ALLOWED_EXCEPTIONS},
     {"siteSettingsDeviceUseBlockedExceptions",
      IDS_SETTINGS_SITE_SETTINGS_DEVICE_USE_BLOCKED_EXCEPTIONS},
+    {"siteSettingsFederatedIdentityApi",
+     IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API},
+    {"siteSettingsFederatedIdentityApiAllowed",
+     IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED},
+    {"siteSettingsFederatedIdentityApiBlocked",
+     IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED},
+    {"siteSettingsFederatedIdentityApiAllowedExceptions",
+     IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_ALLOWED_EXCEPTIONS},
+    {"siteSettingsFederatedIdentityApiBlockedExceptions",
+     IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_BLOCKED_EXCEPTIONS},
+    {"siteSettingsFederatedIdentityApiDescription",
+     IDS_SETTINGS_SITE_SETTINGS_FEDERATED_IDENTITY_API_DESCRIPTION},
+    {"siteSettingsFederatedIdentityApiMidSentence",
+     IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE},
     {"siteSettingsFileSystemWriteDescription",
      IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_WRITE_DESCRIPTION},
     {"siteSettingsFileSystemWriteAllowed",
@@ -2829,6 +2845,12 @@
       "enablePaymentHandlerContentSetting",
       base::FeatureList::IsEnabled(features::kServiceWorkerPaymentApps));
 
+  html_source->AddBoolean(
+      "enableFederatedIdentityApiContentSetting",
+      GetFieldTrialParamByFeatureAsBool(
+          features::kFedCm, features::kFedCmDesktopSettingsFieldTrialParamName,
+          false));
+
   base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
   html_source->AddBoolean(
       "enableExperimentalWebPlatformFeatures",
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 24f9a0d..f7d1a43 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -367,12 +367,12 @@
                    profile, chrome::FaviconUrlFormat::kFavicon2));
 
   // Privacy Sandbox
-  bool isPrivacySandboxRestricted =
+  bool is_privacy_sandbox_restricted =
       PrivacySandboxServiceFactory::GetForProfile(profile)
           ->IsPrivacySandboxRestricted();
   html_source->AddBoolean("isPrivacySandboxRestricted",
-                          isPrivacySandboxRestricted);
-  if (!isPrivacySandboxRestricted) {
+                          is_privacy_sandbox_restricted);
+  if (!is_privacy_sandbox_restricted) {
     html_source->AddResourcePath(
         "privacySandbox", IDR_SETTINGS_PRIVACY_SANDBOX_PRIVACY_SANDBOX_HTML);
   }
diff --git a/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chrome/browser/ui/webui/settings/site_settings_helper.cc
index 9a04b60..691e3878 100644
--- a/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -31,6 +31,7 @@
 #include "chrome/browser/usb/usb_chooser_context.h"
 #include "chrome/browser/usb/usb_chooser_context_factory.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings.h"
@@ -123,6 +124,7 @@
     {ContentSettingsType::LOCAL_FONTS, "local-fonts"},
     {ContentSettingsType::FILE_SYSTEM_ACCESS_CHOOSER_DATA,
      "file-system-access-handles-data"},
+    {ContentSettingsType::FEDERATED_IDENTITY_API, "federated-identity-api"},
 
     // Add new content settings here if a corresponding Javascript string
     // representation for it is not required, for example if the content setting
@@ -165,7 +167,6 @@
     {ContentSettingsType::HTTP_ALLOWED, nullptr},
     {ContentSettingsType::FORMFILL_METADATA, nullptr},
     {ContentSettingsType::FEDERATED_IDENTITY_ACTIVE_SESSION, nullptr},
-    {ContentSettingsType::FEDERATED_IDENTITY_API, nullptr},
     {ContentSettingsType::AUTO_DARK_WEB_CONTENT, nullptr},
     {ContentSettingsType::REQUEST_DESKTOP_SITE, nullptr},
     {ContentSettingsType::GET_DISPLAY_MEDIA_SET_SELECT_ALL_SCREENS, nullptr},
@@ -461,6 +462,12 @@
     if (base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps))
       base_types->push_back(ContentSettingsType::PAYMENT_HANDLER);
 
+    if (GetFieldTrialParamByFeatureAsBool(
+            features::kFedCm,
+            features::kFedCmDesktopSettingsFieldTrialParamName, false)) {
+      base_types->push_back(ContentSettingsType::FEDERATED_IDENTITY_API);
+    }
+
     if (base::FeatureList::IsEnabled(
             features::kWebBluetoothNewPermissionsBackend)) {
       base_types->push_back(ContentSettingsType::BLUETOOTH_GUARD);
diff --git a/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.cc b/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.cc
new file mode 100644
index 0000000..52d441a
--- /dev/null
+++ b/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.cc
@@ -0,0 +1,15 @@
+// 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/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h"
+
+#include <string>
+#include <utility>
+
+HistoryClustersSidePanelUI::HistoryClustersSidePanelUI(content::WebUI* web_ui)
+    : ui::MojoBubbleWebUIController(web_ui) {}
+
+HistoryClustersSidePanelUI::~HistoryClustersSidePanelUI() = default;
+
+WEB_UI_CONTROLLER_TYPE_IMPL(HistoryClustersSidePanelUI)
diff --git a/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h b/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h
new file mode 100644
index 0000000..63beeb9a
--- /dev/null
+++ b/chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h
@@ -0,0 +1,22 @@
+// 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_UI_WEBUI_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_UI_H_
+
+#include "ui/webui/mojo_bubble_web_ui_controller.h"
+
+class HistoryClustersSidePanelUI : public ui::MojoBubbleWebUIController {
+ public:
+  explicit HistoryClustersSidePanelUI(content::WebUI* web_ui);
+  HistoryClustersSidePanelUI(const HistoryClustersSidePanelUI&) = delete;
+  HistoryClustersSidePanelUI& operator=(const HistoryClustersSidePanelUI&) =
+      delete;
+  ~HistoryClustersSidePanelUI() override;
+
+ private:
+  WEB_UI_CONTROLLER_TYPE_DECL();
+};
+
+#endif  // CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_HISTORY_CLUSTERS_HISTORY_CLUSTERS_SIDE_PANEL_UI_H_
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc
index 5afcf19..527715a 100644
--- a/chrome/browser/ui/webui/webui_util.cc
+++ b/chrome/browser/ui/webui/webui_util.cc
@@ -70,7 +70,7 @@
       g_browser_process->platform_part()->browser_policy_connector_ash();
   return connector->IsDeviceEnterpriseManaged();
 #elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-  return base::IsMachineExternallyManaged();
+  return base::IsManagedDevice();
 #else
   return false;
 #endif
diff --git a/chrome/browser/uid/android/BUILD.gn b/chrome/browser/uid/android/BUILD.gn
index 5081bc3b..6aa0460 100644
--- a/chrome/browser/uid/android/BUILD.gn
+++ b/chrome/browser/uid/android/BUILD.gn
@@ -27,7 +27,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base/test:test_support_java",
     "//build/android:build_java",
diff --git a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
index 8b9fec4..7fa7f602 100644
--- a/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector/upgrade_detector_impl.cc
@@ -221,7 +221,7 @@
 #if BUILDFLAG(IS_WIN)
     // TODO(crbug/1027107): Replace with a more generic CBCM check.
     // Don't show the update bubbles to enterprise users.
-    if (base::IsMachineExternallyManaged() ||
+    if (base::IsEnterpriseDevice() ||
         policy::BrowserDMTokenStorage::Get()->RetrieveDMToken().is_valid()) {
       return;
     }
diff --git a/chrome/browser/user_notes/user_notes_tab_helper.cc b/chrome/browser/user_notes/user_notes_tab_helper.cc
index 3fd594f..ebad8e83 100644
--- a/chrome/browser/user_notes/user_notes_tab_helper.cc
+++ b/chrome/browser/user_notes/user_notes_tab_helper.cc
@@ -6,8 +6,8 @@
 
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/user_notes/user_note_service_factory.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/browser/user_note_service.h"
-#include "components/user_notes/browser/user_notes_manager.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/page.h"
 #include "content/public/browser/render_frame_host.h"
@@ -28,8 +28,8 @@
 UserNotesTabHelper::~UserNotesTabHelper() = default;
 
 void UserNotesTabHelper::PrimaryPageChanged(content::Page& page) {
-  if (!UserNotesManager::GetForPage(page)) {
-    UserNotesManager::CreateForPage(page, service()->GetSafeRef());
+  if (!UserNoteManager::GetForPage(page)) {
+    UserNoteManager::CreateForPage(page, service()->GetSafeRef());
   }
 }
 
diff --git a/chrome/browser/user_notes/user_notes_tab_helper_unittest.cc b/chrome/browser/user_notes/user_notes_tab_helper_unittest.cc
index ee15fac..99bb88e 100644
--- a/chrome/browser/user_notes/user_notes_tab_helper_unittest.cc
+++ b/chrome/browser/user_notes/user_notes_tab_helper_unittest.cc
@@ -12,8 +12,8 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/user_notes/user_note_service_factory.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/browser/user_note_service.h"
-#include "components/user_notes/browser/user_notes_manager.h"
 #include "components/user_notes/interfaces/user_note_service_delegate.h"
 #include "components/user_notes/user_notes_features.h"
 #include "content/public/browser/navigation_handle.h"
@@ -32,10 +32,10 @@
 
 const char kTestDomain[] = "http://www.google.com/";
 
-// Matcher that verifies whether the page has an attached `UserNotesManager` via
+// Matcher that verifies whether the page has an attached `UserNoteManager` via
 // the navigation handle supplied as arg.
-MATCHER(HasUserNotesManager, "") {
-  return arg != nullptr && UserNotesManager::GetForPage(
+MATCHER(HasUserNoteManager, "") {
+  return arg != nullptr && UserNoteManager::GetForPage(
                                arg->GetRenderFrameHost()->GetPage()) != nullptr;
 }
 
@@ -99,14 +99,14 @@
 };
 
 // Tests that by the time `UserNotesTabHelper::DidFinishNavigation` is called,
-// a `UserNotesManager` is already attached to the `Page` of the navigated
+// a `UserNoteManager` is already attached to the `Page` of the navigated
 // frame.
-TEST_F(UserNotesTabHelperTest, AttachUserNotesManagerToPage) {
+TEST_F(UserNotesTabHelperTest, AttachUserNoteManagerToPage) {
   // Partially mock the `UserNotesTabHelper` to intercept calls to
   // `DidFinishNavigation` and prevent side effects.
   auto mock_tab_helper =
       std::make_unique<MockUserNotesTabHelper>(web_contents());
-  EXPECT_CALL(*mock_tab_helper, DidFinishNavigation(HasUserNotesManager()))
+  EXPECT_CALL(*mock_tab_helper, DidFinishNavigation(HasUserNoteManager()))
       .Times(4);
   AttachTabHelper(std::move(mock_tab_helper));
 
diff --git a/chrome/browser/video_tutorials/BUILD.gn b/chrome/browser/video_tutorials/BUILD.gn
index 8523c7e..845d614f 100644
--- a/chrome/browser/video_tutorials/BUILD.gn
+++ b/chrome/browser/video_tutorials/BUILD.gn
@@ -110,7 +110,6 @@
     # These deps will be inherited by the resulting android_library target.
     deps = [
       ":java",
-      "//base:base_java",
       "//chrome/browser/profiles/android:java",
       "//components/embedder_support/android:content_view_java",
       "//components/image_fetcher:java",
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 d99d5e7..3117475 100644
--- a/chrome/browser/web_applications/os_integration/web_app_shortcut.cc
+++ b/chrome/browser/web_applications/os_integration/web_app_shortcut.cc
@@ -18,6 +18,7 @@
 #include "base/logging.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/task/lazy_thread_pool_task_runner.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "build/build_config.h"
@@ -53,6 +54,19 @@
 const int kDesiredIconSizesForShortcut[] = {32};
 #endif
 
+#if BUILDFLAG(IS_WIN)
+base::LazyThreadPoolCOMSTATaskRunner g_shortcuts_task_runner =
+    LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
+        base::TaskTraits({base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+                          base::TaskShutdownBehavior::BLOCK_SHUTDOWN}),
+        base::SingleThreadTaskRunnerThreadMode::SHARED);
+#else
+base::LazyThreadPoolSequencedTaskRunner g_shortcuts_task_runner =
+    LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
+        base::TaskTraits({base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+                          base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));
+#endif
+
 size_t GetNumDesiredIconSizesForShortcut() {
 #if BUILDFLAG(IS_WIN)
   return IconUtil::kNumIconDimensions;
@@ -335,16 +349,7 @@
 }
 
 scoped_refptr<base::TaskRunner> GetShortcutIOTaskRunner() {
-  constexpr base::TaskTraits traits = {
-      base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-      base::TaskShutdownBehavior::BLOCK_SHUTDOWN};
-
-#if BUILDFLAG(IS_WIN)
-  return base::ThreadPool::CreateCOMSTATaskRunner(
-      traits, base::SingleThreadTaskRunnerThreadMode::SHARED);
-#else
-  return base::ThreadPool::CreateTaskRunner(traits);
-#endif
+  return g_shortcuts_task_runner.Get();
 }
 
 base::FilePath GetShortcutDataDir(const ShortcutInfo& shortcut_info) {
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java
index 0942c283..50fd3c7 100644
--- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java
+++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/FeedActionsHandler.java
@@ -157,4 +157,26 @@
      * @param toInvalidate Identifies which feed or feeds should have their caches invalidated.
      */
     default void invalidateContentCacheFor(@FeedIdentifier int toInvalidate) {}
+
+    /** Actions that could occur for an info card. */
+    @IntDef({InfoCardAction.INFO_CARD_TRACK_VIEW_STARTED, InfoCardAction.INFO_CARD_VIEWED,
+            InfoCardAction.INFO_CARD_CLICKED, InfoCardAction.INFO_CARD_DISMISSED_EXPLIICITLY})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InfoCardAction {
+        // The info card is being tracked for its full visibility.
+        int INFO_CARD_TRACK_VIEW_STARTED = 0;
+        // The info card is fully visible in the viewport.
+        int INFO_CARD_VIEWED = 1;
+        // The user tapps the info card.
+        int INFO_CARD_CLICKED = 2;
+        // The user dismisses the info card explicitly by tapping the close button.
+        int INFO_CARD_DISMISSED_EXPLIICITLY = 3;
+    }
+
+    /**
+     * Reports that an action has occurred for an info card.
+     * @param type Type of the info card.
+     * @param action Action that occurred.
+     */
+    default void reportInfoCardAction(int type, @InfoCardAction int action) {}
 }
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java
index 8b8555d7..b22768d 100644
--- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java
+++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java
@@ -42,6 +42,9 @@
     /** Add the url to the reading list and make it available offline. */
     default void addToReadingList(String title, String url) {}
 
+    /** Opens Crow CCT for the URL. */
+    default void navigateCrow(String url) {}
+
     /**
      * Open a bottom sheet with the view as contents.
      * @param view The bottom sheet contents view.
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index b050fcaf..616f19dd 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1651579124-144d4dd461b34a7fd4832c142f61673e6ee52afe.profdata
+chrome-linux-main-1651600749-293095709bc7e99c57d4004858d7f71bff85adcf.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index e141dbd..5388850 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1651579124-9277e786c7b0d9ed3d4074d1951ae34069a6062f.profdata
+chrome-mac-arm-main-1651600749-b9a2c01e9dbd97fb92f9f936e9d1ad79000032dc.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index be474d0..27dc73d 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1651579124-fbeb4493c4b82d4f9c4e0eee55b929c01e36a934.profdata
+chrome-mac-main-1651600749-9060fbc1510a41142d18911e5c4d54925cef3ebb.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 3e86d0ad..23c536c 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1651579124-f7d9ea5cd369d587072f9cd911ff739761dc0905.profdata
+chrome-win32-main-1651600749-d0a64482b90fc48678043c783c6485c105cc8bf9.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 978e3e7..3a86406 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1651579124-150a3765e75ed68b3e152801c7de4d12af3e31b4.profdata
+chrome-win64-main-1651600749-d084d138bfab0079c439eb7dadd28c89c47026ab.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index aa3289fb..eb82506 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -416,6 +416,12 @@
 const base::Feature kExternalExtensionDefaultButtonControl{
     "ExternalExtensionDefaultButtonControl", base::FEATURE_DISABLED_BY_DEFAULT};
 
+#if !BUILDFLAG(IS_ANDROID)
+// Field trial boolean parameter which indicates whether FedCM desktop settings
+// are enabled.
+const char kFedCmDesktopSettingsFieldTrialParamName[] = "DesktopSettings";
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 #if BUILDFLAG(ENABLE_PLUGINS)
 // Show Flash deprecation warning to users who have manually enabled Flash.
 // https://crbug.com/918428
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 7a882fa..66198144 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -293,6 +293,11 @@
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kExternalExtensionDefaultButtonControl;
 
+#if !BUILDFLAG(IS_ANDROID)
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const char kFedCmDesktopSettingsFieldTrialParamName[];
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 #if BUILDFLAG(ENABLE_PLUGINS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kFlashDeprecationWarning;
diff --git a/chrome/common/features.gni b/chrome/common/features.gni
index 951c321..e667609 100644
--- a/chrome/common/features.gni
+++ b/chrome/common/features.gni
@@ -35,8 +35,8 @@
   builtin_cert_verifier_policy_supported = is_mac
 
   # Enables support for background apps.
-  enable_background_contents = !is_android && !is_chromecast
-  enable_background_mode = !is_android && !is_chromecast && !is_chromeos
+  enable_background_contents = !is_android && !is_castos
+  enable_background_mode = !is_android && !is_castos && !is_chromeos
 
   # Enable the printing system dialog for platforms that support printing
   # and have a system dialog.
@@ -53,13 +53,13 @@
   enable_hangout_services_extension = is_chrome_branded
 
   enable_one_click_signin = is_win || is_mac || is_fuchsia ||
-                            ((is_linux && !is_chromecast) || is_chromeos_lacros)
+                            ((is_linux && !is_castos) || is_chromeos_lacros)
 
   enable_service_discovery = (enable_mdns && !is_android) || is_mac
 
   # Enables use of the session service, which is enabled by default.
   # Android stores them separately on the Java side.
-  enable_session_service = !is_android && !is_chromecast
+  enable_session_service = !is_android && !is_castos
 
   # Enables usage of the side search feature, which is disabled by default.
   enable_side_search = toolkit_views
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 9359fa03..b6fbd83 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -136,6 +136,12 @@
     "profile.managed.approved_extensions";
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
 
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+// Integer pref to record the day id (number of days since origin of time) when
+// supervised user metrics were last recorded.
+const char kSupervisedUserMetricsDayId[] = "supervised_user.metrics.day_id";
+#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
+
 // Stores the email address associated with the google account of the custodian
 // of the supervised user, set when the supervised user is created.
 const char kSupervisedUserCustodianEmail[] = "profile.managed.custodian_email";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index fafca83..1fc9d10 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -51,6 +51,9 @@
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
 extern const char kSupervisedUserApprovedExtensions[];
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS) && BUILDFLAG(ENABLE_EXTENSIONS)
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+extern const char kSupervisedUserMetricsDayId[];
+#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
 extern const char kSupervisedUserCustodianEmail[];
 extern const char kSupervisedUserCustodianName[];
 extern const char kSupervisedUserCustodianObfuscatedGaiaId[];
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index 40a38843..16da46f5 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -251,6 +251,10 @@
     "bookmarks-side-panel.top-chrome";
 const char kChromeUIBookmarksSidePanelURL[] =
     "chrome://bookmarks-side-panel.top-chrome/";
+const char kChromeUIHistoryClustersSidePanelHost[] =
+    "history-clusters-side-panel.top-chrome";
+const char kChromeUIHistoryClustersSidePanelURL[] =
+    "chrome://history-clusters-side-panel.top-chrome/";
 const char kChromeUIReadAnythingSidePanelHost[] =
     "read-anything-side-panel.top-chrome";
 const char kChromeUIReadAnythingSidePanelURL[] =
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index e3c8fbe..83e585a 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -234,6 +234,8 @@
 extern const char kChromeUINearbyInternalsHost[];
 extern const char kChromeUIBookmarksSidePanelHost[];
 extern const char kChromeUIBookmarksSidePanelURL[];
+extern const char kChromeUIHistoryClustersSidePanelHost[];
+extern const char kChromeUIHistoryClustersSidePanelURL[];
 extern const char kChromeUIReadAnythingSidePanelHost[];
 extern const char kChromeUIReadAnythingSidePanelURL[];
 extern const char kChromeUIReadLaterHost[];
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc
index ee8f84c..eeaa98e 100644
--- a/chrome/installer/setup/install_worker.cc
+++ b/chrome/installer/setup/install_worker.cc
@@ -21,6 +21,7 @@
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
+#include "base/enterprise_util.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
@@ -554,14 +555,8 @@
   if (new_brand.empty())
     return;
 
-  // Only update if this machine is:
-  // - domain joined, or
-  // - registered with MDM and is not windows home edition
-  bool is_enterprise_version =
-      base::win::OSInfo::GetInstance()->version_type() != base::win::SUITE_HOME;
-  if (!(base::win::IsEnrolledToDomain() ||
-        (base::win::IsDeviceRegisteredWithManagement() &&
-         is_enterprise_version))) {
+  // Only update if this machine is a managed device, including domain join.
+  if (!base::IsManagedDevice()) {
     return;
   }
 
diff --git a/chrome/services/file_util/OWNERS b/chrome/services/file_util/OWNERS
index 4fd3847..64d14ed 100644
--- a/chrome/services/file_util/OWNERS
+++ b/chrome/services/file_util/OWNERS
@@ -1,3 +1,7 @@
 # For the ZipFileCreator service
 fdegros@chromium.org
 noel@chromium.org
+
+# For the archive and document analyzers
+drubery@chromium.org
+xinghuilu@chromium.org
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6ebaf84..55c1e4f 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -71,7 +71,6 @@
   android_library("test_support_java") {
     testonly = true
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//chrome/android:chrome_all_java",
       "//components/autofill/android:autofill_java",
@@ -2579,6 +2578,7 @@
         "../browser/lacros/app_mode/kiosk_session_service_browsertest.cc",
         "../browser/lacros/lacros_extension_apps_controller_browsertest.cc",
         "../browser/lacros/lacros_extension_apps_publisher_browsertest.cc",
+        "../browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_lacros_browsertest.cc",
         "../browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc",
       ]
       deps += [
@@ -2630,8 +2630,10 @@
     }
 
     if (is_chromeos_ash) {
-      sources +=
-          [ "../browser/lifetime/application_lifetime_chromeos_browsertest.cc" ]
+      sources += [
+        "../browser/lifetime/application_lifetime_chromeos_browsertest.cc",
+        "../browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_ash_browsertest.cc",
+      ]
     }
 
     if (!is_chromeos) {
@@ -3815,7 +3817,6 @@
         "../browser/ui/browser_navigator_browsertest_chromeos.cc",
         "../browser/ui/extensions/application_launch_browsertest.cc",
         "../browser/ui/settings_window_manager_browsertest_chromeos.cc",
-        "../browser/ui/sharing_hub/sharing_hub_bubble_controller_chromeos_browsertest.cc",
         "../browser/ui/views/apps/app_dialog/app_dialog_view_browsertest.cc",
         "../browser/ui/views/apps/app_dialog/app_uninstall_dialog_view_browsertest.cc",
         "../browser/ui/views/apps/chrome_native_app_window_views_aura_ash_browsertest.cc",
@@ -6152,7 +6153,6 @@
     ]
 
     deps += [
-      "//base:base_java",
       "//build/android:build_java",
       "//chrome:chrome_android_core",
       "//chrome/android:chrome_apk_paks",
@@ -8402,6 +8402,8 @@
       "../browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc",
       "../browser/supervised_user/child_accounts/permission_request_creator_apiary_unittest.cc",
       "../browser/supervised_user/kids_management_url_checker_client_unittest.cc",
+      "../browser/supervised_user/parental_control_metrics_unittest.cc",
+      "../browser/supervised_user/supervised_user_metrics_service_unittest.cc",
       "../browser/supervised_user/supervised_user_model_type_controller_unittest.cc",
       "../browser/supervised_user/supervised_user_pref_store_unittest.cc",
       "../browser/supervised_user/supervised_user_settings_service_unittest.cc",
@@ -8456,7 +8458,7 @@
   # //chrome include.
   # TODO(crbug.com/1215474): Eliminate //chrome being visible in the GN structure
   # on Chromecast and remove this section entirely.
-  if ((is_linux || is_fuchsia) && is_chromecast) {
+  if ((is_linux || is_fuchsia) && is_castos) {
     sources -= [
       "../browser/browsing_data/browsing_data_media_license_helper_unittest.cc",
       "../browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc",
@@ -9479,7 +9481,6 @@
   android_library("sync_integration_test_support_java") {
     testonly = true
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
       "//chrome/android:chrome_all_java",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
index 1604c11..fdd8582 100644
--- a/chrome/test/android/BUILD.gn
+++ b/chrome/test/android/BUILD.gn
@@ -99,7 +99,6 @@
   data_deps = [ "//ui/base:goldctl" ]
   deps = [
     ":chrome_java_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/android:chrome_java",
@@ -136,7 +135,6 @@
   data_deps = [ "//ui/base:goldctl" ]
   deps = [
     ":chrome_java_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//chrome/android:chrome_java",
@@ -230,7 +228,6 @@
   ]
   deps = [
     ":chrome_java_test_pagecontroller",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//build/android:build_java",
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index e3bff60..725cd5c 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -275,7 +275,7 @@
   return nullptr;
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
 views::Button* TestBrowserWindow::GetSharingHubIconButton() {
   return nullptr;
 }
@@ -284,7 +284,7 @@
     content::WebContents* contents) {
   return nullptr;
 }
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
 
 bool TestBrowserWindow::IsDownloadShelfVisible() const {
   return false;
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index fc63706..2c6d45c5 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -161,12 +161,12 @@
 #endif  //  !define(OS_ANDROID)
   send_tab_to_self::SendTabToSelfBubbleView* ShowSendTabToSelfBubble(
       content::WebContents* contents) override;
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   views::Button* GetSharingHubIconButton() override;
 #else
   sharing_hub::SharingHubBubbleView* ShowSharingHubBubble(
       content::WebContents* contents) override;
-#endif
+#endif  // BUILDFLAG(IS_CHROMEOS)
   ShowTranslateBubbleResult ShowTranslateBubble(
       content::WebContents* contents,
       translate::TranslateStep step,
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js
index 347cbb18..053aa83 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js
@@ -5,11 +5,20 @@
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
 import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js';
 import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js';
+import {ShimlessRma} from 'chrome://shimless-rma/shimless_rma.js';
 import {WrapupWaitForManualWpEnablePage} from 'chrome://shimless-rma/wrapup_wait_for_manual_wp_enable_page.js';
+
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
 import {flushTasks} from '../../test_util.js';
 
 export function wrapupWaitForManualWpEnablePageTest() {
+  /**
+   * ShimlessRma is needed to handle the 'transition-state' used to signal write
+   * write protect is enabled.
+   * @type {?ShimlessRma}
+   */
+  let shimless_rma_component = null;
+
   /** @type {?WrapupWaitForManualWpEnablePage} */
   let component = null;
 
@@ -26,6 +35,8 @@
   });
 
   teardown(() => {
+    shimless_rma_component.remove();
+    shimless_rma_component = null;
     component.remove();
     component = null;
     service.reset();
@@ -37,6 +48,11 @@
   function initializeWaitForManualWpEnablePage() {
     assertFalse(!!component);
 
+    shimless_rma_component =
+        /** @type {!ShimlessRma} */ (document.createElement('shimless-rma'));
+    assertTrue(!!shimless_rma_component);
+    document.body.appendChild(shimless_rma_component);
+
     component = /** @type {!WrapupWaitForManualWpEnablePage} */ (
         document.createElement('wrapup-wait-for-manual-wp-enable-page'));
     assertTrue(!!component);
@@ -52,38 +68,18 @@
     assertFalse(manualEnableComponent.hidden);
   });
 
-  test('HwwpDisabledDisablesNext', async () => {
-    await initializeWaitForManualWpEnablePage();
-
-    let savedResult;
-    let savedError;
-    component.onNextButtonClick()
-        .then((result) => savedResult = result)
-        .catch((error) => savedError = error);
-    await flushTasks();
-
-    assertTrue(savedError instanceof Error);
-    assertEquals(
-        savedError.message, 'Hardware Write Protection is not enabled.');
-    assertEquals(savedResult, undefined);
-  });
-
-  test('HwwpEnabledEnablesNext', async () => {
+  test('WriteProtectEnabledAutoTransitions', async () => {
     const resolver = new PromiseResolver();
     await initializeWaitForManualWpEnablePage();
-    service.triggerHardwareWriteProtectionObserver(true, 0);
-    await flushTasks();
+
+    let callCount = 0;
     service.writeProtectManuallyEnabled = () => {
+      callCount++;
       return resolver.promise;
     };
-
-    const expectedResult = {foo: 'bar'};
-    let savedResult;
-    component.onNextButtonClick().then((result) => savedResult = result);
-    // Resolve to a distinct result to confirm it was not modified.
-    resolver.resolve(expectedResult);
+    service.triggerHardwareWriteProtectionObserver(true, 0);
     await flushTasks();
 
-    assertDeepEquals(savedResult, expectedResult);
+    assertEquals(1, callCount);
   });
 }
diff --git a/chrome/test/data/webui/settings/chromeos/device_page_tests.js b/chrome/test/data/webui/settings/chromeos/device_page_tests.js
index e3ff7df..5805516 100644
--- a/chrome/test/data/webui/settings/chromeos/device_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/device_page_tests.js
@@ -470,7 +470,7 @@
 
     devicePage = document.createElement('settings-device-page');
     devicePage.prefs = getFakePrefs();
-    DevicePageBrowserProxyImpl.instance_ = new TestDevicePageBrowserProxy();
+    DevicePageBrowserProxyImpl.setInstance(new TestDevicePageBrowserProxy());
 
     // settings-animated-pages expects a parent with data-page set.
     const basicPage = document.createElement('div');
@@ -484,10 +484,11 @@
 
   /** @return {!Promise<!HTMLElement>} */
   function showAndGetDeviceSubpage(subpage, expectedRoute) {
-    const row = assert(devicePage.$$(`#main #${subpage}Row`));
+    const row =
+        assert(devicePage.shadowRoot.querySelector(`#main #${subpage}Row`));
     row.click();
     assertEquals(expectedRoute, Router.getInstance().getCurrentRoute());
-    const page = devicePage.$$('settings-' + subpage);
+    const page = devicePage.shadowRoot.querySelector('settings-' + subpage);
     assert(page);
     return Promise.resolve(page);
   }
@@ -620,7 +621,7 @@
    */
   function expectReverseScrollValue(pointersPage, expected) {
     const reverseScrollToggle =
-        pointersPage.$$('#enableReverseScrollingToggle');
+        pointersPage.shadowRoot.querySelector('#enableReverseScrollingToggle');
     assertEquals(expected, reverseScrollToggle.checked);
     assertEquals(
         expected, devicePage.prefs.settings.touchpad.natural_scroll.value);
@@ -658,18 +659,25 @@
   }
 
   test(assert(TestNames.DevicePage), function() {
-    assertTrue(isVisible(devicePage.$$('#pointersRow')));
-    assertTrue(isVisible(devicePage.$$('#keyboardRow')));
-    assertTrue(isVisible(devicePage.$$('#displayRow')));
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#pointersRow')));
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#keyboardRow')));
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#displayRow')));
 
     webUIListenerCallback('has-mouse-changed', false);
-    assertTrue(isVisible(devicePage.$$('#pointersRow')));
+    flush();
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#pointersRow')));
+
     webUIListenerCallback('has-pointing-stick-changed', false);
-    assertTrue(isVisible(devicePage.$$('#pointersRow')));
+    flush();
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#pointersRow')));
+
     webUIListenerCallback('has-touchpad-changed', false);
-    assertFalse(isVisible(devicePage.$$('#pointersRow')));
+    flush();
+    assertFalse(isVisible(devicePage.shadowRoot.querySelector('#pointersRow')));
+
     webUIListenerCallback('has-mouse-changed', true);
-    assertTrue(isVisible(devicePage.$$('#pointersRow')));
+    flush();
+    assertTrue(isVisible(devicePage.shadowRoot.querySelector('#pointersRow')));
   });
 
   suite(assert(TestNames.Pointers), function() {
@@ -684,63 +692,90 @@
 
     test('subpage responds to pointer attach/detach', function() {
       assertEquals(routes.POINTERS, Router.getInstance().getCurrentRoute());
-      assertTrue(isVisible(pointersPage.$$('#mouse')));
-      assertTrue(isVisible(pointersPage.$$('#mouse h2')));
-      assertTrue(isVisible(pointersPage.$$('#pointingStick')));
-      assertTrue(isVisible(pointersPage.$$('#pointingStick h2')));
-      assertTrue(isVisible(pointersPage.$$('#touchpad')));
-      assertTrue(isVisible(pointersPage.$$('#touchpad h2')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse h2')));
+      assertTrue(
+          isVisible(pointersPage.shadowRoot.querySelector('#pointingStick')));
+      assertTrue(isVisible(
+          pointersPage.shadowRoot.querySelector('#pointingStick h2')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
+      assertTrue(
+          isVisible(pointersPage.shadowRoot.querySelector('#touchpad h2')));
 
       webUIListenerCallback('has-touchpad-changed', false);
       assertEquals(routes.POINTERS, Router.getInstance().getCurrentRoute());
-      assertTrue(isVisible(pointersPage.$$('#mouse')));
-      assertTrue(isVisible(pointersPage.$$('#mouse h2')));
-      assertTrue(isVisible(pointersPage.$$('#pointingStick')));
-      assertTrue(isVisible(pointersPage.$$('#pointingStick h2')));
-      assertFalse(isVisible(pointersPage.$$('#touchpad')));
-      assertFalse(isVisible(pointersPage.$$('#touchpad h2')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse h2')));
+      assertTrue(
+          isVisible(pointersPage.shadowRoot.querySelector('#pointingStick')));
+      assertTrue(isVisible(
+          pointersPage.shadowRoot.querySelector('#pointingStick h2')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#touchpad h2')));
 
       webUIListenerCallback('has-pointing-stick-changed', false);
       assertEquals(routes.POINTERS, Router.getInstance().getCurrentRoute());
-      assertTrue(isVisible(pointersPage.$$('#mouse')));
-      assertFalse(isVisible(pointersPage.$$('#mouse h2')));
-      assertFalse(isVisible(pointersPage.$$('#pointingStick')));
-      assertFalse(isVisible(pointersPage.$$('#pointingStick h2')));
-      assertFalse(isVisible(pointersPage.$$('#touchpad')));
-      assertFalse(isVisible(pointersPage.$$('#touchpad h2')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#mouse h2')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#pointingStick')));
+      assertFalse(isVisible(
+          pointersPage.shadowRoot.querySelector('#pointingStick h2')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
+      assertFalse(
+          isVisible(pointersPage.shadowRoot.querySelector('#touchpad h2')));
 
       webUIListenerCallback('has-mouse-changed', false);
       assertEquals(routes.DEVICE, Router.getInstance().getCurrentRoute());
-      assertFalse(isVisible(devicePage.$$('#main #pointersRow')));
+      assertFalse(
+          isVisible(devicePage.shadowRoot.querySelector('#main #pointersRow')));
 
       webUIListenerCallback('has-touchpad-changed', true);
-      assertTrue(isVisible(devicePage.$$('#main #pointersRow')));
+      assertTrue(
+          isVisible(devicePage.shadowRoot.querySelector('#main #pointersRow')));
 
       return showAndGetDeviceSubpage('pointers', routes.POINTERS)
           .then(function(page) {
-            assertFalse(isVisible(pointersPage.$$('#mouse')));
-            assertFalse(isVisible(pointersPage.$$('#mouse h2')));
-            assertFalse(isVisible(pointersPage.$$('#pointingStick')));
-            assertFalse(isVisible(pointersPage.$$('#pointingStick h2')));
-            assertTrue(isVisible(pointersPage.$$('#touchpad')));
-            assertFalse(isVisible(pointersPage.$$('#touchpad h2')));
+            assertFalse(
+                isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
+            assertFalse(
+                isVisible(pointersPage.shadowRoot.querySelector('#mouse h2')));
+            assertFalse(isVisible(
+                pointersPage.shadowRoot.querySelector('#pointingStick')));
+            assertFalse(isVisible(
+                pointersPage.shadowRoot.querySelector('#pointingStick h2')));
+            assertTrue(
+                isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
+            assertFalse(isVisible(
+                pointersPage.shadowRoot.querySelector('#touchpad h2')));
 
             webUIListenerCallback('has-mouse-changed', true);
             assertEquals(
                 routes.POINTERS, Router.getInstance().getCurrentRoute());
-            assertTrue(isVisible(pointersPage.$$('#mouse')));
-            assertTrue(isVisible(pointersPage.$$('#mouse h2')));
-            assertFalse(isVisible(pointersPage.$$('#pointingStick')));
-            assertFalse(isVisible(pointersPage.$$('#pointingStick h2')));
-            assertTrue(isVisible(pointersPage.$$('#touchpad')));
-            assertTrue(isVisible(pointersPage.$$('#touchpad h2')));
+            assertTrue(
+                isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
+            assertTrue(
+                isVisible(pointersPage.shadowRoot.querySelector('#mouse h2')));
+            assertFalse(isVisible(
+                pointersPage.shadowRoot.querySelector('#pointingStick')));
+            assertFalse(isVisible(
+                pointersPage.shadowRoot.querySelector('#pointingStick h2')));
+            assertTrue(
+                isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
+            assertTrue(isVisible(
+                pointersPage.shadowRoot.querySelector('#touchpad h2')));
           });
     });
 
     test('mouse', function() {
-      assertTrue(isVisible(pointersPage.$$('#mouse')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#mouse')));
 
-      const slider = assert(pointersPage.$$('#mouse settings-slider'));
+      const slider = assert(
+          pointersPage.shadowRoot.querySelector('#mouse settings-slider'));
       assertEquals(4, slider.pref.value);
       MockInteractions.pressAndReleaseKeyOn(
           slider.shadowRoot.querySelector('cr-slider'), 37, [], 'ArrowLeft');
@@ -751,12 +786,17 @@
     });
 
     test('touchpad', function() {
-      assertTrue(isVisible(pointersPage.$$('#touchpad')));
+      assertTrue(isVisible(pointersPage.shadowRoot.querySelector('#touchpad')));
 
-      assertTrue(pointersPage.$$('#touchpad #enableTapToClick').checked);
-      assertFalse(pointersPage.$$('#touchpad #enableTapDragging').checked);
+      assertTrue(
+          pointersPage.shadowRoot.querySelector('#touchpad #enableTapToClick')
+              .checked);
+      assertFalse(
+          pointersPage.shadowRoot.querySelector('#touchpad #enableTapDragging')
+              .checked);
 
-      const slider = assert(pointersPage.$$('#touchpad settings-slider'));
+      const slider = assert(
+          pointersPage.shadowRoot.querySelector('#touchpad settings-slider'));
       assertEquals(3, slider.pref.value);
       MockInteractions.pressAndReleaseKeyOn(
           slider.shadowRoot.querySelector('cr-slider'), 39 /* right */, [],
@@ -768,9 +808,12 @@
     });
 
     test('haptic touchpad', function() {
-      assertTrue(pointersPage.$$('#touchpadHapticFeedbackToggle').checked);
+      assertTrue(
+          pointersPage.shadowRoot.querySelector('#touchpadHapticFeedbackToggle')
+              .checked);
 
-      const slider = assert(pointersPage.$$('#touchpadHapticClickSensitivity'));
+      const slider = assert(pointersPage.shadowRoot.querySelector(
+          '#touchpadHapticClickSensitivity'));
       assertEquals(3, slider.pref.value);
       MockInteractions.pressAndReleaseKeyOn(
           slider.shadowRoot.querySelector('cr-slider'), 39 /* right */, [],
@@ -788,7 +831,7 @@
 
       // Tapping the link shouldn't enable the radio button.
       const reverseScrollLabel =
-          pointersPage.$$('#enableReverseScrollingLabel');
+          pointersPage.shadowRoot.querySelector('#enableReverseScrollingLabel');
       const a = reverseScrollLabel.$.container.querySelector('a');
       assertTrue(!!a);
       // Prevent actually opening a link, which would block test.
@@ -797,15 +840,16 @@
       expectReverseScrollValue(pointersPage, false);
 
       // Check specifically clicking toggle changes pref.
-      const reverseScrollToggle =
-          pointersPage.$$('#enableReverseScrollingToggle');
+      const reverseScrollToggle = pointersPage.shadowRoot.querySelector(
+          '#enableReverseScrollingToggle');
       reverseScrollToggle.click();
       expectReverseScrollValue(pointersPage, true);
       devicePage.set('prefs.settings.touchpad.natural_scroll.value', false);
       expectReverseScrollValue(pointersPage, false);
 
       // Check specifically clicking the row changes pref.
-      const reverseScrollSettings = pointersPage.$$('#reverseScrollRow');
+      const reverseScrollSettings =
+          pointersPage.shadowRoot.querySelector('#reverseScrollRow');
       reverseScrollSettings.click();
       expectReverseScrollValue(pointersPage, true);
       devicePage.set('prefs.settings.touchpad.natural_scroll.value', false);
@@ -813,7 +857,8 @@
     });
 
     test('pointing stick acceleration toggle', function() {
-      const toggle = assert(pointersPage.$$('#pointingStickAcceleration'));
+      const toggle = assert(
+          pointersPage.shadowRoot.querySelector('#pointingStickAcceleration'));
       assertEquals(true, toggle.pref.value);
       toggle.click();
       assertEquals(
@@ -825,7 +870,8 @@
     });
 
     test('pointing stick speed slider', function() {
-      const slider = assert(pointersPage.$$('#pointingStick settings-slider'));
+      const slider = assert(pointersPage.shadowRoot.querySelector(
+          '#pointingStick settings-slider'));
       assertEquals(4, slider.pref.value);
       MockInteractions.pressAndReleaseKeyOn(
           slider.shadowRoot.querySelector('cr-slider'), 37, [], 'ArrowLeft');
@@ -839,7 +885,8 @@
     test('Deep link to pointing stick primary button setting', async () => {
       return checkDeepLink(
           routes.POINTERS, '437',
-          pointersPage.$$('#pointingStickSwapButtonDropdown')
+          pointersPage.shadowRoot
+              .querySelector('#pointingStickSwapButtonDropdown')
               .shadowRoot.querySelector('select'),
           'Pointing stick primary button dropdown');
     });
@@ -847,7 +894,7 @@
     test('Deep link to pointing stick acceleration setting', async () => {
       return checkDeepLink(
           routes.POINTERS, '436',
-          pointersPage.$$('#pointingStickAcceleration')
+          pointersPage.shadowRoot.querySelector('#pointingStickAcceleration')
               .shadowRoot.querySelector('cr-toggle'),
           'Pointing stick acceleration slider');
     });
@@ -855,7 +902,7 @@
     test('Deep link to pointing stick speed setting', async () => {
       return checkDeepLink(
           routes.POINTERS, '435',
-          pointersPage.$$('#pointingStickSpeedSlider')
+          pointersPage.shadowRoot.querySelector('#pointingStickSpeedSlider')
               .shadowRoot.querySelector('cr-slider'),
           'Pointing stick speed slider');
     });
@@ -863,7 +910,7 @@
     test('Deep link to touchpad speed', async () => {
       return checkDeepLink(
           routes.POINTERS, '405',
-          pointersPage.$$('#touchpadSensitivity')
+          pointersPage.shadowRoot.querySelector('#touchpadSensitivity')
               .shadowRoot.querySelector('cr-slider'),
           'Touchpad speed slider');
     });
@@ -881,7 +928,7 @@
 
     test('keyboard', async () => {
       // Initially, the optional keys are hidden.
-      assertFalse(!!keyboardPage.$$('#capsLockKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
 
       // Pretend no internal keyboard is available.
       const keyboardParams = {
@@ -893,75 +940,87 @@
       };
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertFalse(!!keyboardPage.$$('#launcherKey'));
-      assertFalse(!!keyboardPage.$$('#capsLockKey'));
-      assertFalse(!!keyboardPage.$$('#externalMetaKey'));
-      assertFalse(!!keyboardPage.$$('#externalCommandKey'));
-      assertFalse(!!keyboardPage.$$('#assistantKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertFalse(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
       // Pretend a Caps Lock key is now available.
       keyboardParams['showCapsLock'] = true;
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertFalse(!!keyboardPage.$$('#launcherKey'));
-      assertTrue(!!keyboardPage.$$('#capsLockKey'));
-      assertFalse(!!keyboardPage.$$('#externalMetaKey'));
-      assertFalse(!!keyboardPage.$$('#externalCommandKey'));
-      assertFalse(!!keyboardPage.$$('#assistantKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertFalse(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
       // Add a non-Apple external keyboard.
       keyboardParams['showExternalMetaKey'] = true;
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertFalse(!!keyboardPage.$$('#launcherKey'));
-      assertTrue(!!keyboardPage.$$('#capsLockKey'));
-      assertTrue(!!keyboardPage.$$('#externalMetaKey'));
-      assertFalse(!!keyboardPage.$$('#externalCommandKey'));
-      assertFalse(!!keyboardPage.$$('#assistantKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertFalse(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
       // Add an Apple keyboard.
       keyboardParams['showAppleCommandKey'] = true;
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertFalse(!!keyboardPage.$$('#launcherKey'));
-      assertTrue(!!keyboardPage.$$('#capsLockKey'));
-      assertTrue(!!keyboardPage.$$('#externalMetaKey'));
-      assertTrue(!!keyboardPage.$$('#externalCommandKey'));
-      assertFalse(!!keyboardPage.$$('#assistantKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertTrue(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
       // Add an internal keyboard.
       keyboardParams['hasLauncherKey'] = true;
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertTrue(!!keyboardPage.$$('#launcherKey'));
-      assertTrue(!!keyboardPage.$$('#capsLockKey'));
-      assertTrue(!!keyboardPage.$$('#externalMetaKey'));
-      assertTrue(!!keyboardPage.$$('#externalCommandKey'));
-      assertFalse(!!keyboardPage.$$('#assistantKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertTrue(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertFalse(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
       // Pretend an Assistant key is now available.
       keyboardParams['hasAssistantKey'] = true;
       webUIListenerCallback('show-keys-changed', keyboardParams);
       flush();
-      assertTrue(!!keyboardPage.$$('#launcherKey'));
-      assertTrue(!!keyboardPage.$$('#capsLockKey'));
-      assertTrue(!!keyboardPage.$$('#externalMetaKey'));
-      assertTrue(!!keyboardPage.$$('#externalCommandKey'));
-      assertTrue(!!keyboardPage.$$('#assistantKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#launcherKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#capsLockKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#externalMetaKey'));
+      assertTrue(
+          !!keyboardPage.shadowRoot.querySelector('#externalCommandKey'));
+      assertTrue(!!keyboardPage.shadowRoot.querySelector('#assistantKey'));
 
-      const collapse = keyboardPage.$$('iron-collapse');
+      const collapse = keyboardPage.shadowRoot.querySelector('iron-collapse');
       assertTrue(!!collapse);
       assertTrue(collapse.opened);
 
-      assertEquals(500, keyboardPage.$$('#delaySlider').pref.value);
-      assertEquals(500, keyboardPage.$$('#repeatRateSlider').pref.value);
+      assertEquals(
+          500,
+          keyboardPage.shadowRoot.querySelector('#delaySlider').pref.value);
+      assertEquals(
+          500,
+          keyboardPage.shadowRoot.querySelector('#repeatRateSlider')
+              .pref.value);
 
       // Test interaction with the settings-slider's underlying cr-slider.
       MockInteractions.pressAndReleaseKeyOn(
-          keyboardPage.$$('#delaySlider').shadowRoot.querySelector('cr-slider'),
+          keyboardPage.shadowRoot.querySelector('#delaySlider')
+              .shadowRoot.querySelector('cr-slider'),
           37 /* left */, [], 'ArrowLeft');
       MockInteractions.pressAndReleaseKeyOn(
-          keyboardPage.$$('#repeatRateSlider')
+          keyboardPage.shadowRoot.querySelector('#repeatRateSlider')
               .shadowRoot.querySelector('cr-slider'),
           39, [], 'ArrowRight');
       await flushTasks();
@@ -971,24 +1030,34 @@
       // Test sliders change when prefs change.
       set('xkb_auto_repeat_delay_r2', 1500);
       await flushTasks();
-      assertEquals(1500, keyboardPage.$$('#delaySlider').pref.value);
+      assertEquals(
+          1500,
+          keyboardPage.shadowRoot.querySelector('#delaySlider').pref.value);
       set('xkb_auto_repeat_interval_r2', 2000);
       await flushTasks();
-      assertEquals(2000, keyboardPage.$$('#repeatRateSlider').pref.value);
+      assertEquals(
+          2000,
+          keyboardPage.shadowRoot.querySelector('#repeatRateSlider')
+              .pref.value);
 
       // Test sliders round to nearest value when prefs change.
       set('xkb_auto_repeat_delay_r2', 600);
       await flushTasks();
-      assertEquals(500, keyboardPage.$$('#delaySlider').pref.value);
+      assertEquals(
+          500,
+          keyboardPage.shadowRoot.querySelector('#delaySlider').pref.value);
       set('xkb_auto_repeat_interval_r2', 45);
       await flushTasks();
-      assertEquals(50, keyboardPage.$$('#repeatRateSlider').pref.value);
+      assertEquals(
+          50,
+          keyboardPage.shadowRoot.querySelector('#repeatRateSlider')
+              .pref.value);
 
       set('xkb_auto_repeat_enabled_r2', false);
       assertFalse(collapse.opened);
 
       // Test keyboard shortcut viewer button.
-      keyboardPage.$$('#keyboardShortcutViewer').click();
+      keyboardPage.shadowRoot.querySelector('#keyboardShortcutViewer').click();
       assertEquals(
           1,
           DevicePageBrowserProxyImpl.getInstance()
@@ -998,7 +1067,7 @@
     test('Deep link to keyboard shortcuts', async () => {
       return checkDeepLink(
           routes.KEYBOARD, '413',
-          keyboardPage.$$('#keyboardShortcutViewer')
+          keyboardPage.shadowRoot.querySelector('#keyboardShortcutViewer')
               .shadowRoot.querySelector('cr-icon-button'),
           'Keyboard shortcuts button');
     });
@@ -1065,7 +1134,9 @@
                 false, displayPage.displays[0]));
 
             // Verify that the arrangement section is not shown.
-            assertEquals(null, displayPage.$$('#arrangement-section'));
+            assertEquals(
+                null,
+                displayPage.shadowRoot.querySelector('#arrangement-section'));
 
             // Add a second display.
             addDisplay(2);
@@ -1130,13 +1201,16 @@
                 false, displayPage.displays[1]));
 
             // Verify that the arrangement section is shown.
-            assertTrue(!!displayPage.$$('#arrangement-section'));
+            assertTrue(
+                !!displayPage.shadowRoot.querySelector('#arrangement-section'));
 
             // Select the second display and make it primary. Also change the
             // orientation of the second display.
-            const displayLayout = displayPage.$$('#displayLayout');
+            const displayLayout =
+                displayPage.shadowRoot.querySelector('#displayLayout');
             assertTrue(!!displayLayout);
-            const displayDiv = displayLayout.$$('#_fakeDisplayId2');
+            const displayDiv =
+                displayLayout.shadowRoot.querySelector('#_fakeDisplayId2');
             assertTrue(!!displayDiv);
             displayDiv.click();
             assertEquals(
@@ -1188,7 +1262,8 @@
             assertTrue(displayPage.isMirrored_(displayPage.displays));
 
             // Verify that the arrangement section is shown while mirroring.
-            assertTrue(!!displayPage.$$('#arrangement-section'));
+            assertTrue(
+                !!displayPage.shadowRoot.querySelector('#arrangement-section'));
 
             // Ensure that the zoom value remains unchanged while draggging.
             function pointerEvent(eventType, ratio) {
@@ -1244,7 +1319,8 @@
       assertTrue(displayPage.shouldShowArrangementSection_());
 
       const deepLinkElement =
-          displayPage.$$('#displayMirrorCheckbox').$$('#checkbox');
+          displayPage.shadowRoot.querySelector('#displayMirrorCheckbox')
+              .$$('#checkbox');
       await waitAfterNextRender(deepLinkElement);
       assertEquals(
           deepLinkElement, getDeepActiveElement(),
@@ -1269,7 +1345,8 @@
               assertEquals(2, displayPage.displays.length);
               assertTrue(displayPage.shouldShowArrangementSection_());
 
-              assertTrue(!!displayPage.$$('#arrangement-section'));
+              assertTrue(!!displayPage.shadowRoot.querySelector(
+                  '#arrangement-section'));
 
               assertTrue(displayPage.showMirror_(false, displayPage.displays));
               assertFalse(displayPage.isMirrored_(displayPage.displays));
@@ -1280,8 +1357,10 @@
             });
           })
           .then(() => {
-            const displayLayout = displayPage.$$('#displayLayout');
-            const display = displayLayout.$$('#_fakeDisplayId2');
+            const displayLayout =
+                displayPage.shadowRoot.querySelector('#displayLayout');
+            const display =
+                displayLayout.shadowRoot.querySelector('#_fakeDisplayId2');
             const layout =
                 displayLayout.displayLayoutMap_.get('fakeDisplayId2');
 
@@ -1325,8 +1404,10 @@
     await fakeSystemDisplay.getLayoutCalled.promise;
     assertEquals(1, displayPage.displays.length);
 
-    const temperature = displayPage.$$('#nightLightTemperatureDiv');
-    const schedule = displayPage.$$('#nightLightScheduleTypeDropDown');
+    const temperature =
+        displayPage.shadowRoot.querySelector('#nightLightTemperatureDiv');
+    const schedule =
+        displayPage.shadowRoot.querySelector('#nightLightScheduleTypeDropDown');
 
     // Night Light is off, so temperature is hidden. Schedule is always shown.
     assertTrue(temperature.hidden);
@@ -1379,16 +1460,20 @@
         return showAndGetDeviceSubpage('power', routes.POWER)
             .then(function(page) {
               powerPage = page;
-              powerSourceRow = assert(powerPage.$$('#powerSourceRow'));
-              powerSourceSelect = assert(powerPage.$$('#powerSource'));
+              powerSourceRow =
+                  assert(powerPage.shadowRoot.querySelector('#powerSourceRow'));
+              powerSourceSelect =
+                  assert(powerPage.shadowRoot.querySelector('#powerSource'));
               assertEquals(
                   1,
                   DevicePageBrowserProxyImpl.getInstance()
                       .updatePowerStatusCalled_);
 
-              lidClosedToggle = assert(powerPage.$$('#lidClosedToggle'));
+              lidClosedToggle = assert(
+                  powerPage.shadowRoot.querySelector('#lidClosedToggle'));
               adaptiveChargingToggle =
-                  assert(powerPage.$$('#adaptiveChargingToggle'));
+                  assert(powerPage.shadowRoot.querySelector(
+                      '#adaptiveChargingToggle'));
 
               assertEquals(
                   1,
@@ -1427,10 +1512,13 @@
         assertTrue(powerSourceRow.hidden);
         // Idle settings while on battery and while charging should not be
         // visible if the battery is not present.
-        assertEquals(null, powerPage.$$('#batteryIdleSettingBox'));
-        assertEquals(null, powerPage.$$('#acIdleSettingBox'));
+        assertEquals(
+            null, powerPage.shadowRoot.querySelector('#batteryIdleSettingBox'));
+        assertEquals(
+            null, powerPage.shadowRoot.querySelector('#acIdleSettingBox'));
 
-        const acIdleSelect = assert(powerPage.$$('#noBatteryAcIdleSelect'));
+        const acIdleSelect = assert(
+            powerPage.shadowRoot.querySelector('#noBatteryAcIdleSelect'));
         // Expect the "When idle" dropdown options to appear instead.
         assert(acIdleSelect);
 
@@ -1526,7 +1614,8 @@
         setPowerSources([], '', false);
         flush();
 
-        acIdleSelect = assert(powerPage.$$('#acIdleSelect'));
+        acIdleSelect =
+            assert(powerPage.shadowRoot.querySelector('#acIdleSelect'));
         selectValue(acIdleSelect, IdleBehavior.DISPLAY_ON);
         assertEquals(
             IdleBehavior.DISPLAY_ON,
@@ -1550,8 +1639,8 @@
                  powerPage.async(resolve);
                })
             .then(function() {
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               selectValue(batteryIdleSelect, IdleBehavior.DISPLAY_ON);
               assertEquals(
                   IdleBehavior.DISPLAY_ON,
@@ -1638,12 +1727,13 @@
               });
             })
             .then(function() {
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), batteryIdleSelect.value);
               assertFalse(batteryIdleSelect.disabled);
-              const acIdleSelect = assert(powerPage.$$('#acIdleSelect'));
+              const acIdleSelect =
+                  assert(powerPage.shadowRoot.querySelector('#acIdleSelect'));
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), acIdleSelect.value);
               assertFalse(acIdleSelect.disabled);
@@ -1678,12 +1768,13 @@
               });
             })
             .then(function() {
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), batteryIdleSelect.value);
               assertFalse(batteryIdleSelect.disabled);
-              const acIdleSelect = assert(powerPage.$$('#acIdleSelect'));
+              const acIdleSelect =
+                  assert(powerPage.shadowRoot.querySelector('#acIdleSelect'));
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), acIdleSelect.value);
               assertFalse(acIdleSelect.disabled);
@@ -1732,15 +1823,19 @@
               });
             })
             .then(function() {
-              acIdleSelect = assert(powerPage.$$('#acIdleSelect'));
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              acIdleSelect =
+                  assert(powerPage.shadowRoot.querySelector('#acIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.DISPLAY_ON.toString(), acIdleSelect.value);
               assertEquals(
                   IdleBehavior.DISPLAY_OFF.toString(), batteryIdleSelect.value);
               assertFalse(acIdleSelect.disabled);
-              assertEquals(null, powerPage.$$('#acIdleManagedIndicator'));
+              assertEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#acIdleManagedIndicator'));
               assertEquals(
                   loadTimeData.getString('powerLidSleepLabel'),
                   lidClosedToggle.label);
@@ -1766,16 +1861,22 @@
               });
             })
             .then(function() {
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.DISPLAY_OFF.toString(), acIdleSelect.value);
               assertEquals(
                   IdleBehavior.DISPLAY_ON.toString(), batteryIdleSelect.value);
               assertFalse(acIdleSelect.disabled);
               assertFalse(batteryIdleSelect.disabled);
-              assertEquals(null, powerPage.$$('#acIdleManagedIndicator'));
-              assertEquals(null, powerPage.$$('#batteryIdleManagedIndicator'));
+              assertEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#acIdleManagedIndicator'));
+              assertEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#batteryIdleManagedIndicator'));
               assertEquals(
                   loadTimeData.getString('powerLidSleepLabel'),
                   lidClosedToggle.label);
@@ -1810,18 +1911,24 @@
                  powerPage.async(resolve);
                })
             .then(function() {
-              acIdleSelect = assert(powerPage.$$('#acIdleSelect'));
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              acIdleSelect =
+                  assert(powerPage.shadowRoot.querySelector('#acIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), acIdleSelect.value);
               assertEquals(
                   IdleBehavior.SHUT_DOWN.toString(), batteryIdleSelect.value);
               assertTrue(acIdleSelect.disabled);
               assertTrue(batteryIdleSelect.disabled);
-              expectNotEquals(null, powerPage.$$('#acIdleManagedIndicator'));
               expectNotEquals(
-                  null, powerPage.$$('#batteryIdleManagedIndicator'));
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#acIdleManagedIndicator'));
+              expectNotEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#batteryIdleManagedIndicator'));
               assertEquals(
                   loadTimeData.getString('powerLidShutDownLabel'),
                   lidClosedToggle.label);
@@ -1841,16 +1948,22 @@
               });
             })
             .then(function() {
-              const batteryIdleSelect =
-                  assert(powerPage.$$('#batteryIdleSelect'));
+              const batteryIdleSelect = assert(
+                  powerPage.shadowRoot.querySelector('#batteryIdleSelect'));
               assertEquals(
                   IdleBehavior.DISPLAY_OFF.toString(), acIdleSelect.value);
               assertEquals(
                   IdleBehavior.DISPLAY_OFF.toString(), batteryIdleSelect.value);
               assertTrue(acIdleSelect.disabled);
               assertTrue(batteryIdleSelect.disabled);
-              assertEquals(null, powerPage.$$('#acIdleManagedIndicator'));
-              assertEquals(null, powerPage.$$('#batteryIdleManagedIndicator'));
+              assertEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#acIdleManagedIndicator'));
+              assertEquals(
+                  null,
+                  powerPage.shadowRoot.querySelector(
+                      '#batteryIdleManagedIndicator'));
               assertEquals(
                   loadTimeData.getString('powerLidSignOutLabel'),
                   lidClosedToggle.label);
@@ -1861,7 +1974,9 @@
 
       test('hide lid behavior when lid not present', function() {
         return new Promise(function(resolve) {
-                 assertFalse(powerPage.$$('#lidClosedToggle').hidden);
+                 assertFalse(
+                     powerPage.shadowRoot.querySelector('#lidClosedToggle')
+                         .hidden);
                  sendPowerManagementSettings(
                      [
                        IdleBehavior.DISPLAY_OFF_SLEEP, IdleBehavior.DISPLAY_OFF,
@@ -1879,7 +1994,8 @@
                  powerPage.async(resolve);
                })
             .then(function() {
-              assertTrue(powerPage.$$('#lidClosedToggle').hidden);
+              assertTrue(powerPage.shadowRoot.querySelector('#lidClosedToggle')
+                             .hidden);
             });
       });
 
@@ -1901,7 +2017,10 @@
                      powerPage.async(resolve);
                    })
                 .then(function() {
-                  assertEquals(null, powerPage.$$('#batteryIdleSettingBox'));
+                  assertEquals(
+                      null,
+                      powerPage.shadowRoot.querySelector(
+                          '#batteryIdleSettingBox'));
                 });
           });
 
@@ -1943,9 +2062,9 @@
           .then(function(page) {
             stylusPage = page;
             browserProxy = DevicePageBrowserProxyImpl.getInstance();
-            appSelector = assert(page.$$('#selectApp'));
-            noAppsDiv = assert(page.$$('#no-apps'));
-            waitingDiv = assert(page.$$('#waiting'));
+            appSelector = assert(page.shadowRoot.querySelector('#selectApp'));
+            noAppsDiv = assert(page.shadowRoot.querySelector('#no-apps'));
+            waitingDiv = assert(page.shadowRoot.querySelector('#waiting'));
             LockScreenSupport = NoteAppLockScreenSupport;
 
             assertEquals(1, browserProxy.requestNoteTakingApps_);
@@ -1965,27 +2084,31 @@
 
     /**  @return {?Element} */
     function noteTakingAppLockScreenSettings() {
-      return stylusPage.$$('#note-taking-app-lock-screen-settings');
+      return stylusPage.shadowRoot.querySelector(
+          '#note-taking-app-lock-screen-settings');
     }
 
     /** @return {?Element} */
     function enableAppOnLockScreenToggle() {
-      return stylusPage.$$('#enable-app-on-lock-screen-toggle');
+      return stylusPage.shadowRoot.querySelector(
+          '#enable-app-on-lock-screen-toggle');
     }
 
     /** @return {?Element} */
     function enableAppOnLockScreenPolicyIndicator() {
-      return stylusPage.$$('#enable-app-on-lock-screen-policy-indicator');
+      return stylusPage.shadowRoot.querySelector(
+          '#enable-app-on-lock-screen-policy-indicator');
     }
 
     /** @return {?Element} */
     function enableAppOnLockScreenToggleLabel() {
-      return stylusPage.$$('#lock-screen-toggle-label');
+      return stylusPage.shadowRoot.querySelector('#lock-screen-toggle-label');
     }
 
     /** @return {?Element} */
     function keepLastNoteOnLockScreenToggle() {
-      return stylusPage.$$('#keep-last-note-on-lock-screen-toggle');
+      return stylusPage.shadowRoot.querySelector(
+          '#keep-last-note-on-lock-screen-toggle');
     }
 
     test('stylus tools prefs', function() {
@@ -1996,19 +2119,26 @@
 
       // Since both prefs are initially false, the launch palette on eject pref
       // toggle is disabled.
-      assertTrue(isVisible(stylusPage.$$('#enableStylusToolsToggle')));
-      assertTrue(isVisible(stylusPage.$$('#launchPaletteOnEjectEventToggle')));
-      assertTrue(stylusPage.$$('#launchPaletteOnEjectEventToggle').disabled);
+      assertTrue(isVisible(
+          stylusPage.shadowRoot.querySelector('#enableStylusToolsToggle')));
+      assertTrue(isVisible(stylusPage.shadowRoot.querySelector(
+          '#launchPaletteOnEjectEventToggle')));
+      assertTrue(stylusPage.shadowRoot
+                     .querySelector('#launchPaletteOnEjectEventToggle')
+                     .disabled);
       assertFalse(devicePage.prefs.settings.enable_stylus_tools.value);
       assertFalse(
           devicePage.prefs.settings.launch_palette_on_eject_event.value);
 
       // Tapping the enable stylus tools pref causes the launch palette on
       // eject pref toggle to not be disabled anymore.
-      stylusPage.$$('#enableStylusToolsToggle').click();
+      stylusPage.shadowRoot.querySelector('#enableStylusToolsToggle').click();
       assertTrue(devicePage.prefs.settings.enable_stylus_tools.value);
-      assertFalse(stylusPage.$$('#launchPaletteOnEjectEventToggle').disabled);
-      stylusPage.$$('#launchPaletteOnEjectEventToggle').click();
+      assertFalse(stylusPage.shadowRoot
+                      .querySelector('#launchPaletteOnEjectEventToggle')
+                      .disabled);
+      stylusPage.shadowRoot.querySelector('#launchPaletteOnEjectEventToggle')
+          .click();
       assertTrue(devicePage.prefs.settings.launch_palette_on_eject_event.value);
     });
 
@@ -2083,7 +2213,8 @@
       browserProxy.setAndroidAppsReceived(true);
 
       return checkDeepLink(
-          routes.STYLUS, '417', stylusPage.$$('#selectApp'),
+          routes.STYLUS, '417',
+          stylusPage.shadowRoot.querySelector('#selectApp'),
           'Note-taking apps dropdown');
     });
 
@@ -2488,7 +2619,7 @@
      * @return {string}
      */
     function getStorageItemLabelFromId(id) {
-      const rowItem = storagePage.$$('#' + id).shadowRoot;
+      const rowItem = storagePage.shadowRoot.querySelector('#' + id).shadowRoot;
       return rowItem.querySelector('#label').innerText;
     }
 
@@ -2497,7 +2628,7 @@
      * @return {string}
      */
     function getStorageItemSubLabelFromId(id) {
-      const rowItem = storagePage.$$('#' + id).shadowRoot;
+      const rowItem = storagePage.shadowRoot.querySelector('#' + id).shadowRoot;
       return rowItem.querySelector('#subLabel').innerText;
     }
 
@@ -2519,10 +2650,13 @@
       sendStorageSizeStat('9.1 GB', '0.9 GB', 0.91, StorageSpaceState.LOW);
       assertEquals('91%', storagePage.$.inUseLabelArea.style.width);
       assertEquals('9%', storagePage.$.availableLabelArea.style.width);
-      assertTrue(isVisible(storagePage.$$('#lowMessage')));
-      assertFalse(isVisible(storagePage.$$('#criticallyLowMessage')));
-      assertTrue(!!storagePage.$$('#bar.space-low'));
-      assertFalse(!!storagePage.$$('#bar.space-critically-low'));
+      assertTrue(
+          isVisible(storagePage.shadowRoot.querySelector('#lowMessage')));
+      assertFalse(isVisible(
+          storagePage.shadowRoot.querySelector('#criticallyLowMessage')));
+      assertTrue(!!storagePage.shadowRoot.querySelector('#bar.space-low'));
+      assertFalse(
+          !!storagePage.shadowRoot.querySelector('#bar.space-critically-low'));
       assertEquals(
           '9.1 GB',
           storagePage.$.inUseLabelArea.querySelector('.storage-size')
@@ -2537,10 +2671,13 @@
           '9.7 GB', '0.3 GB', 0.97, StorageSpaceState.CRITICALLY_LOW);
       assertEquals('97%', storagePage.$.inUseLabelArea.style.width);
       assertEquals('3%', storagePage.$.availableLabelArea.style.width);
-      assertFalse(isVisible(storagePage.$$('#lowMessage')));
-      assertTrue(isVisible(storagePage.$$('#criticallyLowMessage')));
-      assertFalse(!!storagePage.$$('#bar.space-low'));
-      assertTrue(!!storagePage.$$('#bar.space-critically-low'));
+      assertFalse(
+          isVisible(storagePage.shadowRoot.querySelector('#lowMessage')));
+      assertTrue(isVisible(
+          storagePage.shadowRoot.querySelector('#criticallyLowMessage')));
+      assertFalse(!!storagePage.shadowRoot.querySelector('#bar.space-low'));
+      assertTrue(
+          !!storagePage.shadowRoot.querySelector('#bar.space-critically-low'));
       assertEquals(
           '9.7 GB',
           storagePage.$.inUseLabelArea.querySelector('.storage-size')
@@ -2554,10 +2691,13 @@
       sendStorageSizeStat('2.5 GB', '7.5 GB', 0.25, StorageSpaceState.NORMAL);
       assertEquals('25%', storagePage.$.inUseLabelArea.style.width);
       assertEquals('75%', storagePage.$.availableLabelArea.style.width);
-      assertFalse(isVisible(storagePage.$$('#lowMessage')));
-      assertFalse(isVisible(storagePage.$$('#criticallyLowMessage')));
-      assertFalse(!!storagePage.$$('#bar.space-low'));
-      assertFalse(!!storagePage.$$('#bar.space-critically-low'));
+      assertFalse(
+          isVisible(storagePage.shadowRoot.querySelector('#lowMessage')));
+      assertFalse(isVisible(
+          storagePage.shadowRoot.querySelector('#criticallyLowMessage')));
+      assertFalse(!!storagePage.shadowRoot.querySelector('#bar.space-low'));
+      assertFalse(
+          !!storagePage.shadowRoot.querySelector('#bar.space-critically-low'));
       assertEquals(
           '2.5 GB',
           storagePage.$.inUseLabelArea.querySelector('.storage-size')
@@ -2569,19 +2709,27 @@
     });
 
     test('system size', async function() {
-      assertEquals('System', storagePage.$$('#systemSizeLabel').innerText);
       assertEquals(
-          'Calculating…', storagePage.$$('#systemSizeSubLabel').innerText);
+          'System',
+          storagePage.shadowRoot.querySelector('#systemSizeLabel').innerText);
+      assertEquals(
+          'Calculating…',
+          storagePage.shadowRoot.querySelector('#systemSizeSubLabel')
+              .innerText);
 
       // Send system size callback.
       webUIListenerCallback('storage-system-size-changed', '8.4 GB');
       flush();
-      assertEquals('8.4 GB', storagePage.$$('#systemSizeSubLabel').innerText);
+      assertEquals(
+          '8.4 GB',
+          storagePage.shadowRoot.querySelector('#systemSizeSubLabel')
+              .innerText);
 
       // In guest mode, the system row should be hidden.
       storagePage.isGuest_ = true;
       flush();
-      assertFalse(isVisible(storagePage.$$('#systemSize')));
+      assertFalse(
+          isVisible(storagePage.shadowRoot.querySelector('#systemSize')));
     });
 
     test('apps extensions size', async function() {
@@ -2598,7 +2746,8 @@
     test('other users size', async function() {
       // The other users row is visible by default, displaying
       // "calculating...".
-      assertTrue(isVisible(storagePage.$$('#otherUsersSize')));
+      assertTrue(
+          isVisible(storagePage.shadowRoot.querySelector('#otherUsersSize')));
       assertEquals('Other users', getStorageItemLabelFromId('otherUsersSize'));
       assertEquals(
           'Calculating…', getStorageItemSubLabelFromId('otherUsersSize'));
@@ -2606,13 +2755,15 @@
       // Simulate absence of other users.
       webUIListenerCallback('storage-other-users-size-changed', '0 B', true);
       flush();
-      assertFalse(isVisible(storagePage.$$('#otherUsersSize')));
+      assertFalse(
+          isVisible(storagePage.shadowRoot.querySelector('#otherUsersSize')));
 
       // Send other users callback with a size that is not null.
       webUIListenerCallback(
           'storage-other-users-size-changed', '322 MB', false);
       flush();
-      assertTrue(isVisible(storagePage.$$('#otherUsersSize')));
+      assertTrue(
+          isVisible(storagePage.shadowRoot.querySelector('#otherUsersSize')));
       assertEquals('322 MB', getStorageItemSubLabelFromId('otherUsersSize'));
 
       // If the user is in Guest mode, the row is not visible.
@@ -2620,7 +2771,8 @@
       webUIListenerCallback(
           'storage-other-users-size-changed', '322 MB', false);
       flush();
-      assertFalse(isVisible(storagePage.$$('#otherUsersSize')));
+      assertFalse(
+          isVisible(storagePage.shadowRoot.querySelector('#otherUsersSize')));
     });
   });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js b/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js
index 1010485..407b6550 100644
--- a/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js
+++ b/chrome/test/data/webui/settings/chromeos/manage_accessibility_page_tests.js
@@ -92,7 +92,7 @@
 
   setup(function() {
     deviceBrowserProxy = new TestDevicePageBrowserProxy();
-    DevicePageBrowserProxyImpl.instance_ = deviceBrowserProxy;
+    DevicePageBrowserProxyImpl.setInstance(deviceBrowserProxy);
 
     PolymerTest.clearBody();
   });
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 4d828bbd..c8f8b122 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -14,6 +14,7 @@
 GEN('#include "chrome/common/chrome_features.h"');
 GEN('#include "components/privacy_sandbox/privacy_sandbox_features.h"');
 GEN('#include "components/autofill/core/common/autofill_features.h"');
+GEN('#include "content/public/common/content_features.h"');
 GEN('#include "content/public/test/browser_test.h"');
 
 GEN('#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_CHROMEOS_LACROS)');
@@ -445,6 +446,13 @@
       ]
     };
   }
+
+  get featuresWithParameters() {
+    return [{
+      featureName: 'features::kFedCm',
+      parameters: [{name: 'DesktopSettings', value: true}]
+    }];
+  }
 };
 
 // TODO(crbug.com/1263420): Flaky on Linux Tests(dbg).
diff --git a/chrome/test/data/webui/settings/privacy_page_test.ts b/chrome/test/data/webui/settings/privacy_page_test.ts
index 4303f7d..4682891 100644
--- a/chrome/test/data/webui/settings/privacy_page_test.ts
+++ b/chrome/test/data/webui/settings/privacy_page_test.ts
@@ -27,6 +27,7 @@
   routes.SITE_SETTINGS_BACKGROUND_SYNC,
   routes.SITE_SETTINGS_CAMERA,
   routes.SITE_SETTINGS_CLIPBOARD,
+  routes.SITE_SETTINGS_FEDERATED_IDENTITY_API,
   routes.SITE_SETTINGS_FILE_SYSTEM_WRITE,
   routes.SITE_SETTINGS_HANDLERS,
   routes.SITE_SETTINGS_HID_DEVICES,
diff --git a/chrome/test/data/webui/settings/site_details_tests.ts b/chrome/test/data/webui/settings/site_details_tests.ts
index 36124620..4c81850 100644
--- a/chrome/test/data/webui/settings/site_details_tests.ts
+++ b/chrome/test/data/webui/settings/site_details_tests.ts
@@ -135,6 +135,9 @@
               ContentSettingsTypes.MIXEDSCRIPT,
               [createRawSiteException('https://foo.com:443')]),
           createContentSettingTypeToValuePair(
+              ContentSettingsTypes.FEDERATED_IDENTITY_API,
+              [createRawSiteException('https://foo.com:443')]),
+          createContentSettingTypeToValuePair(
               ContentSettingsTypes.HID_DEVICES,
               [createRawSiteException('https://foo.com:443')]),
           createContentSettingTypeToValuePair(
diff --git a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.ts b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.ts
index 7ca9b95..7474e6d4 100644
--- a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.ts
+++ b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.ts
@@ -78,6 +78,7 @@
       ContentSettingsTypes.BLUETOOTH_SCANNING,
       ContentSettingsTypes.CAMERA,
       ContentSettingsTypes.CLIPBOARD,
+      ContentSettingsTypes.FEDERATED_IDENTITY_API,
       ContentSettingsTypes.FILE_SYSTEM_WRITE,
       ContentSettingsTypes.GEOLOCATION,
       ContentSettingsTypes.HID_DEVICES,
diff --git a/chrome/test/interaction/interaction_sequence_browser_util.cc b/chrome/test/interaction/interaction_sequence_browser_util.cc
index c52eb4a..d628aad6 100644
--- a/chrome/test/interaction/interaction_sequence_browser_util.cc
+++ b/chrome/test/interaction/interaction_sequence_browser_util.cc
@@ -22,6 +22,7 @@
 #include "base/time/time.h"
 #include "base/timer/elapsed_timer.h"
 #include "base/values.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index e3956c8..749c561 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -413,14 +413,16 @@
       "-e",
       "COPYRIGHT=\"updater_copyright\"",
       "-e",
-      "KEYSTONE_NAME=\"$keystone_app_name\"",
-      "-e",
       "CRASH_PRODUCT_NAME=\"$crash_product_name\"",
       "-e",
       "CRASH_UPLOAD_URL=\"$crash_upload_url\"",
       "-e",
       "DEVICE_MANAGEMENT_SERVER_URL=\"$device_management_server_url\"",
       "-e",
+      "HELP_CENTER_URL=\"$help_center_url\"",
+      "-e",
+      "KEYSTONE_NAME=\"$keystone_app_name\"",
+      "-e",
       "PRIVILEGED_HELPER_NAME=\"$privileged_helper_name\"",
       "-e",
       "PRODUCT_FULLNAME=\"$updater_product_full_name\"",
diff --git a/chrome/updater/branding.gni b/chrome/updater/branding.gni
index e6de3fe..057e3c2 100644
--- a/chrome/updater/branding.gni
+++ b/chrome/updater/branding.gni
@@ -9,6 +9,7 @@
   browser_product_name = "Google Chrome"
   crash_product_name = "Update4"
   crash_upload_url = "https://clients2.google.com/cr/report"
+  help_center_url = "http://support.google.com/installer/"
   keystone_app_name = "GoogleSoftwareUpdate"
   mac_browser_bundle_identifier = "com.google.Chrome"
   mac_updater_bundle_identifier = "com.google.GoogleUpdater"
@@ -24,6 +25,7 @@
   browser_product_name = "Chromium"
   crash_product_name = "ChromiumUpdater"
   crash_upload_url = "https://clients2.google.com/cr/staging_report"
+  help_center_url = "http://support.google.com/installer/"
   keystone_app_name = "ChromiumSoftwareUpdate"
   mac_browser_bundle_identifier = "org.chromium.Chromium"
   mac_updater_bundle_identifier = "org.chromium.ChromiumUpdater"
diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc
index 56c7381..e14d59c 100644
--- a/chrome/updater/configurator.cc
+++ b/chrome/updater/configurator.cc
@@ -36,6 +36,7 @@
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_WIN)
+#include "base/win/win_util.h"
 #include "chrome/updater/win/net/network.h"
 #elif BUILDFLAG(IS_MAC)
 #include "chrome/updater/mac/net/network.h"
@@ -192,8 +193,20 @@
 }
 
 absl::optional<bool> Configurator::IsMachineExternallyManaged() const {
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-  return base::IsMachineExternallyManaged();
+#if BUILDFLAG(IS_WIN)
+  // TODO (crbug.com/1320776): For legacy compatibility, this uses
+  // base::IsEnrolledToDomain(). It cannot use IsEnterpriseDevice() because
+  // checking for AAD-join status involves a potentially blocking which is
+  // currently not allowed in this method.
+  // Consider whether this should use IsManagedDevice() instead.
+  return base::win::IsEnrolledToDomain();
+#elif BUILDFLAG(IS_MAC)
+  // TODO (crbug.com/1320776): For legacy compatibility, this uses
+  // IsEnterpriseDevice() which effectively equates to a domain join check.
+  // IsManagedDevice() involves potentially blocking calls which are currently
+  // not allowed in this method.
+  // Consider whether this should use IsManagedDevice() instead.
+  return base::IsEnterpriseDevice();
 #else
   return absl::nullopt;
 #endif
diff --git a/chrome/updater/policy/dm_policy_manager.cc b/chrome/updater/policy/dm_policy_manager.cc
index a6521663..e2cacaeb 100644
--- a/chrome/updater/policy/dm_policy_manager.cc
+++ b/chrome/updater/policy/dm_policy_manager.cc
@@ -59,7 +59,7 @@
 
 bool DMPolicyManager::IsManaged() const {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-  return base::IsMachineExternallyManaged();
+  return base::IsManagedDevice();
 #else
   // crbug.com/1276162 - implement.
   NOTIMPLEMENTED();
diff --git a/chrome/updater/policy/dm_policy_manager_unittest.cc b/chrome/updater/policy/dm_policy_manager_unittest.cc
index 222d77b..8d77d3d 100644
--- a/chrome/updater/policy/dm_policy_manager_unittest.cc
+++ b/chrome/updater/policy/dm_policy_manager_unittest.cc
@@ -109,7 +109,7 @@
   auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings));
 
 #if !BUILDFLAG(IS_LINUX)
-  EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged());
+  EXPECT_EQ(policy_manager->IsManaged(), base::IsManagedDevice());
 #endif  // BUILDFLAG(IS_LINUX)
   EXPECT_EQ(policy_manager->source(), "DeviceManagement");
 
@@ -185,7 +185,7 @@
   auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings));
 
 #if !BUILDFLAG(IS_LINUX)
-  EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged());
+  EXPECT_EQ(policy_manager->IsManaged(), base::IsManagedDevice());
 #endif  // BUILDFLAG(IS_LINUX)
   EXPECT_EQ(policy_manager->source(), "DeviceManagement");
 
@@ -276,7 +276,7 @@
 
   auto policy_manager(std::make_unique<DMPolicyManager>(omaha_settings));
 
-  EXPECT_EQ(policy_manager->IsManaged(), base::IsMachineExternallyManaged());
+  EXPECT_EQ(policy_manager->IsManaged(), base::IsManagedDevice());
   EXPECT_EQ(policy_manager->source(), "DeviceManagement");
 
   int last_check_period_minutes = 0;
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm
index eeb9b10..7f74db0 100644
--- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm
+++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm
@@ -217,7 +217,7 @@
 
 - (instancetype)initWithDictionary:(CRUUpdatePolicyDictionary*)policies {
   if (([super init])) {
-    _managed = policies.count > 0 && base::IsMachineExternallyManaged();
+    _managed = policies.count > 0 && base::IsManagedOrEnterpriseDevice();
 
     // Always create a global policy instance for default values.
     _globalPolicy.reset([[CRUManagedPreferenceGlobalPolicySettings alloc]
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm
index 1b6771d..ab81ba4c 100644
--- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm
+++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm
@@ -34,7 +34,7 @@
       [[CRUManagedPreferencePolicyManager alloc]
           initWithDictionary:policyDict]);
   EXPECT_NSEQ([policyManager source], @"ManagedPreference");
-  EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged());
+  EXPECT_EQ([policyManager managed], base::IsManagedOrEnterpriseDevice());
 
   // Verify global level policies.
   EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet);
@@ -78,7 +78,7 @@
       [[CRUManagedPreferencePolicyManager alloc]
           initWithDictionary:policyDict]);
   EXPECT_NSEQ([policyManager source], @"ManagedPreference");
-  EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged());
+  EXPECT_EQ([policyManager managed], base::IsManagedOrEnterpriseDevice());
 
   // Verify global level policies are set to default.
   EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet);
@@ -117,7 +117,7 @@
       [[CRUManagedPreferencePolicyManager alloc]
           initWithDictionary:policyDict]);
   EXPECT_NSEQ([policyManager source], @"ManagedPreference");
-  EXPECT_EQ([policyManager managed], base::IsMachineExternallyManaged());
+  EXPECT_EQ([policyManager managed], base::IsManagedOrEnterpriseDevice());
 
   // Verify global level policies.
   EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet);
diff --git a/chrome/updater/policy/win/group_policy_manager.cc b/chrome/updater/policy/win/group_policy_manager.cc
index 4d1e0e97..30d1ebd 100644
--- a/chrome/updater/policy/win/group_policy_manager.cc
+++ b/chrome/updater/policy/win/group_policy_manager.cc
@@ -82,7 +82,7 @@
 GroupPolicyManager::~GroupPolicyManager() = default;
 
 bool GroupPolicyManager::IsManaged() const {
-  return policies_.DictSize() > 0 && base::IsMachineExternallyManaged();
+  return policies_.DictSize() > 0 && base::IsManagedDevice();
 }
 
 std::string GroupPolicyManager::source() const {
@@ -204,10 +204,10 @@
 void GroupPolicyManager::LoadAllPolicies() {
   scoped_hpolicy policy_lock;
 
-  if (base::IsMachineExternallyManaged()) {
+  if (base::IsManagedDevice()) {
     // GPO rules mandate a call to EnterCriticalPolicySection() before reading
     // policies (and a matching LeaveCriticalPolicySection() call after read).
-    // Acquire the lock for domain-joined machines because group policies are
+    // Acquire the lock for managed machines because group policies are
     // applied only in this case, and the lock acquisition can take a long
     // time, in the worst case scenarios.
     policy_lock.reset(::EnterCriticalPolicySection(true));
diff --git a/chrome/updater/updater_branding.h.in b/chrome/updater/updater_branding.h.in
index a37c3fd..0202d516 100644
--- a/chrome/updater/updater_branding.h.in
+++ b/chrome/updater/updater_branding.h.in
@@ -9,11 +9,10 @@
 #define CRASH_PRODUCT_NAME "@CRASH_PRODUCT_NAME@"
 #define DEVICE_MANAGEMENT_SERVER_URL "@DEVICE_MANAGEMENT_SERVER_URL@"
 #define KEYSTONE_NAME "@KEYSTONE_NAME@"
+#define HELP_CENTER_URL "@HELP_CENTER_URL@"
 #define MAC_BROWSER_BUNDLE_IDENTIFIER_STRING "@MAC_BROWSER_BUNDLE_IDENTIFIER@"
 #define MAC_BUNDLE_IDENTIFIER_STRING "@MAC_BUNDLE_IDENTIFIER@"
 #define PRIVILEGED_HELPER_NAME "@PRIVILEGED_HELPER_NAME@"
 #define PRODUCT_FULLNAME_STRING "@PRODUCT_FULLNAME@"
 #define UPDATE_CHECK_URL "@UPDATE_CHECK_URL@"
 
-
-
diff --git a/chrome/updater/win/app_install_controller.cc b/chrome/updater/win/app_install_controller.cc
index fafb948..91107458 100644
--- a/chrome/updater/win/app_install_controller.cc
+++ b/chrome/updater/win/app_install_controller.cc
@@ -9,13 +9,21 @@
 #include <string>
 #include <vector>
 
+#include <shldisp.h>
+#include <shlobj.h>
+#include <wrl/client.h>
+
 #include "base/callback.h"
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/process/launch.h"
 #include "base/sequence_checker.h"
+#include "base/strings/escape.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
@@ -27,13 +35,20 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "base/win/atl.h"
+#include "base/win/scoped_bstr.h"
+#include "base/win/scoped_variant.h"
+#include "base/win/shlwapi.h"
 #include "chrome/updater/registration_data.h"
 #include "chrome/updater/service_proxy_factory.h"
 #include "chrome/updater/update_service.h"
 #include "chrome/updater/update_service_internal.h"
+#include "chrome/updater/updater_branding.h"
 #include "chrome/updater/updater_scope.h"
 #include "chrome/updater/util.h"
 #include "chrome/updater/win/install_progress_observer.h"
+#include "chrome/updater/win/scoped_impersonation.h"
+#include "chrome/updater/win/user_info.h"
+#include "chrome/updater/win/win_util.h"
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wmissing-braces"
@@ -48,6 +63,30 @@
 namespace updater {
 namespace {
 
+bool GetShellDispatch(Microsoft::WRL::ComPtr<IShellDispatch2>* shell_dispatch) {
+  long hwnd = 0;
+  Microsoft::WRL::ComPtr<IShellWindows> shell;
+  Microsoft::WRL::ComPtr<IDispatch> dispatch;
+  Microsoft::WRL::ComPtr<IServiceProvider> service;
+  Microsoft::WRL::ComPtr<IShellBrowser> browser;
+  Microsoft::WRL::ComPtr<IShellView> view;
+  Microsoft::WRL::ComPtr<IShellFolderViewDual> folder;
+  return SUCCEEDED(::CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL,
+                                      IID_PPV_ARGS(&shell))) &&
+         SUCCEEDED(shell->FindWindowSW(
+             base::win::ScopedVariant(CSIDL_DESKTOP).AsInput(), nullptr,
+             SWC_DESKTOP, &hwnd, SWFO_NEEDDISPATCH, &dispatch)) &&
+         SUCCEEDED(dispatch.As(&service)) &&
+         SUCCEEDED(service->QueryService(SID_STopLevelBrowser,
+                                         IID_PPV_ARGS(&browser))) &&
+         SUCCEEDED(browser->QueryActiveShellView(&view)) &&
+         SUCCEEDED(
+             view->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&dispatch))) &&
+         SUCCEEDED(dispatch.As(&folder)) &&
+         SUCCEEDED(folder->get_Application(&dispatch)) &&
+         SUCCEEDED(dispatch.As(shell_dispatch));
+}
+
 // Implements a simple inter-thread communication protocol based on Windows
 // messages exchanged between the application installer and its UI.
 //
@@ -389,7 +428,7 @@
   void DoExit() override;
 
   // Overrides for CompleteWndEvents. This function is called on the UI thread.
-  bool DoLaunchBrowser(const std::u16string& url) override;
+  bool DoLaunchBrowser(const std::string& url) override;
 
   // Overrides for ProgressWndEvents. These functions are called on the UI
   // thread.
@@ -611,8 +650,10 @@
   ObserverCompletionInfo observer_info;
   observer_info.completion_code = completion_code;
   observer_info.completion_text = completion_text;
-  // TODO(sorin): implement handling the help URL. https://crbug.com/1014622
-  observer_info.help_url = u"http://www.google.com";
+  observer_info.help_url =
+      base::StringPrintf("%s?product=%s&error=%d", HELP_CENTER_URL,
+                         base::EscapeUrlEncodedData(app_id_, false).c_str(),
+                         update_state.error_code);
   // TODO(sorin): implement the installer API and provide the
   // application info in the observer info. https://crbug.com/1014630
   observer_info.apps_info.push_back({});
@@ -668,9 +709,16 @@
   return ::GetWindowThreadProcessId(progress_wnd_->m_hWnd, nullptr);
 }
 
-bool AppInstallControllerImpl::DoLaunchBrowser(const std::u16string& url) {
+bool AppInstallControllerImpl::DoLaunchBrowser(const std::string& url) {
   DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
-  return false;
+  Microsoft::WRL::ComPtr<IShellDispatch2> shell_dispatch;
+  base::win::ScopedVariant empty(L"");
+#undef ShellExecute
+  return GetShellDispatch(&shell_dispatch) &&
+         SUCCEEDED(shell_dispatch->ShellExecute(
+             base::win::ScopedBstr(base::SysUTF8ToWide(url).c_str()).Get(),
+             *empty.AsInput(), *empty.AsInput(), *empty.AsInput(),
+             *base::win::ScopedVariant(SW_SHOWNORMAL).AsInput()));
 }
 
 bool AppInstallControllerImpl::DoRestartBrowser(
diff --git a/chrome/updater/win/install_progress_observer.h b/chrome/updater/win/install_progress_observer.h
index f1a1777c..8adfa7d 100644
--- a/chrome/updater/win/install_progress_observer.h
+++ b/chrome/updater/win/install_progress_observer.h
@@ -79,7 +79,7 @@
 struct ObserverCompletionInfo {
   CompletionCodes completion_code = CompletionCodes::COMPLETION_CODE_SUCCESS;
   std::wstring completion_text;
-  std::u16string help_url;
+  std::string help_url;
   std::vector<AppCompletionInfo> apps_info;
 
   ObserverCompletionInfo();
diff --git a/chrome/updater/win/ui/complete_wnd.cc b/chrome/updater/win/ui/complete_wnd.cc
index a13fbea..a2633f77 100644
--- a/chrome/updater/win/ui/complete_wnd.cc
+++ b/chrome/updater/win/ui/complete_wnd.cc
@@ -88,7 +88,7 @@
 
 void CompleteWnd::DisplayCompletionDialog(bool is_success,
                                           const std::wstring& text,
-                                          const std::u16string& help_url) {
+                                          const std::string& help_url) {
   if (!OmahaWnd::OnComplete())
     return;
 
diff --git a/chrome/updater/win/ui/complete_wnd.h b/chrome/updater/win/ui/complete_wnd.h
index 5a3f09d..1d7063a0 100644
--- a/chrome/updater/win/ui/complete_wnd.h
+++ b/chrome/updater/win/ui/complete_wnd.h
@@ -21,7 +21,7 @@
  public:
   // Launches the browser and returns true if the browser was successfully
   // launched.
-  virtual bool DoLaunchBrowser(const std::u16string& url) = 0;
+  virtual bool DoLaunchBrowser(const std::string& url) = 0;
 };
 
 class CompleteWnd : public OmahaWnd {
@@ -35,7 +35,7 @@
 
   void DisplayCompletionDialog(bool is_success,
                                const std::wstring& text,
-                               const std::u16string& help_url);
+                               const std::string& help_url);
   BEGIN_MSG_MAP(CompleteWnd)
     MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
     COMMAND_HANDLER(IDC_GET_HELP, BN_CLICKED, OnClickedGetHelp)
@@ -71,7 +71,7 @@
 
   HRESULT SetControlState(bool is_success);
 
-  std::u16string help_url_;
+  std::string help_url_;
   raw_ptr<CompleteWndEvents> events_sink_ = nullptr;
   const DWORD control_classes_;
 };
diff --git a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
index 9c07b11..abd334d6 100644
--- a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
+++ b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
@@ -24,7 +24,7 @@
                   android:screenOrientation="landscape"
                   android:taskAffinity=".CastWebContentsActivity"
                   android:supportsPictureInPicture="true"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|screenLayout|smallestScreenSize"
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|screenLayout|smallestScreenSize|uiMode"
                   android:excludeFromRecents="false"
                   android:noHistory="false">
         </activity>
diff --git a/chromecast/browser/android/apk/CastBrowserAndroidManifest.xml.jinja2 b/chromecast/browser/android/apk/CastBrowserAndroidManifest.xml.jinja2
index 635009a7..2769d7e 100644
--- a/chromecast/browser/android/apk/CastBrowserAndroidManifest.xml.jinja2
+++ b/chromecast/browser/android/apk/CastBrowserAndroidManifest.xml.jinja2
@@ -55,7 +55,7 @@
                   android:screenOrientation="landscape"
                   android:taskAffinity=".CastWebContentsActivity"
                   android:supportsPictureInPicture="true"
-                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|screenLayout|smallestScreenSize|uiMode"
                   android:excludeFromRecents="false"
                   android:noHistory="false">
         </activity>
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 00883ac..592f007 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -2767,20 +2767,20 @@
         Not sure
       </message>
       <!-- Choose write protect disable method page -->
-      <message name="IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE" translateable="false" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
-        Select how you would like to disable write-protect
+      <message name="IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
+        Select how you would like to turn off Write Protect
       </message>
-      <message name="IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION"  translateable="false" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
-        Manually disable write-protect
+      <message name="IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
+        Manually turn off
       </message>
-      <message name="IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION" translateable="false" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
-        Once you disable write-protect, you can immediately enable it again. You will see instructions for disabling write-protect on this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> on the next screen.
+      <message name="IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
+        You'll need to take apart the device
       </message>
-      <message name="IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_OPTION"  translateable="false" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
+      <message name="IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_OPTION" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
         Perform RMA Server Unlock (RSU)
       </message>
-      <message name="IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_DESCRIPTION" translateable="false" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
-        This requires an RSU-enabled Security Key, a QR code scanner, and a second device with internet connectivity.
+      <message name="IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_DESCRIPTION" desc="Title for the page offering the options for disabling write protect on this device. Disabling write protection allows the new components to be calibrated and the system to be updated with information about them.">
+        You'll need an RSU-enabled security key, a QR code scanner, and a second device with an internet connection
       </message>
       <!-- Enter RSU code page -->
       <message name="IDS_SHIMLESS_RMA_RSU_CODE_PAGE_TITLE" desc="Title for the RSU challenge page.">
@@ -3007,9 +3007,6 @@
       <message name="IDS_SHIMLESS_RMA_MANUALLY_ENABLE_WP_INSTRUCTIONS" translateable="false" desc="The text instructions to manually enable write-protect on the device.">
         Enable write-protect to continue to the next screen. Learn how to enable write-protect for this device by viewing the manufacturer's instructions.
       </message>
-      <message name="IDS_SHIMLESS_RMA_MANUALLY_ENABLED_WP_MESSAGE" translateable="false" desc="Message to inform user hardware write protection has been enabled and RMA is ready to continue.">
-        Hardware write protection enabled. Click 'Next' to continue.
-      </message>
       <!-- Confirm device information page -->
       <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_TITLE" translateable="false" desc="The title for the page for confirming the device info.">
         Please confirm device information
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE.png.sha1
new file mode 100644
index 0000000..30afd6b
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_CHOOSE_WP_DISABLE_METHOD_PAGE_TITLE.png.sha1
@@ -0,0 +1 @@
+62d0ef9471e4d7c3a092bd38d350d2f1c6f683cc
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..30afd6b
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+62d0ef9471e4d7c3a092bd38d350d2f1c6f683cc
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION.png.sha1
new file mode 100644
index 0000000..30afd6b
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_MANUAL_WP_DISABLE_METHOD_OPTION.png.sha1
@@ -0,0 +1 @@
+62d0ef9471e4d7c3a092bd38d350d2f1c6f683cc
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_DESCRIPTION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..30afd6b
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+62d0ef9471e4d7c3a092bd38d350d2f1c6f683cc
\ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_OPTION.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_OPTION.png.sha1
new file mode 100644
index 0000000..30afd6b
--- /dev/null
+++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_RSU_WP_DISABLE_METHOD_OPTION.png.sha1
@@ -0,0 +1 @@
+62d0ef9471e4d7c3a092bd38d350d2f1c6f683cc
\ No newline at end of file
diff --git a/chromeos/memory/userspace_swap/userspace_swap.cc b/chromeos/memory/userspace_swap/userspace_swap.cc
index 5c6de4e6..376fad0 100644
--- a/chromeos/memory/userspace_swap/userspace_swap.cc
+++ b/chromeos/memory/userspace_swap/userspace_swap.cc
@@ -36,6 +36,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace chromeos {
 namespace memory {
@@ -516,7 +517,7 @@
         current_area_length += base::kSuperPageSize;
       } else {
         if (current_area) {
-          regions.emplace_back(base::in_place, current_area,
+          regions.emplace_back(absl::in_place, current_area,
                                current_area_length);
           current_area = 0;
           current_area_length = 0;
@@ -525,7 +526,7 @@
     }
 
     if (current_area) {
-      regions.emplace_back(base::in_place, current_area, current_area_length);
+      regions.emplace_back(absl::in_place, current_area, current_area_length);
     }
 
     if (!superpages_remaining)
diff --git a/chromeos/profiles/orderfile.newest.txt b/chromeos/profiles/orderfile.newest.txt
index ea947c37..dcab11d5 100644
--- a/chromeos/profiles/orderfile.newest.txt
+++ b/chromeos/profiles/orderfile.newest.txt
@@ -1 +1 @@
-chromeos-chrome-orderfile-field-102-5005.6-1650882860-benchmark-102.0.5005.36-r1.orderfile.xz
+chromeos-chrome-orderfile-field-102-5005.6-1650882860-benchmark-102.0.5005.37-r1.orderfile.xz
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 295990c..a2f9136 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -307,7 +307,6 @@
       "//components/certificate_transparency:unit_tests",
       "//components/content_capture/browser:unit_tests",
       "//components/content_settings/browser:unit_tests",
-      "//components/contextual_search/core:unit_tests",
       "//components/continuous_search/browser:unit_tests",
       "//components/continuous_search/common:unit_tests",
       "//components/custom_handlers:unit_tests",
diff --git a/components/about_ui/android/BUILD.gn b/components/about_ui/android/BUILD.gn
index f1e9562..670e2ab 100644
--- a/components/about_ui/android/BUILD.gn
+++ b/components/about_ui/android/BUILD.gn
@@ -10,7 +10,6 @@
 android_library("aboutui_java") {
   sources = [ "java/src/org/chromium/components/aboutui/CreditUtils.java" ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
diff --git a/components/android_autofill/browser/test_support/BUILD.gn b/components/android_autofill/browser/test_support/BUILD.gn
index 67e63fe..98f6a97 100644
--- a/components/android_autofill/browser/test_support/BUILD.gn
+++ b/components/android_autofill/browser/test_support/BUILD.gn
@@ -14,7 +14,6 @@
     "java/src/org/chromium/components/autofill/AutofillProviderTestHelper.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn
index 7e080415..6c2f0b5 100644
--- a/components/autofill/android/BUILD.gn
+++ b/components/autofill/android/BUILD.gn
@@ -94,7 +94,6 @@
   deps = [
     ":autofill_java_resources",
     ":payments_autofill_java",
-    "//base:base_java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 648401c..ace0619 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -100,10 +100,10 @@
 class MockBrowserAutofillManager : public BrowserAutofillManager {
  public:
   MockBrowserAutofillManager(AutofillDriver* driver, MockAutofillClient* client)
-      // Force to use the constructor designated for unit test.
       : BrowserAutofillManager(driver,
                                client,
-                               client->GetPersonalDataManager()) {}
+                               "en-US",
+                               EnableDownloadManager(false)) {}
   MockBrowserAutofillManager(const MockBrowserAutofillManager&) = delete;
   MockBrowserAutofillManager& operator=(const MockBrowserAutofillManager&) =
       delete;
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc
index 07f1649..d43c29c8 100644
--- a/components/autofill/core/browser/autofill_field.cc
+++ b/components/autofill/core/browser/autofill_field.cc
@@ -41,7 +41,7 @@
   return field;
 }
 
-ServerFieldType AutofillField::heuristic_type(PredictionSource s) const {
+ServerFieldType AutofillField::heuristic_type(PatternSource s) const {
   ServerFieldType type = local_type_predictions_[static_cast<size_t>(s)];
   // `NO_SERVER_DATA` would mean that there is no heuristic type. Client code
   // presumes there is a prediction, therefore we coalesce to `UNKNOWN_TYPE`.
@@ -60,8 +60,7 @@
                                      : server_predictions_[0].override();
 }
 
-void AutofillField::set_heuristic_type(PredictionSource s,
-                                       ServerFieldType type) {
+void AutofillField::set_heuristic_type(PatternSource s, ServerFieldType type) {
   if (type < 0 || type > MAX_VALID_FIELD_TYPE ||
       type == FIELD_WITH_DEFAULT_VALUE) {
     NOTREACHED();
@@ -70,7 +69,7 @@
     type = UNKNOWN_TYPE;
   }
   local_type_predictions_[static_cast<size_t>(s)] = type;
-  if (s == PredictionSource::kDefaultHeuristics)
+  if (s == PatternSource::kDefault)
     overall_type_ = AutofillType(NO_SERVER_DATA);
 }
 
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h
index 7add6599..7da0f65 100644
--- a/components/autofill/core/browser/autofill_field.h
+++ b/components/autofill/core/browser/autofill_field.h
@@ -53,7 +53,7 @@
       FieldSignature field_signature);
 
   ServerFieldType heuristic_type(
-      PredictionSource s = PredictionSource::kDefaultHeuristics) const;
+      PatternSource s = PatternSource::kDefault) const;
   ServerFieldType server_type() const;
   bool server_type_prediction_is_override() const;
   const std::vector<
@@ -77,7 +77,7 @@
   bool only_fill_when_focused() const { return only_fill_when_focused_; }
 
   // Setters for the detected types.
-  void set_heuristic_type(PredictionSource s, ServerFieldType t);
+  void set_heuristic_type(PatternSource s, ServerFieldType t);
   void add_possible_types_validities(
       const ServerFieldTypeValidityStateMap& possible_types_validities);
   void set_server_predictions(
@@ -253,8 +253,7 @@
   // Predictions which where calculated on the client. This is initialized to
   // `NO_SERVER_DATA`, which means "NO_DATA", i.e. no classification was
   // attempted.
-  std::array<ServerFieldType,
-             static_cast<size_t>(PredictionSource::kMaxValue) + 1>
+  std::array<ServerFieldType, static_cast<size_t>(PatternSource::kMaxValue) + 1>
       local_type_predictions_;
 
   // The type of the field. Overrides all other types (html_type_,
diff --git a/components/autofill/core/browser/autofill_merge_unittest.cc b/components/autofill/core/browser/autofill_merge_unittest.cc
index 8f232cdb..b43a893 100644
--- a/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -292,7 +292,7 @@
             const_cast<AutofillField*>(form_structure.field(j));
         ServerFieldType type =
             StringToFieldType(base::UTF16ToUTF8(field->name));
-        field->set_heuristic_type(PredictionSource::kDefaultHeuristics, type);
+        field->set_heuristic_type(PatternSource::kDefault, type);
       }
       form_structure.IdentifySections(false);
 
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index e5c79bf..efbd61e5 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -414,18 +414,6 @@
     AutofillClient* client,
     const std::string& app_locale,
     EnableDownloadManager enable_download_manager)
-    : BrowserAutofillManager(driver,
-                             client,
-                             client->GetPersonalDataManager(),
-                             app_locale,
-                             enable_download_manager) {}
-
-BrowserAutofillManager::BrowserAutofillManager(
-    AutofillDriver* driver,
-    AutofillClient* client,
-    PersonalDataManager* personal_data,
-    const std::string app_locale,
-    EnableDownloadManager enable_download_manager)
     : AutofillManager(driver,
                       client,
                       client->GetChannel(),
@@ -433,7 +421,7 @@
       external_delegate_(
           std::make_unique<AutofillExternalDelegate>(this, driver)),
       app_locale_(app_locale),
-      personal_data_(personal_data),
+      personal_data_(client->GetPersonalDataManager()),
       field_filler_(app_locale, client->GetAddressNormalizer()),
       single_field_form_fill_router_(client->GetSingleFieldFormFillRouter()),
       suggestion_generator_(
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index 31dede18..0019c7e 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -337,14 +337,6 @@
 #endif
 
  protected:
-  // Test code should prefer to use this constructor.
-  BrowserAutofillManager(AutofillDriver* driver,
-                         AutofillClient* client,
-                         PersonalDataManager* personal_data,
-                         const std::string app_locale = "en-US",
-                         EnableDownloadManager enable_download_manager =
-                             EnableDownloadManager(false));
-
   // Uploads the form data to the Autofill server. |observed_submission|
   // indicates that upload is the result of a submission event.
   virtual void UploadFormData(const FormStructure& submitted_form,
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 4c4b8c1..42f88637 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -348,17 +348,17 @@
 
   void SetUp() override {
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
-    personal_data_.set_auto_accept_address_imports_for_testing(true);
-    personal_data_.Init(/*profile_database=*/database_,
-                        /*account_database=*/nullptr,
-                        /*pref_service=*/autofill_client_.GetPrefs(),
-                        /*local_state=*/autofill_client_.GetPrefs(),
-                        /*identity_manager=*/nullptr,
-                        /*history_service=*/nullptr,
-                        /*strike_database=*/nullptr,
-                        /*image_fetcher=*/nullptr,
-                        /*is_off_the_record=*/false);
-    personal_data_.SetPrefService(autofill_client_.GetPrefs());
+    personal_data().set_auto_accept_address_imports_for_testing(true);
+    personal_data().Init(/*profile_database=*/database_,
+                         /*account_database=*/nullptr,
+                         /*pref_service=*/autofill_client_.GetPrefs(),
+                         /*local_state=*/autofill_client_.GetPrefs(),
+                         /*identity_manager=*/nullptr,
+                         /*history_service=*/nullptr,
+                         /*strike_database=*/nullptr,
+                         /*image_fetcher=*/nullptr,
+                         /*is_off_the_record=*/false);
+    personal_data().SetPrefService(autofill_client_.GetPrefs());
 
     autocomplete_history_manager_ =
         std::make_unique<NiceMock<MockAutocompleteHistoryManager>>();
@@ -371,22 +371,22 @@
         std::make_unique<testing::NiceMock<MockAutofillDriver>>();
     auto payments_client = std::make_unique<payments::TestPaymentsClient>(
         autofill_driver_->GetURLLoaderFactory(),
-        autofill_client_.GetIdentityManager(), &personal_data_);
+        autofill_client_.GetIdentityManager(), &personal_data());
     payments_client_ = payments_client.get();
     autofill_client_.set_test_payments_client(std::move(payments_client));
     TestCreditCardSaveManager* credit_card_save_manager =
         new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_,
-                                      payments_client_, &personal_data_);
+                                      payments_client_, &personal_data());
     credit_card_save_manager->SetCreditCardUploadEnabled(true);
     TestFormDataImporter* test_form_data_importer = new TestFormDataImporter(
         &autofill_client_, payments_client_,
         std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager),
-        &personal_data_, "en-US");
+        &personal_data(), "en-US");
     autofill_client_.set_test_form_data_importer(
         std::unique_ptr<autofill::TestFormDataImporter>(
             test_form_data_importer));
     browser_autofill_manager_ = std::make_unique<TestBrowserAutofillManager>(
-        autofill_driver_.get(), &autofill_client_, &personal_data_);
+        autofill_driver_.get(), &autofill_client_);
 
     auto single_field_form_fill_router =
         std::make_unique<NiceMock<MockSingleFieldFormFillRouter>>(
@@ -418,7 +418,7 @@
   }
 
   void CreateTestServerCreditCards() {
-    personal_data_.ClearCreditCards();
+    personal_data().ClearCreditCards();
 
     CreditCard masked_server_card;
     test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
@@ -426,7 +426,7 @@
                             "04", "2999", "1");
     masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
     masked_server_card.set_record_type(CreditCard::MASKED_SERVER_CARD);
-    personal_data_.AddServerCreditCard(masked_server_card);
+    personal_data().AddServerCreditCard(masked_server_card);
 
     CreditCard full_server_card;
     test::SetCreditCardInfo(&full_server_card, "Buddy Holly",
@@ -434,11 +434,11 @@
                             "10", "2998", "1");
     full_server_card.set_guid("00000000-0000-0000-0000-000000000008");
     full_server_card.set_record_type(CreditCard::FULL_SERVER_CARD);
-    personal_data_.AddServerCreditCard(full_server_card);
+    personal_data().AddServerCreditCard(full_server_card);
   }
 
   void CreateTestServerAndLocalCreditCards() {
-    personal_data_.ClearCreditCards();
+    personal_data().ClearCreditCards();
 
     CreditCard masked_server_card;
     test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
@@ -446,7 +446,7 @@
                             "04", "2999", "1");
     masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
     masked_server_card.set_record_type(CreditCard::MASKED_SERVER_CARD);
-    personal_data_.AddServerCreditCard(masked_server_card);
+    personal_data().AddServerCreditCard(masked_server_card);
 
     CreditCard full_server_card;
     test::SetCreditCardInfo(&full_server_card, "Buddy Holly",
@@ -454,7 +454,7 @@
                             "10", "2998", "1");
     full_server_card.set_guid("00000000-0000-0000-0000-000000000008");
     full_server_card.set_record_type(CreditCard::FULL_SERVER_CARD);
-    personal_data_.AddServerCreditCard(full_server_card);
+    personal_data().AddServerCreditCard(full_server_card);
 
     CreditCard local_card;
     test::SetCreditCardInfo(&local_card, "Elvis Presley",
@@ -462,7 +462,7 @@
                             "04", "2999", "1");
     local_card.set_guid("00000000-0000-0000-0000-000000000009");
     local_card.set_record_type(CreditCard::LOCAL_CARD);
-    personal_data_.AddCreditCard(local_card);
+    personal_data().AddCreditCard(local_card);
   }
 
   void TearDown() override {
@@ -470,8 +470,8 @@
     // PersonalDataManager to be around when it gets destroyed.
     browser_autofill_manager_.reset();
 
-    personal_data_.SetPrefService(nullptr);
-    personal_data_.ClearCreditCards();
+    personal_data().SetPrefService(nullptr);
+    personal_data().ClearCreditCards();
   }
 
   void GetAutofillSuggestions(int query_id,
@@ -704,9 +704,8 @@
     // |browser_autofill_manager_| owns the |single_field_form_fill_router_| and
     // clears it upon being recreated. Clear it first and then give it a new
     // SingleFieldFormFillRouter to avoid referencing deleted memory.
-    browser_autofill_manager_.reset();
     browser_autofill_manager_ = std::make_unique<TestBrowserAutofillManager>(
-        autofill_driver_.get(), &autofill_client_, &personal_data_);
+        autofill_driver_.get(), &autofill_client_);
 
     auto single_field_form_fill_router =
         std::make_unique<NiceMock<MockSingleFieldFormFillRouter>>(
@@ -717,6 +716,10 @@
   }
 
  protected:
+  TestPersonalDataManager& personal_data() {
+    return *autofill_client_.GetPersonalDataManager();
+  }
+
   base::test::TaskEnvironment task_environment_;
   NiceMock<MockAutofillClient> autofill_client_;
   std::unique_ptr<MockAutofillDriver> autofill_driver_;
@@ -724,7 +727,6 @@
   raw_ptr<TestAutofillExternalDelegate> external_delegate_;
   scoped_refptr<AutofillWebDataService> database_;
   raw_ptr<MockAutofillDownloadManager> download_manager_;
-  TestPersonalDataManager personal_data_;
   std::unique_ptr<MockAutocompleteHistoryManager> autocomplete_history_manager_;
   raw_ptr<MockSingleFieldFormFillRouter> single_field_form_fill_router_;
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -748,20 +750,20 @@
                          "Apt. 10", "Memphis", "Tennessee", "38116", "US",
                          "12345678901");
     profile1.set_guid("00000000-0000-0000-0000-000000000001");
-    personal_data_.AddProfile(profile1);
+    personal_data().AddProfile(profile1);
 
     AutofillProfile profile2;
     test::SetProfileInfo(&profile2, "Charles", "Hardin", "Holley",
                          "buddy@gmail.com", "Decca", "123 Apple St.", "unit 6",
                          "Lubbock", "Texas", "79401", "US", "23456789012");
     profile2.set_guid("00000000-0000-0000-0000-000000000002");
-    personal_data_.AddProfile(profile2);
+    personal_data().AddProfile(profile2);
 
     AutofillProfile profile3;
     test::SetProfileInfo(&profile3, "", "", "", "", "", "", "", "", "", "", "",
                          "");
     profile3.set_guid("00000000-0000-0000-0000-000000000003");
-    personal_data_.AddProfile(profile3);
+    personal_data().AddProfile(profile3);
   }
 
   void CreateTestCreditCards() {
@@ -772,7 +774,7 @@
     credit_card1.set_guid("00000000-0000-0000-0000-000000000004");
     credit_card1.set_use_count(10);
     credit_card1.set_use_date(AutofillClock::Now() - base::Days(5));
-    personal_data_.AddCreditCard(credit_card1);
+    personal_data().AddCreditCard(credit_card1);
 
     CreditCard credit_card2;
     test::SetCreditCardInfo(&credit_card2, "Buddy Holly",
@@ -781,12 +783,12 @@
     credit_card2.set_guid("00000000-0000-0000-0000-000000000005");
     credit_card2.set_use_count(5);
     credit_card2.set_use_date(AutofillClock::Now() - base::Days(4));
-    personal_data_.AddCreditCard(credit_card2);
+    personal_data().AddCreditCard(credit_card2);
 
     CreditCard credit_card3;
     test::SetCreditCardInfo(&credit_card3, "", "", "", "", "");
     credit_card3.set_guid("00000000-0000-0000-0000-000000000006");
-    personal_data_.AddCreditCard(credit_card3);
+    personal_data().AddCreditCard(credit_card3);
   }
 };
 
@@ -1280,21 +1282,21 @@
   profile1.SetInfo(NAME_FIRST, u"Robin", "en-US");
   profile1.SetInfo(NAME_LAST, u"Grimes", "en-US");
   profile1.SetInfo(ADDRESS_HOME_LINE1, u"1234 Smith Blvd.", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
 
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000124");
   profile2.SetInfo(NAME_FIRST, u"Carl", "en-US");
   profile2.SetInfo(NAME_LAST, u"Grimes", "en-US");
   profile2.SetInfo(ADDRESS_HOME_LINE1, u"1234 Smith Blvd.", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 
   AutofillProfile profile3;
   profile3.set_guid("00000000-0000-0000-0000-000000000126");
   profile3.SetInfo(NAME_FIRST, u"Aaron", "en-US");
   profile3.SetInfo(NAME_LAST, u"Googler", "en-US");
   profile3.SetInfo(ADDRESS_HOME_LINE1, u"1600 Amphitheater pkwy", "en-US");
-  personal_data_.AddProfile(profile3);
+  personal_data().AddProfile(profile3);
 
   FormFieldData field;
   test::CreateTestFormField("Last Name", "lastname", "G", "text", &field);
@@ -1387,9 +1389,9 @@
   FormsSeen(forms);
 
   // Add a duplicate profile.
-  AutofillProfile duplicate_profile = *(personal_data_.GetProfileWithGUID(
+  AutofillProfile duplicate_profile = *(personal_data().GetProfileWithGUID(
       "00000000-0000-0000-0000-000000000001"));
-  personal_data_.AddProfile(duplicate_profile);
+  personal_data().AddProfile(duplicate_profile);
 
   const FormFieldData& field = form.fields[0];
   GetAutofillSuggestions(form, field);
@@ -1614,7 +1616,7 @@
                           "5255667890123123",  // Mastercard
                           "08", "2017", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
 
   // Set up our form data.
   FormData form;
@@ -1675,7 +1677,7 @@
 // field is the credit card number field.
 TEST_P(CreditCardSuggestionTest, GetCreditCardSuggestions_CCNumber) {
   // Set nickname with the corresponding guid of the Mastercard 8765.
-  personal_data_.SetNicknameForCardWithGUID(
+  personal_data().SetNicknameForCardWithGUID(
       "00000000-0000-0000-0000-000000000005", kArbitraryNickname);
   // Set up our form data.
   FormData form;
@@ -1719,7 +1721,7 @@
 // field is not the credit card number field.
 TEST_P(CreditCardSuggestionTest, GetCreditCardSuggestions_NonCCNumber) {
   // Set nickname with the corresponding guid of the Mastercard 8765.
-  personal_data_.SetNicknameForCardWithGUID(
+  personal_data().SetNicknameForCardWithGUID(
       "00000000-0000-0000-0000-000000000005", kArbitraryNickname);
   // Set up our form data.
   FormData form;
@@ -1780,7 +1782,7 @@
 // AutofillExternalDelegateTest that test whether the promo is added.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        GetCreditCardSuggestions_OnlySigninPromo) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
 
   // Set up our form data.
   FormData form;
@@ -1832,7 +1834,7 @@
 
   // Clear the test credit cards and try again -- we should still show the
   // mixed form warning.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   GetAutofillSuggestions(form, field);
   CheckSuggestions(
       kDefaultPageID,
@@ -1924,7 +1926,7 @@
                           "05", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
   credit_card.set_use_date(AutofillClock::Now() - base::Days(15));
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
 
   // Set up our form data.
   FormData form;
@@ -1967,7 +1969,7 @@
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        GetCreditCardSuggestions_MaskedCardWithMoreThan6Digits) {
   // Add a masked server card.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
 
   CreditCard masked_server_card;
   test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
@@ -1975,8 +1977,8 @@
                           "04", "2999", "1");
   masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
   masked_server_card.set_record_type(CreditCard::MASKED_SERVER_CARD);
-  personal_data_.AddServerCreditCard(masked_server_card);
-  EXPECT_EQ(1U, personal_data_.GetCreditCards().size());
+  personal_data().AddServerCreditCard(masked_server_card);
+  EXPECT_EQ(1U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
@@ -1995,7 +1997,7 @@
 // after non expired cards even if they have a higher frecency score.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        GetCreditCardSuggestions_ExpiredCards) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
 
   // Add a never used non expired credit card.
   CreditCard credit_card0("002149C1-EE28-4213-A3B9-DA243FFF021B",
@@ -2004,7 +2006,7 @@
                           "5105105105105100" /* Mastercard */, "04", "2055",
                           "1");
   credit_card0.set_guid("00000000-0000-0000-0000-000000000001");
-  personal_data_.AddCreditCard(credit_card0);
+  personal_data().AddCreditCard(credit_card0);
 
   // Add an expired card with a higher frecency score.
   CreditCard credit_card1("287151C8-6AB1-487C-9095-28E80BE5DA15",
@@ -2015,7 +2017,7 @@
   credit_card1.set_guid("00000000-0000-0000-0000-000000000002");
   credit_card1.set_use_count(300);
   credit_card1.set_use_date(AutofillClock::Now() - base::Days(10));
-  personal_data_.AddCreditCard(credit_card1);
+  personal_data().AddCreditCard(credit_card1);
 
   // Add an expired card with a lower frecency score.
   CreditCard credit_card2("1141084B-72D7-4B73-90CF-3D6AC154673B",
@@ -2025,9 +2027,9 @@
   test::SetCreditCardInfo(&credit_card2, "John Dillinger",
                           "4234567890123456" /* Visa */, "01", "2011", "1");
   credit_card2.set_guid("00000000-0000-0000-0000-000000000003");
-  personal_data_.AddCreditCard(credit_card2);
+  personal_data().AddCreditCard(credit_card2);
 
-  ASSERT_EQ(3U, personal_data_.GetCreditCards().size());
+  ASSERT_EQ(3U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
@@ -2067,8 +2069,8 @@
 // enabled and the input field is empty.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        GetCreditCardSuggestions_SuppressDisusedCreditCardsOnEmptyField) {
-  personal_data_.ClearCreditCards();
-  ASSERT_EQ(0U, personal_data_.GetCreditCards().size());
+  personal_data().ClearCreditCards();
+  ASSERT_EQ(0U, personal_data().GetCreditCards().size());
 
   // Add a never used non expired local credit card.
   CreditCard credit_card0("00000000-0000-0000-0000-000000000000",
@@ -2076,7 +2078,7 @@
   test::SetCreditCardInfo(&credit_card0, "Bonnie Parker",
                           "5105105105105100" /* Mastercard */, "04", "2999",
                           "1");
-  personal_data_.AddCreditCard(credit_card0);
+  personal_data().AddCreditCard(credit_card0);
 
   auto now = AutofillClock::Now();
 
@@ -2086,7 +2088,7 @@
   test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
                           "4234567890123456" /* Visa */, "04", "2010", "1");
   credit_card1.set_use_date(now - base::Days(10));
-  personal_data_.AddCreditCard(credit_card1);
+  personal_data().AddCreditCard(credit_card1);
 
   // Add an expired local card last used 180 days ago.
   CreditCard credit_card2("00000000-0000-0000-0000-000000000002",
@@ -2095,9 +2097,9 @@
   test::SetCreditCardInfo(&credit_card2, "John Dillinger",
                           "378282246310005" /* American Express */, "01",
                           "2010", "1");
-  personal_data_.AddCreditCard(credit_card2);
+  personal_data().AddCreditCard(credit_card2);
 
-  ASSERT_EQ(3U, personal_data_.GetCreditCards().size());
+  ASSERT_EQ(3U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
@@ -2215,8 +2217,8 @@
        GetCreditCardSuggestions_NumberMissing) {
   // Create one normal credit card and one credit card with the number
   // missing.
-  personal_data_.ClearCreditCards();
-  ASSERT_EQ(0U, personal_data_.GetCreditCards().size());
+  personal_data().ClearCreditCards();
+  ASSERT_EQ(0U, personal_data().GetCreditCards().size());
 
   CreditCard credit_card0("287151C8-6AB1-487C-9095-28E80BE5DA15",
                           test::kEmptyOrigin);
@@ -2224,16 +2226,16 @@
                           "378282246310005" /* American Express */, "04",
                           "2999", "1");
   credit_card0.set_guid("00000000-0000-0000-0000-000000000001");
-  personal_data_.AddCreditCard(credit_card0);
+  personal_data().AddCreditCard(credit_card0);
 
   CreditCard credit_card1("1141084B-72D7-4B73-90CF-3D6AC154673B",
                           test::kEmptyOrigin);
   test::SetCreditCardInfo(&credit_card1, "John Dillinger", "", "01", "2999",
                           "1");
   credit_card1.set_guid("00000000-0000-0000-0000-000000000002");
-  personal_data_.AddCreditCard(credit_card1);
+  personal_data().AddCreditCard(credit_card1);
 
-  ASSERT_EQ(2U, personal_data_.GetCreditCards().size());
+  ASSERT_EQ(2U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
@@ -2380,7 +2382,7 @@
                               "", "", -1));
 
   // Clear the test credit cards and try again -- we shouldn't return a warning.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   GetAutofillSuggestions(form, field);
   external_delegate_->CheckNoSuggestions(kDefaultPageID);
 }
@@ -2451,7 +2453,7 @@
   }
 
   const char guid[] = "00000000-0000-0000-0000-000000000001";
-  AutofillProfile* profile = personal_data_.GetProfileWithGUID(guid);
+  AutofillProfile* profile = personal_data().GetProfileWithGUID(guid);
   ASSERT_TRUE(profile);
   EXPECT_EQ(1U, profile->use_count());
   EXPECT_NE(base::Time(), profile->use_date());
@@ -2497,7 +2499,7 @@
     *it = FormFieldData();
 
   const char guid[] = "00000000-0000-0000-0000-000000000001";
-  AutofillProfile* profile = personal_data_.GetProfileWithGUID(guid);
+  AutofillProfile* profile = personal_data().GetProfileWithGUID(guid);
   ASSERT_TRUE(profile);
 
   int response_query_id = 0;
@@ -2535,7 +2537,7 @@
   form.fields.pop_back();
 
   const char guid[] = "00000000-0000-0000-0000-000000000001";
-  AutofillProfile* profile = personal_data_.GetProfileWithGUID(guid);
+  AutofillProfile* profile = personal_data().GetProfileWithGUID(guid);
   ASSERT_TRUE(profile);
 
   EXPECT_CALL(*autofill_driver_, FillOrPreviewForm(_, _, _, _, _)).Times(0);
@@ -2664,8 +2666,8 @@
                                   << static_cast<int>(form_type));
 
   if (!params.run_with_data_on_file) {
-    personal_data_.ClearAllServerData();
-    personal_data_.ClearAllLocalData();
+    personal_data().ClearAllServerData();
+    personal_data().ClearAllLocalData();
   }
 
   DisableAutofillViaAblation(scoped_feature_list_, /*for_addresses=*/true,
@@ -3010,7 +3012,7 @@
   test::SetProfileInfo(&profile, "Elvis", "", "", "", "", "", "", "", "", "",
                        "", "");
   profile.set_guid("00000000-0000-0000-0000-000000000101");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   FormFieldData& field = form.fields[0];
   field.is_autofilled = true;
@@ -3043,7 +3045,7 @@
   profile.set_guid("00000000-0000-0000-0000-000000000103");
   profile.SetInfo(NAME_FULL, u"Natty Bumppo", "en-US");
   profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"1800PRAIRIE");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   const FormFieldData& field = form.fields[9];
   GetAutofillSuggestions(form, field);
@@ -3131,11 +3133,11 @@
   std::vector<FormData> forms(1, form);
   FormsSeen(forms);
 
-  personal_data_.ClearProfiles();
+  personal_data().ClearProfiles();
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000104");
   profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"1800FLOWERS");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   const FormFieldData& phone_prefix = form.fields[2];
   GetAutofillSuggestions(form, phone_prefix);
@@ -3165,8 +3167,8 @@
   profile.set_guid("00000000-0000-0000-0000-000000000103");
   profile.SetInfo(NAME_FULL, u"Natty Bumppo", "en-US");
   profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+886123456789");
-  personal_data_.ClearProfiles();
-  personal_data_.AddProfile(profile);
+  personal_data().ClearProfiles();
+  personal_data().AddProfile(profile);
 
   const FormFieldData& field = form.fields[9];
   GetAutofillSuggestions(form, field);
@@ -3209,12 +3211,12 @@
   std::vector<FormData> forms(1, form);
   FormsSeen(forms);
 
-  personal_data_.ClearProfiles();
+  personal_data().ClearProfiles();
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000103");
   profile.SetRawInfo(NAME_FULL, u"Natty Bumppo");
   profile.SetRawInfo(EMAIL_ADDRESS, u"test@example.com");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   GetAutofillSuggestions(form, form.fields[2]);
   CheckSuggestions(kDefaultPageID,
@@ -3230,7 +3232,7 @@
   FormsSeen(forms);
 
   const char guid[] = "00000000-0000-0000-0000-000000000001";
-  AutofillProfile* profile = personal_data_.GetProfileWithGUID(guid);
+  AutofillProfile* profile = personal_data().GetProfileWithGUID(guid);
   ASSERT_TRUE(profile);
   EXPECT_EQ(1U, profile->use_count());
   EXPECT_NE(base::Time(), profile->use_date());
@@ -3343,13 +3345,13 @@
        FillCreditCardForm_StripCardNumberWhitespace) {
   // Same as the SetUp(), but generate Elvis card with whitespace in credit
   // card number.  |credit_card| will be owned by the TestPersonalDataManager.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Elvis Presley",
                           "4234 5678 9012 3456",  // Visa
                           "04", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000008");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, false);
@@ -3372,13 +3374,13 @@
   // Same as the SetUp(), but generate Elvis card with separator characters in
   // credit card number.  |credit_card| will be owned by the
   // TestPersonalDataManager.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Elvis Presley",
                           "4234-5678-9012-3456",  // Visa
                           "04", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000009");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, false);
@@ -3399,13 +3401,13 @@
 // Test 1 of 4: Empty month, empty year
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillCreditCardForm_NoYearNoMonth) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
                           "4234567890654321",  // Visa
                           "", "", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, true);
@@ -3426,13 +3428,13 @@
 // Test 2 of 4: Non-empty month, empty year
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillCreditCardForm_NoYearMonth) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
                           "4234567890654321",  // Visa
                           "04", "", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, true);
@@ -3455,13 +3457,13 @@
        FillCreditCardForm_YearNoMonth) {
   // Same as the SetUp(), but generate 4 credit cards with year month
   // combination.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
                           "4234567890654321",  // Visa
                           "", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, true);
@@ -3482,13 +3484,13 @@
 // Test 4 of 4: Non-empty month, non-empty year
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillCreditCardForm_YearMonth) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
                           "4234567890654321",  // Visa
                           "04", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, true);
@@ -3767,7 +3769,7 @@
                        "Apt. 10", "Memphis", "Tennessee", "38116", "US",
                        "12345678901");
   profile.set_guid(guid);
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   int response_page_id = 0;
   FormData response_data;
@@ -3960,7 +3962,7 @@
                        "Apt. 10", "Memphis", "Tennessee", "38116", "US",
                        "12345678901");
   profile.set_guid(guid);
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   int response_page_id = 0;
   FormData response_data;
@@ -4094,13 +4096,13 @@
 // expiration date.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillCreditCardForm_ExpiredCard) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard expired_card;
   test::SetCreditCardInfo(&expired_card, "Homer Simpson",
                           "4234567890654321",  // Visa
                           "05", "2000", "1");
   expired_card.set_guid("00000000-0000-0000-0000-000000000009");
-  personal_data_.AddCreditCard(expired_card);
+  personal_data().AddCreditCard(expired_card);
 
   // Set up the form data.
   FormData form;
@@ -4155,9 +4157,9 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        PreviewCreditCardForm_VirtualCard) {
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard virtual_card = test::GetVirtualCard();
-  personal_data_.AddServerCreditCard(virtual_card);
+  personal_data().AddServerCreditCard(virtual_card);
   // Set up our form data.
   FormData form;
   CreateTestCreditCardFormData(&form, true, false);
@@ -4701,8 +4703,8 @@
   FormsSeen(forms);
 
   // We should be able to fill prefix and suffix fields for US numbers.
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -4780,8 +4782,8 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_ComponentizedNumbers) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -4848,8 +4850,8 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_WholeNumbers) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -4898,8 +4900,8 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_FillPartsOnceOnly) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -4971,8 +4973,8 @@
 // phone field, we do not fill anything to extension field.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_NotFillMisclassifiedExtention) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -5031,8 +5033,8 @@
 // Verify when no complete number can be found, we do best-effort filling.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_BestEfforFilling) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -5088,8 +5090,8 @@
 // entire form, both first phone field and second phone field included.
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_FocusOnSecondPhoneNumber) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -5141,8 +5143,8 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_HiddenFieldShouldNotCount) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -5265,8 +5267,8 @@
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest,
        FillFirstPhoneNumber_MultipleSectionFilledCorrectly) {
-  AutofillProfile* work_profile =
-      personal_data_.GetProfileWithGUID("00000000-0000-0000-0000-000000000002");
+  AutofillProfile* work_profile = personal_data().GetProfileWithGUID(
+      "00000000-0000-0000-0000-000000000002");
   ASSERT_TRUE(work_profile != nullptr);
   work_profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"16505554567");
 
@@ -5508,7 +5510,7 @@
   // Simulate form submission. We should call into the PDM to try to save the
   // filled data.
   FormSubmitted(response_data);
-  EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called());
+  EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 }
 
 // Test that we are saving form data when the FormSubmitted event is sent.
@@ -5531,7 +5533,7 @@
 
   browser_autofill_manager_->OnFormSubmitted(response_data, false,
                                              SubmissionSource::FORM_SUBMISSION);
-  EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called());
+  EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 }
 
 // Test that when Autocomplete is enabled and Autofill is disabled, form
@@ -6090,7 +6092,7 @@
   // Simulate form submission. We should call into the PDM to try to save the
   // filled data.
   FormSubmitted(response_data);
-  EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called());
+  EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 }
 
 // Test that we are able to save form data after the possible types have been
@@ -6114,18 +6116,18 @@
   ExpectFilledAddressFormElvis(response_page_id, response_data, kDefaultPageID,
                                false);
 
-  personal_data_.ClearProfiles();
+  personal_data().ClearProfiles();
   // The default credit card is a Elvis card. It must be removed because name
   // fields would be detected. However at least one profile or card is needed to
   // start the upload process, which is why this other card is created.
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard credit_card;
   test::SetCreditCardInfo(&credit_card, "Miku Hatsune",
                           "4234567890654321",  // Visa
                           "04", "2999", "1");
   credit_card.set_guid("00000000-0000-0000-0000-000000000007");
-  personal_data_.AddCreditCard(credit_card);
-  ASSERT_EQ(0u, personal_data_.GetProfiles().size());
+  personal_data().AddCreditCard(credit_card);
+  ASSERT_EQ(0u, personal_data().GetProfiles().size());
 
   // Simulate form submission. The first submission should not count the data
   // towards possible types. Therefore we expect all UNKNOWN_TYPE entries.
@@ -6135,12 +6137,12 @@
                                                 type_set);
   browser_autofill_manager_->SetExpectedSubmittedFieldTypes(unknown_types);
   FormSubmitted(response_data);
-  ASSERT_EQ(1u, personal_data_.GetProfiles().size());
+  ASSERT_EQ(1u, personal_data().GetProfiles().size());
 
   // The second submission should now have data by which to infer types.
   browser_autofill_manager_->SetExpectedSubmittedFieldTypes(expected_types);
   FormSubmitted(response_data);
-  ASSERT_EQ(1u, personal_data_.GetProfiles().size());
+  ASSERT_EQ(1u, personal_data().GetProfiles().size());
 }
 
 // Test that the form signature for an uploaded form always matches the form
@@ -6198,7 +6200,7 @@
   // Simulate form submission.  We should call into the PDM to try to save the
   // filled data.
   FormSubmitted(response_data);
-  EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called());
+  EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 
   // Set the address field's value back to the default value.
   response_data.fields[3].value = u"Enter your address";
@@ -6206,7 +6208,7 @@
   // Simulate form submission.  We should not call into the PDM to try to save
   // the filled data, since the filled form is effectively missing an address.
   FormSubmitted(response_data);
-  EXPECT_EQ(1, personal_data_.num_times_save_imported_profile_called());
+  EXPECT_EQ(1, personal_data().num_times_save_imported_profile_called());
 }
 
 struct ProfileMatchingTypesTestCase {
@@ -7003,13 +7005,13 @@
   AutofillProfile profile;
   const char guid[] = "00000000-0000-0000-0000-000000000102";
   profile.set_guid(guid);
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   int id = MakeFrontendID(std::string(), guid);
 
   browser_autofill_manager_->RemoveAutofillProfileOrCreditCard(id);
 
-  EXPECT_FALSE(personal_data_.GetProfileWithGUID(guid));
+  EXPECT_FALSE(personal_data().GetProfileWithGUID(guid));
 }
 
 TEST_P(BrowserAutofillManagerStructuredProfileTest, RemoveCreditCard) {
@@ -7017,13 +7019,13 @@
   CreditCard credit_card;
   const char guid[] = "00000000-0000-0000-0000-000000100007";
   credit_card.set_guid(guid);
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
 
   int id = MakeFrontendID(guid, std::string());
 
   browser_autofill_manager_->RemoveAutofillProfileOrCreditCard(id);
 
-  EXPECT_FALSE(personal_data_.GetCreditCardWithGUID(guid));
+  EXPECT_FALSE(personal_data().GetCreditCardWithGUID(guid));
 }
 
 // Test our external delegate is called at the right time.
@@ -7595,7 +7597,7 @@
                           "01", "2030", "1");
   credit_card.set_guid(guid);
   credit_card.SetNickname(kArbitraryNickname16);
-  personal_data_.AddCreditCard(credit_card);
+  personal_data().AddCreditCard(credit_card);
 
 #if BUILDFLAG(IS_ANDROID)
   // When keyboard accessary is enabled, always show "7777".
@@ -7865,7 +7867,7 @@
   profile1.SetInfo(NAME_MIDDLE, u"Adam Smith", "en-US");
   profile1.SetInfo(NAME_LAST, u"Grimes", "en-US");
   profile1.SetInfo(ADDRESS_HOME_LINE1, u"1234 Smith Blvd.", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
 
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000124");
@@ -7873,7 +7875,7 @@
   profile2.SetInfo(NAME_MIDDLE, u"Shawn Smith", "en-US");
   profile2.SetInfo(NAME_LAST, u"Grimes", "en-US");
   profile2.SetInfo(ADDRESS_HOME_LINE1, u"1234 Smith Blvd.", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 
   FormFieldData field;
   test::CreateTestFormField("Middle Name", "middlename", "S", "text", &field);
@@ -8170,7 +8172,7 @@
       {features::kAutofillEnableMerchantBoundVirtualCards},
       {features::kAutofillSuggestVirtualCardsOnIncompleteForm});
 
-  personal_data_.ClearCreditCards();
+  personal_data().ClearCreditCards();
   CreditCard masked_server_card(CreditCard::MASKED_SERVER_CARD,
                                 /*server_id=*/"a123");
   test::SetCreditCardInfo(&masked_server_card, "Elvis Presley",
@@ -8180,7 +8182,7 @@
   masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
   masked_server_card.set_virtual_card_enrollment_state(CreditCard::ENROLLED);
   masked_server_card.SetNickname(u"nickname");
-  personal_data_.AddServerCreditCard(masked_server_card);
+  personal_data().AddServerCreditCard(masked_server_card);
 
   // Set up our form data.
   FormData form;
@@ -8960,9 +8962,9 @@
 
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   // The feature is not implemented for mobile.
-  EXPECT_EQ(0, personal_data_.num_times_save_upi_id_called());
+  EXPECT_EQ(0, personal_data().num_times_save_upi_id_called());
 #else
-  EXPECT_EQ(1, personal_data_.num_times_save_upi_id_called());
+  EXPECT_EQ(1, personal_data().num_times_save_upi_id_called());
 #endif
 }
 
@@ -8993,7 +8995,7 @@
   form.fields[0].value = u"user@indianbank";
   FormSubmitted(form);
 
-  EXPECT_EQ(0, personal_data_.num_times_save_upi_id_called());
+  EXPECT_EQ(0, personal_data().num_times_save_upi_id_called());
 }
 
 TEST_F(BrowserAutofillManagerTest, PageLanguageGetsCorrectlySet) {
@@ -9336,7 +9338,7 @@
 
     // Add only one server card so the second suggestion (if any) must be the
     // "Use a virtual card number" option.
-    personal_data_.ClearCreditCards();
+    personal_data().ClearCreditCards();
     CreditCard masked_server_card(CreditCard::MASKED_SERVER_CARD,
                                   /*server_id=*/"a123");
     // TODO(crbug.com/1020740): Replace all the hard-coded expiration year in
@@ -9346,7 +9348,7 @@
                             "04", "2999", "1");
     masked_server_card.SetNetworkForMaskedCard(kVisaCard);
     masked_server_card.set_guid("00000000-0000-0000-0000-000000000007");
-    personal_data_.AddServerCreditCard(masked_server_card);
+    personal_data().AddServerCreditCard(masked_server_card);
   }
 
   void CreateCompleteFormAndGetSuggestions() {
@@ -9362,10 +9364,10 @@
   // Adds a CreditCardCloudTokenData to PersonalDataManager. This needs to be
   // called before suggestions are fetched.
   void CreateCloudTokenDataForDefaultCard() {
-    personal_data_.ClearCloudTokenData();
+    personal_data().ClearCloudTokenData();
     CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1();
     data1.masked_card_id = "a123";
-    personal_data_.AddCloudTokenData(data1);
+    personal_data().AddCloudTokenData(data1);
   }
 
   void VerifyNoVirtualCardSuggestions() {
@@ -9468,7 +9470,7 @@
   CreateCloudTokenDataForDefaultCard();
   CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2();
   data2.masked_card_id = "a123";
-  personal_data_.AddCloudTokenData(data2);
+  personal_data().AddCloudTokenData(data2);
   CreateCompleteFormAndGetSuggestions();
 
   VerifyNoVirtualCardSuggestions();
@@ -9567,13 +9569,13 @@
                           "04", "2999", "1");
   masked_server_card.SetNetworkForMaskedCard(kVisaCard);
   masked_server_card.set_guid("00000000-0000-0000-0000-000000000008");
-  personal_data_.AddServerCreditCard(masked_server_card);
+  personal_data().AddServerCreditCard(masked_server_card);
   CreditCardCloudTokenData data1 = test::GetCreditCardCloudTokenData1();
   data1.masked_card_id = "a456";
-  personal_data_.AddCloudTokenData(data1);
+  personal_data().AddCloudTokenData(data1);
   CreditCardCloudTokenData data2 = test::GetCreditCardCloudTokenData2();
   data2.masked_card_id = "a456";
-  personal_data_.AddCloudTokenData(data2);
+  personal_data().AddCloudTokenData(data2);
 
   CreateCompleteFormAndGetSuggestions();
 
@@ -9839,12 +9841,12 @@
 
 TEST_P(BrowserAutofillManagerTestForSharingNickname,
        VerifySuggestion_DuplicateCards) {
-  personal_data_.ClearCreditCards();
-  ASSERT_EQ(0U, personal_data_.GetCreditCards().size());
+  personal_data().ClearCreditCards();
+  ASSERT_EQ(0U, personal_data().GetCreditCards().size());
   CreditCard local_card = GetLocalCard();
-  personal_data_.AddCreditCard(local_card);
-  personal_data_.AddServerCreditCard(GetServerCard());
-  ASSERT_EQ(2U, personal_data_.GetCreditCards().size());
+  personal_data().AddCreditCard(local_card);
+  personal_data().AddServerCreditCard(GetServerCard());
+  ASSERT_EQ(2U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
@@ -9873,18 +9875,18 @@
 
 TEST_P(BrowserAutofillManagerTestForSharingNickname,
        VerifySuggestion_UnrelatedCards) {
-  personal_data_.ClearCreditCards();
-  ASSERT_EQ(0U, personal_data_.GetCreditCards().size());
+  personal_data().ClearCreditCards();
+  ASSERT_EQ(0U, personal_data().GetCreditCards().size());
   CreditCard local_card = GetLocalCard();
-  personal_data_.AddCreditCard(local_card);
+  personal_data().AddCreditCard(local_card);
 
   std::vector<CreditCard> server_cards;
   CreditCard server_card = GetServerCard();
   // Make sure the cards are different by giving a different card number.
   server_card.SetNumber(u"371449635398431");
-  personal_data_.AddServerCreditCard(server_card);
+  personal_data().AddServerCreditCard(server_card);
 
-  ASSERT_EQ(2U, personal_data_.GetCreditCards().size());
+  ASSERT_EQ(2U, personal_data().GetCreditCards().size());
 
   // Set up our form data.
   FormData form;
diff --git a/components/autofill/core/browser/field_filler_unittest.cc b/components/autofill/core/browser/field_filler_unittest.cc
index 980b1cd..0904d944 100644
--- a/components/autofill/core/browser/field_filler_unittest.cc
+++ b/components/autofill/core/browser/field_filler_unittest.cc
@@ -93,8 +93,7 @@
   AutofillField field;
   test::CreateTestSelectField("", "", "", values, contents, select_size,
                               &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
 
@@ -161,7 +160,7 @@
   EXPECT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
 
   // Set the heuristic type and check it.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
   EXPECT_EQ(FieldTypeGroup::kName, field.Type().group());
 
@@ -194,7 +193,7 @@
   EXPECT_EQ(FieldTypeGroup::kAddressBilling, field.Type().group());
 
   // Set the heuristic type and check it and reset overall Type.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
   EXPECT_EQ(FieldTypeGroup::kName, field.Type().group());
 }
@@ -207,20 +206,18 @@
   field.SetHtmlType(HTML_TYPE_UNRECOGNIZED, HTML_MODE_NONE);
 
   // A credit card heuristic prediction overrides the unrecognized type.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
   EXPECT_EQ(CREDIT_CARD_NUMBER, field.Type().GetStorableType());
 
   // A non credit card heuristic prediction doesn't override the unrecognized
   // type.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   EXPECT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
 
   // A credit card heuristic prediction doesn't override a known specified html
   // type.
   field.SetHtmlType(HTML_TYPE_NAME, HTML_MODE_NONE);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
   EXPECT_EQ(NAME_FULL, field.Type().GetStorableType());
 }
 
@@ -323,7 +320,7 @@
   EXPECT_EQ("502192749", field.FieldSignatureAsStr());
 
   // Heuristic type does not affect FieldSignature.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   EXPECT_EQ("502192749", field.FieldSignatureAsStr());
 
   // Server type does not affect FieldSignature.
@@ -342,17 +339,17 @@
   EXPECT_FALSE(field.IsFieldFillable());
 
   // Only heuristic type is set.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   EXPECT_TRUE(field.IsFieldFillable());
 
   // Only server type is set.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, UNKNOWN_TYPE);
+  field.set_heuristic_type(PatternSource::kDefault, UNKNOWN_TYPE);
   prediction.set_type(NAME_LAST);
   field.set_server_predictions({prediction});
   EXPECT_TRUE(field.IsFieldFillable());
 
   // Both types set.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
   prediction.set_type(NAME_LAST);
   field.set_server_predictions({prediction});
   EXPECT_TRUE(field.IsFieldFillable());
@@ -370,7 +367,7 @@
        FillFormField_AutocompleteOffNotRespected_AddressField) {
   AutofillField field;
   field.should_autocomplete = false;
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
 
   // Non credit card related field.
   address()->SetRawInfo(NAME_FIRST, u"Test");
@@ -387,8 +384,7 @@
 TEST_F(AutofillFieldFillerTest, FillFormField_AutocompleteOff_CreditCardField) {
   AutofillField field;
   field.should_autocomplete = false;
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"4111111111111111");
@@ -407,8 +403,7 @@
   AutofillField field;
   field.max_length = 30;
   field.set_credit_card_number_offset(2);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"0123456789999999");
@@ -428,8 +423,7 @@
   AutofillField field;
   field.max_length = 18;
   field.set_credit_card_number_offset(30);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"0123456789999999");
@@ -448,8 +442,7 @@
   AutofillField field;
   field.max_length = 1;
   field.set_credit_card_number_offset(3);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"0123456789999999");
@@ -466,8 +459,7 @@
 TEST_F(AutofillFieldFillerTest, FillFormField_MaxLength_CreditCardField) {
   AutofillField field;
   field.max_length = 1;
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"4111111111111111");
@@ -483,8 +475,7 @@
 // Test that in the preview credit card numbers are obfuscated.
 TEST_F(AutofillFieldFillerTest, FillFormField_Preview_CreditCardField) {
   AutofillField field;
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
 
   // Credit card related field.
   credit_card()->SetNumber(u"4111111111111111");
@@ -752,7 +743,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kOptions, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
 
   // Set semantically empty contents for each option, so that only the values
   // can be used for matching.
@@ -775,7 +766,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kOptions, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics, NAME_FIRST);
+  field.set_heuristic_type(PatternSource::kDefault, NAME_FIRST);
 
   // Set semantically empty values for each option, so that only the contents
   // can be used for matching.
@@ -846,8 +837,7 @@
   auto test_case = GetParam();
   AutofillField field;
   test::CreateTestSelectField(test_case.select_values, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   // Without a normalizer.
   AutofillProfile address = test::GetFullProfile();
@@ -943,8 +933,7 @@
 TEST_F(AutofillFieldFillerTest, FillSelectWithCountries) {
   AutofillField field;
   test::CreateTestSelectField({"Albania", "Canada"}, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_COUNTRY);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_COUNTRY);
 
   AutofillProfile address = test::GetFullProfile();
   address.SetRawInfo(ADDRESS_HOME_COUNTRY, u"CA");
@@ -1071,8 +1060,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kMonthsAbbreviated, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(4);
@@ -1089,8 +1077,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kMonthsFull, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(4);
@@ -1108,8 +1095,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kMonthsFullWithDigits, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(4);
@@ -1137,8 +1123,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kMonthsFullWithDigits, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(8);
@@ -1157,8 +1142,7 @@
                                             "décembre"};
   AutofillField field;
   test::CreateTestSelectField(kMonthsFrench, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(2);
@@ -1185,8 +1169,7 @@
   };
   AutofillField field;
   test::CreateTestSelectField(kMonthsNumeric, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   CreditCard card = test::GetCreditCard();
   card.SetExpirationMonth(4);
@@ -1201,7 +1184,7 @@
                                      "16", "17", "18", "19"};
   AutofillField field;
   test::CreateTestSelectField(kYears, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_2_DIGIT_YEAR);
 
   CreditCard card = test::GetCreditCard();
@@ -1217,8 +1200,7 @@
                                                "discover"};
   AutofillField field;
   test::CreateTestSelectField(kCreditCardTypes, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_TYPE);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_TYPE);
   CreditCard card = test::GetCreditCard();
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
 
@@ -1251,7 +1233,7 @@
   AutofillField field;
   field.form_control_type = "month";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_4_DIGIT_YEAR);
 
   // Try a month with two digits.
@@ -1272,7 +1254,7 @@
   AutofillField field;
   field.form_control_type = "textarea";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            ADDRESS_HOME_STREET_ADDRESS);
 
   std::u16string value = u"123 Fake St.\nApt. 42";
@@ -1317,7 +1299,7 @@
 TEST_F(AutofillFieldFillerTest, FillCreditCardNumberWithoutSplits) {
   // Case 1: card number without any split.
   AutofillField cc_number_full;
-  cc_number_full.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  cc_number_full.set_heuristic_type(PatternSource::kDefault,
                                     CREDIT_CARD_NUMBER);
 
   credit_card()->SetNumber(u"41111111111111111");
@@ -1342,7 +1324,7 @@
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
   for (size_t i = 0; i < test.total_splits_; ++i) {
     AutofillField cc_number_part;
-    cc_number_part.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+    cc_number_part.set_heuristic_type(PatternSource::kDefault,
                                       CREDIT_CARD_NUMBER);
     cc_number_part.max_length = test.splits_[i];
     cc_number_part.set_credit_card_number_offset(4 * i);
@@ -1360,7 +1342,7 @@
 
   // Verify that full card-number shall get fill properly as well.
   AutofillField cc_number_full;
-  cc_number_full.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  cc_number_full.set_heuristic_type(PatternSource::kDefault,
                                     CREDIT_CARD_NUMBER);
 
   credit_card()->SetNumber(test.card_number_);
@@ -1389,7 +1371,7 @@
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
   for (size_t i = 0; i < test.total_splits_; ++i) {
     AutofillField cc_number_part;
-    cc_number_part.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+    cc_number_part.set_heuristic_type(PatternSource::kDefault,
                                       CREDIT_CARD_NUMBER);
     cc_number_part.max_length = test.splits_[i];
     cc_number_part.set_credit_card_number_offset(4 * i);
@@ -1407,7 +1389,7 @@
 
   // Verify that full card-number shall get fill properly as well.
   AutofillField cc_number_full;
-  cc_number_full.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  cc_number_full.set_heuristic_type(PatternSource::kDefault,
                                     CREDIT_CARD_NUMBER);
 
   credit_card()->SetNumber(test.card_number_);
@@ -1432,7 +1414,7 @@
   // Start executing test cases to verify parts and full credit card number.
   for (size_t i = 0; i < test.total_splits_; ++i) {
     AutofillField cc_number_part;
-    cc_number_part.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+    cc_number_part.set_heuristic_type(PatternSource::kDefault,
                                       CREDIT_CARD_NUMBER);
     cc_number_part.max_length = test.splits_[i];
     cc_number_part.set_credit_card_number_offset(GetNumberOffset(i, test));
@@ -1451,7 +1433,7 @@
 
   // Verify that full card-number shall get fill properly as well.
   AutofillField cc_number_full;
-  cc_number_full.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  cc_number_full.set_heuristic_type(PatternSource::kDefault,
                                     CREDIT_CARD_NUMBER);
   credit_card()->SetNumber(test.card_number_);
   filler.FillFormField(cc_number_full, credit_card(), &cc_number_full,
@@ -1483,7 +1465,7 @@
   // Start executing test cases to verify parts and full credit card number.
   for (size_t i = 0; i < test.total_splits_; ++i) {
     AutofillField cc_number_part;
-    cc_number_part.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+    cc_number_part.set_heuristic_type(PatternSource::kDefault,
                                       CREDIT_CARD_NUMBER);
     cc_number_part.max_length = test.splits_[i];
     cc_number_part.set_credit_card_number_offset(GetNumberOffset(i, test));
@@ -1502,7 +1484,7 @@
 
   // Verify that full card-number shall get fill properly as well.
   AutofillField cc_number_full;
-  cc_number_full.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  cc_number_full.set_heuristic_type(PatternSource::kDefault,
                                     CREDIT_CARD_NUMBER);
   credit_card()->SetNumber(test.card_number_);
   filler.FillFormField(cc_number_full, credit_card(), &cc_number_full,
@@ -1631,8 +1613,7 @@
   std::vector<const char*> kPhoneCountryCode = {"91", "1", "20", "49"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+15145554578");
@@ -1654,8 +1635,7 @@
   std::vector<const char*> kPhoneCountryCode = {"+91", "+1", "+20", "+49"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+918890888888");
@@ -1677,8 +1657,7 @@
   std::vector<const char*> kPhoneCountryCode = {"0091", "001", "0020", "0049"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+918890888888");
@@ -1700,8 +1679,7 @@
       "+20 (Egypt)", "+49 (Germany)"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+49151669087345");
@@ -1724,8 +1702,7 @@
       "(00 20) Egypt", "(00 49) Germany"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+49151669087345");
@@ -1749,8 +1726,7 @@
       "(0020) Egypt", "(0049) Germany"};
   AutofillField field;
   test::CreateTestSelectField(kPhoneCountryCode, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           PHONE_HOME_COUNTRY_CODE);
+  field.set_heuristic_type(PatternSource::kDefault, PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile address;
   address.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, u"+49151669087345");
@@ -1771,8 +1747,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"Bavaria");
@@ -1796,8 +1771,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"Bavaria");
@@ -1821,8 +1795,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"Bavaria");
@@ -1845,8 +1818,7 @@
 
   AutofillField field;
   test::CreateTestFormField("State", "state", "", "text", &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
   field.max_length = 4;
 
   AutofillProfile address;
@@ -1871,8 +1843,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"Bavari");
@@ -1901,8 +1872,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"CO");
@@ -1926,8 +1896,7 @@
 
   AutofillField field;
   test::CreateTestSelectField(kState, &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
 
   AutofillProfile address;
   address.SetRawInfo(ADDRESS_HOME_STATE, u"CO");
@@ -1953,8 +1922,7 @@
 
   AutofillField field;
   test::CreateTestFormField("State", "state", "", "text", &field);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           ADDRESS_HOME_STATE);
+  field.set_heuristic_type(PatternSource::kDefault, ADDRESS_HOME_STATE);
   field.max_length = 4;
 
   AutofillProfile address;
@@ -1971,8 +1939,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_EXP_MONTH);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_EXP_MONTH);
 
   // A month with two digits should return two dots.
   CreditCard card = test::GetVirtualCard();
@@ -1994,7 +1961,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_4_DIGIT_YEAR);
 
   CreditCard card = test::GetVirtualCard();
@@ -2004,7 +1971,7 @@
                        /*failure_to_fill*/ nullptr);
   EXPECT_EQ(kMidlineEllipsis4Dots, field.value);
 
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_2_DIGIT_YEAR);
   filler.FillFormField(field, &card, &field, /*cvc=*/std::u16string(),
                        mojom::RendererFormDataAction::kPreview,
@@ -2018,7 +1985,7 @@
   field.max_length = 2;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_4_DIGIT_YEAR);
 
   CreditCard card = test::GetVirtualCard();
@@ -2033,7 +2000,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
   field.max_length = 7;
 
@@ -2051,7 +2018,7 @@
 
   // A date that has a year containing two digits should return two dots for
   // month and two for year.
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
   field.max_length = 5;
   filler.FillFormField(field, &card, &field, /*cvc=*/std::u16string(),
@@ -2068,7 +2035,7 @@
   field.form_control_type = "text";
   field.max_length = 4;
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
 
   CreditCard card = test::GetVirtualCard();
@@ -2114,7 +2081,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_VERIFICATION_CODE);
 
   CreditCard card = test::GetVirtualCard();
@@ -2130,7 +2097,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
+  field.set_heuristic_type(PatternSource::kDefault,
                            CREDIT_CARD_VERIFICATION_CODE);
 
   CreditCard card = test::GetVirtualCard();
@@ -2143,8 +2110,7 @@
 
 TEST_F(AutofillFieldFillerTest, PreviewVirtualCardNumber) {
   AutofillField field;
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NUMBER);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NUMBER);
   field.set_credit_card_number_offset(50);
   field.form_control_type = "text";
   const char kMasterCard[] = "masterCardCC";
@@ -2174,8 +2140,7 @@
   AutofillField field;
   field.form_control_type = "text";
   FieldFiller filler(/*app_locale=*/"en-US", /*address_normalizer=*/nullptr);
-  field.set_heuristic_type(PredictionSource::kDefaultHeuristics,
-                           CREDIT_CARD_NAME_FULL);
+  field.set_heuristic_type(PatternSource::kDefault, CREDIT_CARD_NAME_FULL);
 
   CreditCard card = test::GetVirtualCard();
   card.SetRawInfoWithVerificationStatus(
diff --git a/components/autofill/core/browser/form_parsing/address_field.cc b/components/autofill/core/browser/form_parsing/address_field.cc
index 190f133..32cacb9 100644
--- a/components/autofill/core/browser/form_parsing/address_field.cc
+++ b/components/autofill/core/browser/form_parsing/address_field.cc
@@ -88,7 +88,7 @@
 std::unique_ptr<FormField> AddressField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   if (scanner->IsEnd())
     return nullptr;
@@ -98,19 +98,19 @@
   size_t saved_cursor = scanner->SaveCursor();
 
   base::span<const MatchPatternRef> email_patterns =
-      GetMatchPatterns("EMAIL_ADDRESS", page_language, prediction_source);
+      GetMatchPatterns("EMAIL_ADDRESS", page_language, pattern_source);
 
   base::span<const MatchPatternRef> address_patterns =
-      GetMatchPatterns("ADDRESS_LOOKUP", page_language, prediction_source);
+      GetMatchPatterns("ADDRESS_LOOKUP", page_language, pattern_source);
 
-  base::span<const MatchPatternRef> address_ignore_patterns = GetMatchPatterns(
-      "ADDRESS_NAME_IGNORED", page_language, prediction_source);
+  base::span<const MatchPatternRef> address_ignore_patterns =
+      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language, pattern_source);
 
   base::span<const MatchPatternRef> attention_ignore_patterns =
-      GetMatchPatterns("ATTENTION_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("ATTENTION_IGNORED", page_language, pattern_source);
 
   base::span<const MatchPatternRef> region_ignore_patterns =
-      GetMatchPatterns("REGION_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("REGION_IGNORED", page_language, pattern_source);
 
   // Allow address fields to appear in any order.
   size_t begin_trailing_non_labeled_fields = 0;
@@ -133,11 +133,11 @@
                    })) {
       continue;
     } else if (address_field->ParseAddress(scanner, page_language,
-                                           prediction_source) ||
+                                           pattern_source) ||
                address_field->ParseDependentLocalityCityStateCountryZipCode(
-                   scanner, page_language, prediction_source) ||
+                   scanner, page_language, pattern_source) ||
                address_field->ParseCompany(scanner, page_language,
-                                           prediction_source)) {
+                                           pattern_source)) {
       has_trailing_non_labeled_fields = false;
       continue;
     } else if (ParseField(scanner, kAttentionIgnoredRe,
@@ -231,21 +231,20 @@
 
 bool AddressField::ParseCompany(AutofillScanner* scanner,
                                 const LanguageCode& page_language,
-                                PredictionSource prediction_source) {
+                                PatternSource pattern_source) {
   if (company_)
     return false;
 
   base::span<const MatchPatternRef> company_patterns =
-      GetMatchPatterns("COMPANY_NAME", page_language, prediction_source);
+      GetMatchPatterns("COMPANY_NAME", page_language, pattern_source);
 
   return ParseField(scanner, kCompanyRe, company_patterns, &company_,
                     {log_manager_, "kCompanyRe"});
 }
 
-bool AddressField::ParseAddressFieldSequence(
-    AutofillScanner* scanner,
-    const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+bool AddressField::ParseAddressFieldSequence(AutofillScanner* scanner,
+                                             const LanguageCode& page_language,
+                                             PatternSource pattern_source) {
   // Search for a sequence of a street name field followed by a house number
   // field. Only if both are found in an abitrary order, the parsing is
   // considered successful.
@@ -258,13 +257,13 @@
 
   const size_t cursor_position = scanner->CursorPosition();
 
-  base::span<const MatchPatternRef> street_name_patterns = GetMatchPatterns(
-      ADDRESS_HOME_STREET_NAME, page_language, prediction_source);
+  base::span<const MatchPatternRef> street_name_patterns =
+      GetMatchPatterns(ADDRESS_HOME_STREET_NAME, page_language, pattern_source);
 
   base::span<const MatchPatternRef> house_number_patterns = GetMatchPatterns(
-      ADDRESS_HOME_HOUSE_NUMBER, page_language, prediction_source);
+      ADDRESS_HOME_HOUSE_NUMBER, page_language, pattern_source);
   base::span<const MatchPatternRef> apartment_number_patterns =
-      GetMatchPatterns(ADDRESS_HOME_APT_NUM, page_language, prediction_source);
+      GetMatchPatterns(ADDRESS_HOME_APT_NUM, page_language, pattern_source);
 
   while (!scanner->IsEnd()) {
     if (!street_name_ &&
@@ -313,22 +312,22 @@
 
 bool AddressField::ParseAddress(AutofillScanner* scanner,
                                 const LanguageCode& page_language,
-                                PredictionSource prediction_source) {
+                                PatternSource pattern_source) {
   if (street_name_ && house_number_) {
     return false;
   }
   // Do not inline these calls: After passing an address field sequence, there
   // might be an additional address line 2 to parse afterwards.
   bool has_field_sequence =
-      ParseAddressFieldSequence(scanner, page_language, prediction_source);
+      ParseAddressFieldSequence(scanner, page_language, pattern_source);
   bool has_address_lines =
-      ParseAddressLines(scanner, page_language, prediction_source);
+      ParseAddressLines(scanner, page_language, pattern_source);
   return has_field_sequence || has_address_lines;
 }
 
 bool AddressField::ParseAddressLines(AutofillScanner* scanner,
                                      const LanguageCode& page_language,
-                                     PredictionSource prediction_source) {
+                                     PatternSource pattern_source) {
   // We only match the string "address" in page text, not in element names,
   // because sometimes every element in a group of address fields will have
   // a name containing the string "address"; for example, on the page
@@ -344,7 +343,7 @@
   std::u16string label_pattern = kAddressLine1LabelRe;
 
   base::span<const MatchPatternRef> address_line1_patterns =
-      GetMatchPatterns("ADDRESS_LINE_1", page_language, prediction_source);
+      GetMatchPatterns("ADDRESS_LINE_1", page_language, pattern_source);
 
   // TODO(crbug.com/1121990): Remove duplicate calls when launching
   // AutofillParsingPatternProvider. The old code calls ParseFieldSpecifics()
@@ -392,7 +391,7 @@
   label_pattern = kAddressLine2LabelRe;
 
   base::span<const MatchPatternRef> address_line2_patterns =
-      GetMatchPatterns("ADDRESS_LINE_2", page_language, prediction_source);
+      GetMatchPatterns("ADDRESS_LINE_2", page_language, pattern_source);
 
   if (!ParseField(scanner, pattern, address_line2_patterns, &address2_,
                   {log_manager_, "kAddressLine2Re"}) &&
@@ -404,7 +403,7 @@
     return true;
 
   base::span<const MatchPatternRef> address_line_extra_patterns =
-      GetMatchPatterns("ADDRESS_LINE_EXTRA", page_language, prediction_source);
+      GetMatchPatterns("ADDRESS_LINE_EXTRA", page_language, pattern_source);
 
   // Optionally parse address line 3. This uses the same label regexp as
   // address 2 above.
@@ -434,14 +433,14 @@
 
 bool AddressField::ParseCountry(AutofillScanner* scanner,
                                 const LanguageCode& page_language,
-                                PredictionSource prediction_source) {
+                                PatternSource pattern_source) {
   if (country_)
     return false;
 
   base::span<const MatchPatternRef> country_patterns =
-      GetMatchPatterns("COUNTRY", page_language, prediction_source);
+      GetMatchPatterns("COUNTRY", page_language, pattern_source);
   base::span<const MatchPatternRef> country_patternsl =
-      GetMatchPatterns("COUNTRY_LOCATION", page_language, prediction_source);
+      GetMatchPatterns("COUNTRY_LOCATION", page_language, pattern_source);
 
   scanner->SaveCursor();
   if (ParseFieldSpecifics(scanner, kCountryRe,
@@ -464,15 +463,15 @@
 
 bool AddressField::ParseZipCode(AutofillScanner* scanner,
                                 const LanguageCode& page_language,
-                                PredictionSource prediction_source) {
+                                PatternSource pattern_source) {
   if (zip_)
     return false;
 
   base::span<const MatchPatternRef> zip_code_patterns =
-      GetMatchPatterns("ZIP_CODE", page_language, prediction_source);
+      GetMatchPatterns("ZIP_CODE", page_language, pattern_source);
 
   base::span<const MatchPatternRef> four_digit_zip_code_patterns =
-      GetMatchPatterns("ZIP_4", page_language, prediction_source);
+      GetMatchPatterns("ZIP_4", page_language, pattern_source);
   if (!ParseFieldSpecifics(scanner, kZipCodeRe, kZipCodeMatchType,
                            zip_code_patterns, &zip_,
                            {log_manager_, "kZipCodeRe"})) {
@@ -489,7 +488,7 @@
 
 bool AddressField::ParseDependentLocality(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source) {
+                                          PatternSource pattern_source) {
   const bool is_enabled_dependent_locality_parsing =
       base::FeatureList::IsEnabled(
           features::kAutofillEnableDependentLocalityParsing);
@@ -499,7 +498,7 @@
 
   base::span<const MatchPatternRef> dependent_locality_patterns =
       GetMatchPatterns("ADDRESS_HOME_DEPENDENT_LOCALITY", page_language,
-                       prediction_source);
+                       pattern_source);
   return ParseFieldSpecifics(scanner, kDependentLocalityRe,
                              kDependentLocalityMatchType,
                              dependent_locality_patterns, &dependent_locality_,
@@ -508,24 +507,24 @@
 
 bool AddressField::ParseCity(AutofillScanner* scanner,
                              const LanguageCode& page_language,
-                             PredictionSource prediction_source) {
+                             PatternSource pattern_source) {
   if (city_)
     return false;
 
   base::span<const MatchPatternRef> city_patterns =
-      GetMatchPatterns("CITY", page_language, prediction_source);
+      GetMatchPatterns("CITY", page_language, pattern_source);
   return ParseFieldSpecifics(scanner, kCityRe, kCityMatchType, city_patterns,
                              &city_, {log_manager_, "kCityRe"});
 }
 
 bool AddressField::ParseState(AutofillScanner* scanner,
                               const LanguageCode& page_language,
-                              PredictionSource prediction_source) {
+                              PatternSource pattern_source) {
   if (state_)
     return false;
 
   base::span<const MatchPatternRef> patterns_state =
-      GetMatchPatterns("STATE", page_language, prediction_source);
+      GetMatchPatterns("STATE", page_language, pattern_source);
   return ParseFieldSpecifics(scanner, kStateRe, kStateMatchType, patterns_state,
                              &state_, {log_manager_, "kStateRe"});
 }
@@ -570,7 +569,7 @@
 bool AddressField::ParseDependentLocalityCityStateCountryZipCode(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   // The |scanner| is not pointing at a field.
   if (scanner->IsEnd())
     return false;
@@ -589,37 +588,37 @@
   // Exactly one field type is missing.
   if (num_of_missing_types == 1) {
     if (!dependent_locality_)
-      return ParseDependentLocality(scanner, page_language, prediction_source);
+      return ParseDependentLocality(scanner, page_language, pattern_source);
     if (!city_)
-      return ParseCity(scanner, page_language, prediction_source);
+      return ParseCity(scanner, page_language, pattern_source);
     if (!state_)
-      return ParseState(scanner, page_language, prediction_source);
+      return ParseState(scanner, page_language, pattern_source);
     if (!country_)
-      return ParseCountry(scanner, page_language, prediction_source);
+      return ParseCountry(scanner, page_language, pattern_source);
     if (!zip_)
-      return ParseZipCode(scanner, page_language, prediction_source);
+      return ParseZipCode(scanner, page_language, pattern_source);
   }
 
   // Check for matches to both the name and the label.
   ParseNameLabelResult dependent_locality_result =
       ParseNameAndLabelForDependentLocality(scanner, page_language,
-                                            prediction_source);
+                                            pattern_source);
   if (dependent_locality_result == RESULT_MATCH_NAME_LABEL)
     return true;
   ParseNameLabelResult city_result =
-      ParseNameAndLabelForCity(scanner, page_language, prediction_source);
+      ParseNameAndLabelForCity(scanner, page_language, pattern_source);
   if (city_result == RESULT_MATCH_NAME_LABEL)
     return true;
   ParseNameLabelResult state_result =
-      ParseNameAndLabelForState(scanner, page_language, prediction_source);
+      ParseNameAndLabelForState(scanner, page_language, pattern_source);
   if (state_result == RESULT_MATCH_NAME_LABEL)
     return true;
   ParseNameLabelResult country_result =
-      ParseNameAndLabelForCountry(scanner, page_language, prediction_source);
+      ParseNameAndLabelForCountry(scanner, page_language, pattern_source);
   if (country_result == RESULT_MATCH_NAME_LABEL)
     return true;
   ParseNameLabelResult zip_result =
-      ParseNameAndLabelForZipCode(scanner, page_language, prediction_source);
+      ParseNameAndLabelForZipCode(scanner, page_language, pattern_source);
   if (zip_result == RESULT_MATCH_NAME_LABEL)
     return true;
 
@@ -641,7 +640,7 @@
     if (country_result != RESULT_MATCH_NONE)
       return SetFieldAndAdvanceCursor(scanner, &country_);
     if (zip_result != RESULT_MATCH_NONE)
-      return ParseZipCode(scanner, page_language, prediction_source);
+      return ParseZipCode(scanner, page_language, pattern_source);
   }
 
   // If there is a clash between the country and the state, set the type of
@@ -671,7 +670,7 @@
     if (country_result == result)
       return SetFieldAndAdvanceCursor(scanner, &country_);
     if (zip_result == result)
-      return ParseZipCode(scanner, page_language, prediction_source);
+      return ParseZipCode(scanner, page_language, pattern_source);
   }
 
   return false;
@@ -680,15 +679,15 @@
 AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForZipCode(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   if (zip_)
     return RESULT_MATCH_NONE;
 
   base::span<const MatchPatternRef> zip_code_patterns =
-      GetMatchPatterns("ZIP_CODE", page_language, prediction_source);
+      GetMatchPatterns("ZIP_CODE", page_language, pattern_source);
 
   base::span<const MatchPatternRef> four_digit_zip_code_patterns =
-      GetMatchPatterns("ZIP_4", page_language, prediction_source);
+      GetMatchPatterns("ZIP_4", page_language, pattern_source);
 
   ParseNameLabelResult result = ParseNameAndLabelSeparately(
       scanner, kZipCodeRe, kZipCodeMatchType, zip_code_patterns, &zip_,
@@ -698,12 +697,12 @@
     return result;
 
   size_t saved_cursor = scanner->SaveCursor();
-  bool found_non_zip4 = ParseCity(scanner, page_language, prediction_source);
+  bool found_non_zip4 = ParseCity(scanner, page_language, pattern_source);
   if (found_non_zip4)
     city_ = nullptr;
   scanner->RewindTo(saved_cursor);
   if (!found_non_zip4) {
-    found_non_zip4 = ParseState(scanner, page_language, prediction_source);
+    found_non_zip4 = ParseState(scanner, page_language, pattern_source);
     if (found_non_zip4)
       state_ = nullptr;
     scanner->RewindTo(saved_cursor);
@@ -723,7 +722,7 @@
 AddressField::ParseNameAndLabelForDependentLocality(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   const bool is_enabled_dependent_locality_parsing =
       base::FeatureList::IsEnabled(
           features::kAutofillEnableDependentLocalityParsing);
@@ -733,7 +732,7 @@
 
   base::span<const MatchPatternRef> dependent_locality_patterns =
       GetMatchPatterns("ADDRESS_HOME_DEPENDENT_LOCALITY", page_language,
-                       prediction_source);
+                       pattern_source);
   return ParseNameAndLabelSeparately(
       scanner, kDependentLocalityRe, kDependentLocalityMatchType,
       dependent_locality_patterns, &dependent_locality_,
@@ -743,12 +742,12 @@
 AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForCity(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   if (city_)
     return RESULT_MATCH_NONE;
 
   base::span<const MatchPatternRef> city_patterns =
-      GetMatchPatterns("CITY", page_language, prediction_source);
+      GetMatchPatterns("CITY", page_language, pattern_source);
   return ParseNameAndLabelSeparately(scanner, kCityRe, kCityMatchType,
                                      city_patterns, &city_,
                                      {log_manager_, "kCityRe"});
@@ -757,12 +756,12 @@
 AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForState(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   if (state_)
     return RESULT_MATCH_NONE;
 
   base::span<const MatchPatternRef> patterns_state =
-      GetMatchPatterns("STATE", page_language, prediction_source);
+      GetMatchPatterns("STATE", page_language, pattern_source);
   return ParseNameAndLabelSeparately(scanner, kStateRe, kStateMatchType,
                                      patterns_state, &state_,
                                      {log_manager_, "kStateRe"});
@@ -771,15 +770,15 @@
 AddressField::ParseNameLabelResult AddressField::ParseNameAndLabelForCountry(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   if (country_)
     return RESULT_MATCH_NONE;
 
   base::span<const MatchPatternRef> country_patterns =
-      GetMatchPatterns("COUNTRY", page_language, prediction_source);
+      GetMatchPatterns("COUNTRY", page_language, pattern_source);
 
   base::span<const MatchPatternRef> country_location_patterns =
-      GetMatchPatterns("COUNTRY_LOCATION", page_language, prediction_source);
+      GetMatchPatterns("COUNTRY_LOCATION", page_language, pattern_source);
 
   ParseNameLabelResult country_result = ParseNameAndLabelSeparately(
       scanner, kCountryRe,
diff --git a/components/autofill/core/browser/form_parsing/address_field.h b/components/autofill/core/browser/form_parsing/address_field.h
index 98f0684..5b48565 100644
--- a/components/autofill/core/browser/form_parsing/address_field.h
+++ b/components/autofill/core/browser/form_parsing/address_field.h
@@ -26,7 +26,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
 
   AddressField(const AddressField&) = delete;
@@ -48,39 +48,39 @@
 
   bool ParseCompany(AutofillScanner* scanner,
                     const LanguageCode& page_language,
-                    PredictionSource prediction_source);
+                    PatternSource pattern_source);
 
   bool ParseAddress(AutofillScanner* scanner,
                     const LanguageCode& page_language,
-                    PredictionSource prediction_source);
+                    PatternSource pattern_source);
 
   bool ParseAddressFieldSequence(AutofillScanner* scanner,
                                  const LanguageCode& page_language,
-                                 PredictionSource prediction_source);
+                                 PatternSource pattern_source);
 
   bool ParseAddressLines(AutofillScanner* scanner,
                          const LanguageCode& page_language,
-                         PredictionSource prediction_source);
+                         PatternSource pattern_source);
 
   bool ParseCountry(AutofillScanner* scanner,
                     const LanguageCode& page_language,
-                    PredictionSource prediction_source);
+                    PatternSource pattern_source);
 
   bool ParseZipCode(AutofillScanner* scanner,
                     const LanguageCode& page_language,
-                    PredictionSource prediction_source);
+                    PatternSource pattern_source);
 
   bool ParseDependentLocality(AutofillScanner* scanner,
                               const LanguageCode& page_language,
-                              PredictionSource prediction_source);
+                              PatternSource pattern_source);
 
   bool ParseCity(AutofillScanner* scanner,
                  const LanguageCode& page_language,
-                 PredictionSource prediction_source);
+                 PatternSource pattern_source);
 
   bool ParseState(AutofillScanner* scanner,
                   const LanguageCode& page_language,
-                  PredictionSource prediction_source);
+                  PatternSource pattern_source);
 
   // Parses the current field pointed to by |scanner|, if it exists, and tries
   // to determine if the field's type corresponds to one of the following:
@@ -88,7 +88,7 @@
   bool ParseDependentLocalityCityStateCountryZipCode(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   // Like ParseFieldSpecifics(), but applies |pattern| against the name and
   // label of the current field separately. If the return value is
@@ -109,27 +109,27 @@
   ParseNameLabelResult ParseNameAndLabelForZipCode(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   ParseNameLabelResult ParseNameAndLabelForDependentLocality(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   ParseNameLabelResult ParseNameAndLabelForCity(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   ParseNameLabelResult ParseNameAndLabelForCountry(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   ParseNameLabelResult ParseNameAndLabelForState(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source);
+      PatternSource pattern_source);
 
   raw_ptr<LogManager> log_manager_;
   AutofillField* company_ = nullptr;
diff --git a/components/autofill/core/browser/form_parsing/address_field_unittest.cc b/components/autofill/core/browser/form_parsing/address_field_unittest.cc
index 2163e37..62d8907 100644
--- a/components/autofill/core/browser/form_parsing/address_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/address_field_unittest.cc
@@ -23,8 +23,7 @@
  protected:
   std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                    const LanguageCode& page_language) override {
-    return AddressField::Parse(scanner, page_language,
-                               PredictionSource::kDefaultHeuristics,
+    return AddressField::Parse(scanner, page_language, PatternSource::kDefault,
                                /*log_manager=*/nullptr);
   }
 };
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field.cc b/components/autofill/core/browser/form_parsing/credit_card_field.cc
index 108529e..51aa1db 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field.cc
@@ -64,7 +64,7 @@
 std::unique_ptr<FormField> CreditCardField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   if (scanner->IsEnd())
     return nullptr;
@@ -75,24 +75,24 @@
   bool cardholder_name_match_has_low_confidence = false;
 
   base::span<const MatchPatternRef> name_on_card_patterns =
-      GetMatchPatterns("NAME_ON_CARD", page_language, prediction_source);
+      GetMatchPatterns("NAME_ON_CARD", page_language, pattern_source);
 
   base::span<const MatchPatternRef> name_on_card_contextual_patterns =
       GetMatchPatterns("NAME_ON_CARD_CONTEXTUAL", page_language,
-                       prediction_source);
+                       pattern_source);
 
   base::span<const MatchPatternRef> last_name_patterns =
-      GetMatchPatterns("LAST_NAME", page_language, prediction_source);
+      GetMatchPatterns("LAST_NAME", page_language, pattern_source);
 
   base::span<const MatchPatternRef> cvc_patterns = GetMatchPatterns(
-      CREDIT_CARD_VERIFICATION_CODE, page_language, prediction_source);
+      CREDIT_CARD_VERIFICATION_CODE, page_language, pattern_source);
 
   // Credit card fields can appear in many different orders.
   // We loop until no more credit card related fields are found, see |break| at
   // the bottom of the loop.
   for (int fields = 0; !scanner->IsEnd(); ++fields) {
     // Ignore gift card fields.
-    if (IsGiftCardField(scanner, log_manager, page_language, prediction_source))
+    if (IsGiftCardField(scanner, log_manager, page_language, pattern_source))
       break;
 
     if (!credit_card_field->cardholder_) {
@@ -191,7 +191,7 @@
     // doesn't have bad side effects.
     AutofillField* current_number_field;
     base::span<const MatchPatternRef> patterns =
-        GetMatchPatterns(CREDIT_CARD_NUMBER, page_language, prediction_source);
+        GetMatchPatterns(CREDIT_CARD_NUMBER, page_language, pattern_source);
     if (ParseFieldSpecifics(scanner, kCardNumberRe, kMatchNumTelAndPwd,
                             patterns, &current_number_field,
                             {log_manager, "kCardNumberRe"})) {
@@ -218,8 +218,8 @@
       continue;
     }
 
-    if (credit_card_field->ParseExpirationDate(
-            scanner, log_manager, page_language, prediction_source)) {
+    if (credit_card_field->ParseExpirationDate(scanner, log_manager,
+                                               page_language, pattern_source)) {
       nb_unknown_fields = 0;
       continue;
     }
@@ -328,7 +328,7 @@
     AutofillScanner* scanner,
     LogManager* log_manager,
     const LanguageCode& page_language,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   if (scanner->IsEnd())
     return false;
 
@@ -350,7 +350,7 @@
 
   // Another way to eliminate days - filter out 'day' fields.
   base::span<const MatchPatternRef> day_patterns =
-      GetMatchPatterns("DAY", page_language, prediction_source);
+      GetMatchPatterns("DAY", page_language, pattern_source);
   if (FormField::ParseFieldSpecifics(
           scanner, kDayRe, kDefaultMatchParamsWith<MatchFieldType::kSelect>,
           day_patterns, nullptr, {log_manager, "kDayRe"})) {
@@ -419,7 +419,7 @@
 bool CreditCardField::IsGiftCardField(AutofillScanner* scanner,
                                       LogManager* log_manager,
                                       const LanguageCode& page_language,
-                                      PredictionSource prediction_source) {
+                                      PatternSource pattern_source) {
   if (scanner->IsEnd())
     return false;
 
@@ -432,13 +432,13 @@
   size_t saved_cursor = scanner->SaveCursor();
 
   base::span<const MatchPatternRef> debit_cards_patterns =
-      GetMatchPatterns("DEBIT_CARD", page_language, prediction_source);
+      GetMatchPatterns("DEBIT_CARD", page_language, pattern_source);
 
   base::span<const MatchPatternRef> debit_gift_card_patterns =
-      GetMatchPatterns("DEBIT_GIFT_CARD", page_language, prediction_source);
+      GetMatchPatterns("DEBIT_GIFT_CARD", page_language, pattern_source);
 
   base::span<const MatchPatternRef> gift_card_patterns =
-      GetMatchPatterns("GIFT_CARD", page_language, prediction_source);
+      GetMatchPatterns("GIFT_CARD", page_language, pattern_source);
 
   if (ParseFieldSpecifics(scanner, kDebitCardRe, kMatchFieldType,
                           debit_cards_patterns, nullptr,
@@ -513,7 +513,7 @@
 bool CreditCardField::ParseExpirationDate(AutofillScanner* scanner,
                                           LogManager* log_manager,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source) {
+                                          PatternSource pattern_source) {
   if (!expiration_date_ && base::LowerCaseEqualsASCII(
                                scanner->Cursor()->form_control_type, "month")) {
     expiration_date_ = scanner->Cursor();
@@ -534,7 +534,7 @@
     expiration_month_ = scanner->Cursor();
     scanner->Advance();
     if (LikelyCardYearSelectField(scanner, log_manager, page_language,
-                                  prediction_source)) {
+                                  pattern_source)) {
       expiration_year_ = scanner->Cursor();
       scanner->Advance();
       return true;
@@ -551,18 +551,18 @@
                               MatchFieldType::kSelect, MatchFieldType::kSearch>;
 
   base::span<const MatchPatternRef> cc_exp_month_patterns =
-      GetMatchPatterns(CREDIT_CARD_EXP_MONTH, page_language, prediction_source);
+      GetMatchPatterns(CREDIT_CARD_EXP_MONTH, page_language, pattern_source);
 
-  base::span<const MatchPatternRef> cc_exp_year_patterns = GetMatchPatterns(
-      "CREDIT_CARD_EXP_YEAR", page_language, prediction_source);
+  base::span<const MatchPatternRef> cc_exp_year_patterns =
+      GetMatchPatterns("CREDIT_CARD_EXP_YEAR", page_language, pattern_source);
 
   base::span<const MatchPatternRef> cc_exp_month_before_year_patterns =
       GetMatchPatterns("CREDIT_CARD_EXP_MONTH_BEFORE_YEAR", page_language,
-                       prediction_source);
+                       pattern_source);
 
   base::span<const MatchPatternRef> cc_exp_year_after_month_patterns =
       GetMatchPatterns("CREDIT_CARD_EXP_YEAR_AFTER_MONTH", page_language,
-                       prediction_source);
+                       pattern_source);
 
   if (ParseFieldSpecifics(scanner, kExpirationMonthRe, kMatchCCType,
                           cc_exp_month_patterns, &expiration_month_,
@@ -597,7 +597,7 @@
   // Try to look for a 2-digit year expiration date.
   base::span<const MatchPatternRef> cc_exp_2digit_year_patterns =
       GetMatchPatterns(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, page_language,
-                       prediction_source);
+                       pattern_source);
   if (ParseFieldSpecifics(scanner, kExpirationDate2DigitYearRe, kMatchCCType,
                           cc_exp_2digit_year_patterns, &expiration_date_,
                           {log_manager_, "kExpirationDate2DigitYearRe"})) {
@@ -607,8 +607,8 @@
   }
 
   // Try to look for a generic expiration date field. (2 or 4 digit year)
-  base::span<const MatchPatternRef> cc_exp_date_patterns = GetMatchPatterns(
-      "CREDIT_CARD_EXP_DATE", page_language, prediction_source);
+  base::span<const MatchPatternRef> cc_exp_date_patterns =
+      GetMatchPatterns("CREDIT_CARD_EXP_DATE", page_language, pattern_source);
   if (ParseFieldSpecifics(scanner, kExpirationDateRe, kMatchCCType,
                           cc_exp_date_patterns, &expiration_date_,
                           {log_manager_, "kExpirationDateRe"})) {
@@ -626,7 +626,7 @@
   // Try to look for a 4-digit year expiration date.
   base::span<const MatchPatternRef> cc_exp_date_4_digit_year_patterns =
       GetMatchPatterns(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, page_language,
-                       prediction_source);
+                       pattern_source);
   if (FieldCanFitDataForFieldType(current_field_max_length,
                                   CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR) &&
       ParseFieldSpecifics(scanner, kExpirationDate4DigitYearRe, kMatchCCType,
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field.h b/components/autofill/core/browser/form_parsing/credit_card_field.h
index 1fa1228..b2b8dc7c 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field.h
+++ b/components/autofill/core/browser/form_parsing/credit_card_field.h
@@ -30,7 +30,7 @@
   ~CreditCardField() override;
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
 
  protected:
@@ -50,7 +50,7 @@
   static bool LikelyCardYearSelectField(AutofillScanner* scanner,
                                         LogManager* log_manager,
                                         const LanguageCode& page_language,
-                                        PredictionSource prediction_source);
+                                        PatternSource pattern_source);
 
   // Returns true if |scanner| points to a <select> field that contains credit
   // card type options.
@@ -63,14 +63,14 @@
   static bool IsGiftCardField(AutofillScanner* scanner,
                               LogManager* log_manager,
                               const LanguageCode& page_language,
-                              PredictionSource prediction_source);
+                              PatternSource pattern_source);
 
   // Parses the expiration month/year/date fields. Returns true if it finds
   // something new.
   bool ParseExpirationDate(AutofillScanner* scanner,
                            LogManager* log_manager,
                            const LanguageCode& page_language,
-                           PredictionSource prediction_source);
+                           PatternSource pattern_source);
 
   // For the combined expiration field we return |exp_year_type_|; otherwise if
   // |expiration_year_| is having year with |max_length| of 2-digits we return
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc b/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
index 07eb9bb..e7f61d7 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
@@ -88,8 +88,8 @@
   std::unique_ptr<FormField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language = LanguageCode("us")) override {
-    return CreditCardField::Parse(
-        scanner, page_language, PredictionSource::kDefaultHeuristics, nullptr);
+    return CreditCardField::Parse(scanner, page_language,
+                                  PatternSource::kDefault, nullptr);
   }
 
   // Runs multiple parsing attempts until the end of the form is reached.
diff --git a/components/autofill/core/browser/form_parsing/email_field.cc b/components/autofill/core/browser/form_parsing/email_field.cc
index 9e91301..864642a 100644
--- a/components/autofill/core/browser/form_parsing/email_field.cc
+++ b/components/autofill/core/browser/form_parsing/email_field.cc
@@ -13,11 +13,11 @@
 // static
 std::unique_ptr<FormField> EmailField::Parse(AutofillScanner* scanner,
                                              const LanguageCode& page_language,
-                                             PredictionSource prediction_source,
+                                             PatternSource pattern_source,
                                              LogManager* log_manager) {
   AutofillField* field;
   base::span<const MatchPatternRef> email_patterns =
-      GetMatchPatterns("EMAIL_ADDRESS", page_language, prediction_source);
+      GetMatchPatterns("EMAIL_ADDRESS", page_language, pattern_source);
   if (ParseFieldSpecifics(scanner, kEmailRe,
                           kDefaultMatchParamsWith<MatchFieldType::kEmail>,
                           email_patterns, &field, {log_manager, "kEmailRe"})) {
diff --git a/components/autofill/core/browser/form_parsing/email_field.h b/components/autofill/core/browser/form_parsing/email_field.h
index a2739e272..8fc4af8d 100644
--- a/components/autofill/core/browser/form_parsing/email_field.h
+++ b/components/autofill/core/browser/form_parsing/email_field.h
@@ -20,7 +20,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
   explicit EmailField(const AutofillField* field);
 
diff --git a/components/autofill/core/browser/form_parsing/field_candidates.h b/components/autofill/core/browser/form_parsing/field_candidates.h
index 9b5b15a..40642b81 100644
--- a/components/autofill/core/browser/form_parsing/field_candidates.h
+++ b/components/autofill/core/browser/form_parsing/field_candidates.h
@@ -9,18 +9,11 @@
 
 #include "base/containers/flat_map.h"
 #include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/form_parsing/regex_patterns.h"
 #include "components/autofill/core/common/unique_ids.h"
 
 namespace autofill {
 
-enum class PredictionSource {
-  kDefaultHeuristics,
-  kExperimentalHeuristics,
-  kNextGenHeuristics,
-  kFallbackHeuristics,
-  kMaxValue = kFallbackHeuristics
-};
-
 // Represents a possible type for a given field.
 struct FieldCandidate {
   FieldCandidate(ServerFieldType field_type, float field_score);
diff --git a/components/autofill/core/browser/form_parsing/form_field.cc b/components/autofill/core/browser/form_parsing/form_field.cc
index 9e841ec3..63409bf 100644
--- a/components/autofill/core/browser/form_parsing/form_field.cc
+++ b/components/autofill/core/browser/form_parsing/form_field.cc
@@ -51,50 +51,50 @@
     const std::vector<std::unique_ptr<AutofillField>>& fields,
     const LanguageCode& page_language,
     bool is_form_tag,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   std::vector<AutofillField*> processed_fields = RemoveCheckableFields(fields);
   FieldCandidatesMap field_candidates;
 
   // Email pass.
   ParseFormFieldsPass(EmailField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
   const size_t email_count = field_candidates.size();
 
   // Merchant promo code pass.
   ParseFormFieldsPass(MerchantPromoCodeField::Parse, processed_fields,
-                      &field_candidates, page_language, prediction_source,
+                      &field_candidates, page_language, pattern_source,
                       log_manager);
   const size_t promo_code_count = field_candidates.size() - email_count;
 
   // Phone pass.
   ParseFormFieldsPass(PhoneField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   // Travel pass.
   ParseFormFieldsPass(TravelField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   // Address pass.
   ParseFormFieldsPass(AddressField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   // Credit card pass.
   ParseFormFieldsPass(CreditCardField::Parse, processed_fields,
-                      &field_candidates, page_language, prediction_source,
+                      &field_candidates, page_language, pattern_source,
                       log_manager);
 
   // Price pass.
   ParseFormFieldsPass(PriceField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   // Name pass.
   ParseFormFieldsPass(NameField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   // Search pass.
   ParseFormFieldsPass(SearchField::Parse, processed_fields, &field_candidates,
-                      page_language, prediction_source, log_manager);
+                      page_language, pattern_source, log_manager);
 
   size_t fillable_fields = 0;
   if (base::FeatureList::IsEnabled(features::kAutofillFixFillableFieldTypes)) {
@@ -151,14 +151,14 @@
     const std::vector<std::unique_ptr<AutofillField>>& fields,
     const LanguageCode& page_language,
     bool is_form_tag,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   std::vector<AutofillField*> processed_fields = RemoveCheckableFields(fields);
   FieldCandidatesMap field_candidates;
 
   // Merchant promo code pass.
   ParseFormFieldsPass(MerchantPromoCodeField::Parse, processed_fields,
-                      &field_candidates, page_language, prediction_source,
+                      &field_candidates, page_language, pattern_source,
                       log_manager);
 
   return field_candidates;
@@ -370,12 +370,12 @@
                                     const std::vector<AutofillField*>& fields,
                                     FieldCandidatesMap* field_candidates,
                                     const LanguageCode& page_language,
-                                    PredictionSource prediction_source,
+                                    PatternSource pattern_source,
                                     LogManager* log_manager) {
   AutofillScanner scanner(fields);
   while (!scanner.IsEnd()) {
     std::unique_ptr<FormField> form_field =
-        parse(&scanner, page_language, prediction_source, log_manager);
+        parse(&scanner, page_language, pattern_source, log_manager);
     if (form_field == nullptr) {
       scanner.Advance();
     } else {
diff --git a/components/autofill/core/browser/form_parsing/form_field.h b/components/autofill/core/browser/form_parsing/form_field.h
index 41752266..12af574 100644
--- a/components/autofill/core/browser/form_parsing/form_field.h
+++ b/components/autofill/core/browser/form_parsing/form_field.h
@@ -50,7 +50,7 @@
       const std::vector<std::unique_ptr<AutofillField>>& fields,
       const LanguageCode& page_language,
       bool is_form_tag,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager = nullptr);
 
   // Looks for a promo code field in |fields|. Each field has a derived unique
@@ -59,7 +59,7 @@
       const std::vector<std::unique_ptr<AutofillField>>& fields,
       const LanguageCode& page_language,
       bool is_form_tag,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager = nullptr);
 
 #if defined(UNIT_TEST)
@@ -139,7 +139,7 @@
   typedef std::unique_ptr<FormField> ParseFunction(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   static bool ParseFieldSpecificsWithNewPatterns(
@@ -192,7 +192,7 @@
                                   const std::vector<AutofillField*>& fields,
                                   FieldCandidatesMap* field_candidates,
                                   const LanguageCode& page_language,
-                                  PredictionSource prediction_source,
+                                  PatternSource pattern_source,
                                   LogManager* log_manager);
 };
 
diff --git a/components/autofill/core/browser/form_parsing/form_field_unittest.cc b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
index ed2d912..2f5f20a 100644
--- a/components/autofill/core/browser/form_parsing/form_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
@@ -131,7 +131,7 @@
   // languages are used.
   EXPECT_TRUE(FormField::ParseFormFields(
                   fields, LanguageCode(""), /*is_form_tag=*/true,
-                  PredictionSource::kDefaultHeuristics, /*log_manager=*/nullptr)
+                  PatternSource::kDefault, /*log_manager=*/nullptr)
                   .empty());
 
   // reset |is_checkable| to false.
@@ -143,7 +143,7 @@
   // Parse a single address line 1 field.
   ASSERT_EQ(0u, FormField::ParseFormFields(fields, LanguageCode(""),
                                            /*is_form_tag=*/true,
-                                           PredictionSource::kDefaultHeuristics,
+                                           PatternSource::kDefault,
                                            /*log_manager=*/nullptr)
                     .size());
 
@@ -156,7 +156,7 @@
   // all languages are used.
   ASSERT_EQ(0u, FormField::ParseFormFields(fields, LanguageCode(""),
                                            /*is_form_tag=*/true,
-                                           PredictionSource::kDefaultHeuristics,
+                                           PatternSource::kDefault,
                                            /*log_manager=*/nullptr)
                     .size());
 }
@@ -181,7 +181,7 @@
   // languages are used.
   EXPECT_EQ(0u, FormField::ParseFormFields(fields, LanguageCode(""),
                                            /*is_form_tag=*/true,
-                                           PredictionSource::kDefaultHeuristics,
+                                           PatternSource::kDefault,
                                            /*log_manager=*/nullptr)
                     .size());
 
@@ -196,11 +196,11 @@
     feature_list.InitAndDisableFeature(kAutofillFixFillableFieldTypes);
     // An empty page_language means the language is unknown and patterns of all
     // languages are used.
-    EXPECT_EQ(3u,
-              FormField::ParseFormFields(
-                  fields, LanguageCode(""), /*is_form_tag=*/true,
-                  PredictionSource::kDefaultHeuristics, /*log_manager=*/nullptr)
-                  .size());
+    EXPECT_EQ(3u, FormField::ParseFormFields(fields, LanguageCode(""),
+                                             /*is_form_tag=*/true,
+                                             PatternSource::kDefault,
+                                             /*log_manager=*/nullptr)
+                      .size());
   }
 
   // With the fix, we don't parse the form because search fields are not
@@ -211,13 +211,13 @@
     // An empty page_language means the language is unknown and patterns of all
     // languages are used.
     const FieldCandidatesMap field_candidates_map = FormField::ParseFormFields(
-        fields, LanguageCode(""), /*is_form_tag=*/true,
-        PredictionSource::kDefaultHeuristics, /*log_manager=*/nullptr);
-    EXPECT_EQ(0u,
-              FormField::ParseFormFields(
-                  fields, LanguageCode(""), /*is_form_tag=*/true,
-                  PredictionSource::kDefaultHeuristics, /*log_manager=*/nullptr)
-                  .size());
+        fields, LanguageCode(""), /*is_form_tag=*/true, PatternSource::kDefault,
+        /*log_manager=*/nullptr);
+    EXPECT_EQ(0u, FormField::ParseFormFields(fields, LanguageCode(""),
+                                             /*is_form_tag=*/true,
+                                             PatternSource::kDefault,
+                                             /*log_manager=*/nullptr)
+                      .size());
   }
 }
 
@@ -263,7 +263,7 @@
 
   EXPECT_EQ(1u, FormField::ParseFormFieldsForPromoCodes(
                     fields, LanguageCode(""), /*is_form_tag=*/true,
-                    PredictionSource::kDefaultHeuristics)
+                    PatternSource::kDefault)
                     .size());
 
   // Don't parse other fields.
@@ -274,7 +274,7 @@
   // Still only the promo code field should be parsed.
   EXPECT_EQ(1u, FormField::ParseFormFieldsForPromoCodes(
                     fields, LanguageCode(""), /*is_form_tag=*/true,
-                    PredictionSource::kDefaultHeuristics)
+                    PatternSource::kDefault)
                     .size());
 }
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
index 5ea5141..aa18677 100644
--- a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
+++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.cc
@@ -15,7 +15,7 @@
 std::unique_ptr<FormField> MerchantPromoCodeField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   if (!base::FeatureList::IsEnabled(
           features::kAutofillParseMerchantPromoCodeFields)) {
@@ -24,7 +24,7 @@
 
   AutofillField* field;
   base::span<const MatchPatternRef> merchant_promo_code_patterns =
-      GetMatchPatterns("MERCHANT_PROMO_CODE", page_language, prediction_source);
+      GetMatchPatterns("MERCHANT_PROMO_CODE", page_language, pattern_source);
 
   if (ParseFieldSpecifics(scanner, kMerchantPromoCodeRe,
                           kDefaultMatchParamsWith<MatchFieldType::kNumber,
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h
index a8a9927..1b918ae 100644
--- a/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h
+++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field.h
@@ -25,7 +25,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
   explicit MerchantPromoCodeField(const AutofillField* field);
 
diff --git a/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
index 92835f78..f6c52f20 100644
--- a/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/merchant_promo_code_field_unittest.cc
@@ -31,7 +31,7 @@
       AutofillScanner* scanner,
       const LanguageCode& page_language = LanguageCode("en")) override {
     return MerchantPromoCodeField::Parse(scanner, page_language,
-                                         PredictionSource::kDefaultHeuristics,
+                                         PatternSource::kDefault,
                                          /*log_manager=*/nullptr);
   }
 };
diff --git a/components/autofill/core/browser/form_parsing/name_field.cc b/components/autofill/core/browser/form_parsing/name_field.cc
index e464d13c..858750b 100644
--- a/components/autofill/core/browser/form_parsing/name_field.cc
+++ b/components/autofill/core/browser/form_parsing/name_field.cc
@@ -22,11 +22,10 @@
 // A form field that can parse a full name field.
 class FullNameField : public NameField {
  public:
-  static std::unique_ptr<FullNameField> Parse(
-      AutofillScanner* scanner,
-      const LanguageCode& page_language,
-      PredictionSource prediction_source,
-      LogManager* log_manager);
+  static std::unique_ptr<FullNameField> Parse(AutofillScanner* scanner,
+                                              const LanguageCode& page_language,
+                                              PatternSource pattern_source,
+                                              LogManager* log_manager);
   explicit FullNameField(AutofillField* field);
 
   FullNameField(const FullNameField&) = delete;
@@ -46,12 +45,12 @@
   static std::unique_ptr<FirstTwoLastNamesField> ParseComponentNames(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
   static std::unique_ptr<FirstTwoLastNamesField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   FirstTwoLastNamesField(const FirstTwoLastNamesField&) = delete;
@@ -79,7 +78,7 @@
   static std::unique_ptr<FirstLastNameField> ParseNameSurnameLabelSequence(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   // Tries to match a series of fields with a shared label: The first field
@@ -88,7 +87,7 @@
   static std::unique_ptr<FirstLastNameField> ParseSharedNameLabelSequence(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   // Tries to match a series of fields with patterns that are specific to the
@@ -97,7 +96,7 @@
   static std::unique_ptr<FirstLastNameField> ParseSpecificComponentSequence(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   // Probes the matching strategies defined above. Returns the result of the
@@ -105,7 +104,7 @@
   static std::unique_ptr<FirstLastNameField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language,
-      PredictionSource prediction_source,
+      PatternSource pattern_source,
       LogManager* log_manager);
 
   FirstLastNameField(const FirstLastNameField&) = delete;
@@ -129,7 +128,7 @@
 // static
 std::unique_ptr<FormField> NameField::Parse(AutofillScanner* scanner,
                                             const LanguageCode& page_language,
-                                            PredictionSource prediction_source,
+                                            PatternSource pattern_source,
                                             LogManager* log_manager) {
   if (scanner->IsEnd())
     return nullptr;
@@ -140,14 +139,14 @@
   if (!field && base::FeatureList::IsEnabled(
                     features::kAutofillEnableSupportForMoreStructureInNames)) {
     field = FirstTwoLastNamesField::Parse(scanner, page_language,
-                                          prediction_source, log_manager);
+                                          pattern_source, log_manager);
   }
   if (!field) {
-    field = FirstLastNameField::Parse(scanner, page_language, prediction_source,
+    field = FirstLastNameField::Parse(scanner, page_language, pattern_source,
                                       log_manager);
   }
   if (!field) {
-    field = FullNameField::Parse(scanner, page_language, prediction_source,
+    field = FullNameField::Parse(scanner, page_language, pattern_source,
                                  log_manager);
   }
   return field;
@@ -161,15 +160,14 @@
 std::unique_ptr<FullNameField> FullNameField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   // Exclude e.g. "username" or "nickname" fields.
   scanner->SaveCursor();
   base::span<const MatchPatternRef> name_ignored_patterns =
-      GetMatchPatterns("NAME_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> address_name_ignored_patterns =
-      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language,
-                       prediction_source);
+      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language, pattern_source);
   bool should_ignore =
       ParseField(scanner, kNameIgnoredRe, name_ignored_patterns, nullptr,
                  {log_manager, "kNameIgnoredRe"}) ||
@@ -185,7 +183,7 @@
   AutofillField* field = nullptr;
 
   base::span<const MatchPatternRef> name_patterns =
-      GetMatchPatterns("FULL_NAME", page_language, prediction_source);
+      GetMatchPatterns("FULL_NAME", page_language, pattern_source);
   if (ParseField(scanner, kFullNameRe, name_patterns, &field,
                  {log_manager, "kFullNameRe"}))
     return std::make_unique<FullNameField>(field);
@@ -206,9 +204,9 @@
 std::unique_ptr<FirstTwoLastNamesField> FirstTwoLastNamesField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
-  return ParseComponentNames(scanner, page_language, prediction_source,
+  return ParseComponentNames(scanner, page_language, pattern_source,
                              log_manager);
 }
 
@@ -216,26 +214,25 @@
 std::unique_ptr<FirstTwoLastNamesField>
 FirstTwoLastNamesField::ParseComponentNames(AutofillScanner* scanner,
                                             const LanguageCode& page_language,
-                                            PredictionSource prediction_source,
+                                            PatternSource pattern_source,
                                             LogManager* log_manager) {
   auto v = base::WrapUnique(new FirstTwoLastNamesField());
   scanner->SaveCursor();
 
   base::span<const MatchPatternRef> honorific_prefix_patterns =
-      GetMatchPatterns("HONORIFIC_PREFIX", page_language, prediction_source);
+      GetMatchPatterns("HONORIFIC_PREFIX", page_language, pattern_source);
   base::span<const MatchPatternRef> name_ignored_patterns =
-      GetMatchPatterns("NAME_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> address_name_ignored_patterns =
-      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language,
-                       prediction_source);
+      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> first_name_patterns =
-      GetMatchPatterns("FIRST_NAME", page_language, prediction_source);
+      GetMatchPatterns("FIRST_NAME", page_language, pattern_source);
   base::span<const MatchPatternRef> middle_name_patterns =
-      GetMatchPatterns("MIDDLE_NAME", page_language, prediction_source);
+      GetMatchPatterns("MIDDLE_NAME", page_language, pattern_source);
   base::span<const MatchPatternRef> first_last_name_patterns =
-      GetMatchPatterns("LAST_NAME_FIRST", page_language, prediction_source);
+      GetMatchPatterns("LAST_NAME_FIRST", page_language, pattern_source);
   base::span<const MatchPatternRef> second_last_name_patterns =
-      GetMatchPatterns("LAST_NAME_SECOND", page_language, prediction_source);
+      GetMatchPatterns("LAST_NAME_SECOND", page_language, pattern_source);
 
   // Allow name fields to appear in any order.
   while (!scanner->IsEnd()) {
@@ -324,7 +321,7 @@
 FirstLastNameField::ParseNameSurnameLabelSequence(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   // Some pages have a generic name label that corresponds to a first name
   // followed by a last name label.
@@ -332,18 +329,17 @@
   auto v = base::WrapUnique(new FirstLastNameField());
 
   base::span<const MatchPatternRef> name_specific_patterns =
-      GetMatchPatterns("NAME_GENERIC", page_language, prediction_source);
+      GetMatchPatterns("NAME_GENERIC", page_language, pattern_source);
   base::span<const MatchPatternRef> middle_name_patterns =
-      GetMatchPatterns("MIDDLE_NAME", page_language, prediction_source);
+      GetMatchPatterns("MIDDLE_NAME", page_language, pattern_source);
   base::span<const MatchPatternRef> last_name_patterns =
-      GetMatchPatterns("LAST_NAME", page_language, prediction_source);
+      GetMatchPatterns("LAST_NAME", page_language, pattern_source);
   // Check that the field should not be ignored.
 
   base::span<const MatchPatternRef> name_ignored_patterns =
-      GetMatchPatterns("NAME_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> address_name_ignored_patterns =
-      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language,
-                       prediction_source);
+      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language, pattern_source);
   scanner->SaveCursor();
 
   bool should_ignore =
@@ -377,7 +373,7 @@
 FirstLastNameField::ParseSharedNameLabelSequence(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   // Some pages (e.g. Overstock_comBilling.html, SmithsonianCheckout.html)
   // have the label "Name" followed by two or three text fields.
@@ -386,7 +382,7 @@
 
   AutofillField* next = nullptr;
   base::span<const MatchPatternRef> name_specific_patterns =
-      GetMatchPatterns("NAME_GENERIC", page_language, prediction_source);
+      GetMatchPatterns("NAME_GENERIC", page_language, pattern_source);
 
   if (ParseField(scanner, kNameGenericRe, name_specific_patterns,
                  &v->first_name_, {log_manager, "kNameGenericRe"}) &&
@@ -412,7 +408,7 @@
 FirstLastNameField::ParseSpecificComponentSequence(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   auto v = base::WrapUnique(new FirstLastNameField());
   scanner->SaveCursor();
@@ -430,20 +426,19 @@
   // Allow name fields to appear in any order.
 
   base::span<const MatchPatternRef> honorific_prefix_patterns =
-      GetMatchPatterns("HONORIFIC_PREFIX", page_language, prediction_source);
+      GetMatchPatterns("HONORIFIC_PREFIX", page_language, pattern_source);
   base::span<const MatchPatternRef> name_ignored_patterns =
-      GetMatchPatterns("NAME_IGNORED", page_language, prediction_source);
+      GetMatchPatterns("NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> address_name_ignored_patterns =
-      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language,
-                       prediction_source);
+      GetMatchPatterns("ADDRESS_NAME_IGNORED", page_language, pattern_source);
   base::span<const MatchPatternRef> first_name_patterns =
-      GetMatchPatterns("FIRST_NAME", page_language, prediction_source);
+      GetMatchPatterns("FIRST_NAME", page_language, pattern_source);
   base::span<const MatchPatternRef> middle_name_initial_patterns =
-      GetMatchPatterns("MIDDLE_INITIAL", page_language, prediction_source);
+      GetMatchPatterns("MIDDLE_INITIAL", page_language, pattern_source);
   base::span<const MatchPatternRef> middle_name_patterns =
-      GetMatchPatterns("MIDDLE_NAME", page_language, prediction_source);
+      GetMatchPatterns("MIDDLE_NAME", page_language, pattern_source);
   base::span<const MatchPatternRef> last_name_patterns =
-      GetMatchPatterns("LAST_NAME", page_language, prediction_source);
+      GetMatchPatterns("LAST_NAME", page_language, pattern_source);
 
   while (!scanner->IsEnd()) {
     // Skip over address label fields, which can have misleading names
@@ -524,19 +519,19 @@
 std::unique_ptr<FirstLastNameField> FirstLastNameField::Parse(
     AutofillScanner* scanner,
     const LanguageCode& page_language,
-    PredictionSource prediction_source,
+    PatternSource pattern_source,
     LogManager* log_manager) {
   std::unique_ptr<FirstLastNameField> field = ParseSharedNameLabelSequence(
-      scanner, page_language, prediction_source, log_manager);
+      scanner, page_language, pattern_source, log_manager);
 
   if (!field && base::FeatureList::IsEnabled(
                     features::kAutofillEnableNameSurenameParsing)) {
     field = ParseNameSurnameLabelSequence(scanner, page_language,
-                                          prediction_source, log_manager);
+                                          pattern_source, log_manager);
   }
   if (!field) {
     field = ParseSpecificComponentSequence(scanner, page_language,
-                                           prediction_source, log_manager);
+                                           pattern_source, log_manager);
   }
   return field;
 }
diff --git a/components/autofill/core/browser/form_parsing/name_field.h b/components/autofill/core/browser/form_parsing/name_field.h
index 235e84a8..d3b23f5 100644
--- a/components/autofill/core/browser/form_parsing/name_field.h
+++ b/components/autofill/core/browser/form_parsing/name_field.h
@@ -23,7 +23,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
 
   NameField(const NameField&) = delete;
diff --git a/components/autofill/core/browser/form_parsing/name_field_unittest.cc b/components/autofill/core/browser/form_parsing/name_field_unittest.cc
index 5d3de5c..1a7d4f7 100644
--- a/components/autofill/core/browser/form_parsing/name_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/name_field_unittest.cc
@@ -26,8 +26,7 @@
   std::unique_ptr<FormField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language = LanguageCode("us")) override {
-    return NameField::Parse(scanner, page_language,
-                            PredictionSource::kDefaultHeuristics,
+    return NameField::Parse(scanner, page_language, PatternSource::kDefault,
                             /*log_manager=*/nullptr);
   }
 };
diff --git a/components/autofill/core/browser/form_parsing/phone_field.cc b/components/autofill/core/browser/form_parsing/phone_field.cc
index f31d38c1..a20aa0656 100644
--- a/components/autofill/core/browser/form_parsing/phone_field.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field.cc
@@ -211,7 +211,7 @@
 // static
 std::unique_ptr<FormField> PhoneField::Parse(AutofillScanner* scanner,
                                              const LanguageCode& page_language,
-                                             PredictionSource prediction_source,
+                                             PatternSource pattern_source,
                                              LogManager* log_manager) {
   if (scanner->IsEnd())
     return nullptr;
@@ -246,7 +246,7 @@
               {log_manager, GetRegExpName(kPhoneFieldGrammars[i].regex)},
               is_country_code_field,
               GetJSONFieldType(kPhoneFieldGrammars[i].regex), page_language,
-              prediction_source)) {
+              pattern_source)) {
         break;
       }
       if (kPhoneFieldGrammars[i].max_size &&
@@ -293,12 +293,12 @@
                          &phone_field->parsed_phone_fields_[FIELD_SUFFIX],
                          {log_manager, "kPhoneSuffixRe"},
                          /*is_country_code_field=*/false, "PHONE_SUFFIX",
-                         page_language, prediction_source)) {
+                         page_language, pattern_source)) {
       ParsePhoneField(scanner, kPhoneSuffixSeparatorRe,
                       &phone_field->parsed_phone_fields_[FIELD_SUFFIX],
                       {log_manager, "kPhoneSuffixSeparatorRe"},
                       /*is_country_code_field=*/false, "PHONE_SUFFIX_SEPARATOR",
-                      page_language, prediction_source);
+                      page_language, pattern_source);
     }
   }
 
@@ -309,7 +309,7 @@
                   &phone_field->parsed_phone_fields_[FIELD_EXTENSION],
                   {log_manager, "kPhoneExtensionRe"},
                   /*is_country_code_field=*/false, "PHONE_EXTENSION",
-                  page_language, prediction_source);
+                  page_language, pattern_source);
 
   return std::move(phone_field);
 }
@@ -466,7 +466,7 @@
                                  const bool is_country_code_field,
                                  const std::string& json_field_type,
                                  const LanguageCode& page_language,
-                                 PredictionSource prediction_source) {
+                                 PatternSource pattern_source) {
   MatchParams match_type = kDefaultMatchParamsWith<MatchFieldType::kTelephone,
                                                    MatchFieldType::kNumber>;
   // Include the selection boxes too for the matching of the phone country code.
@@ -477,7 +477,7 @@
   }
 
   base::span<const MatchPatternRef> patterns =
-      GetMatchPatterns(json_field_type, page_language, prediction_source);
+      GetMatchPatterns(json_field_type, page_language, pattern_source);
 
   return ParseFieldSpecifics(scanner, regex, match_type, patterns, field,
                              logging);
diff --git a/components/autofill/core/browser/form_parsing/phone_field.h b/components/autofill/core/browser/form_parsing/phone_field.h
index 96ea4e5b..1dfc0d3 100644
--- a/components/autofill/core/browser/form_parsing/phone_field.h
+++ b/components/autofill/core/browser/form_parsing/phone_field.h
@@ -36,7 +36,7 @@
 
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
 
 #if defined(UNIT_TEST)
@@ -109,7 +109,7 @@
                               const bool is_country_code_field,
                               const std::string& json_field_type,
                               const LanguageCode& page_language,
-                              PredictionSource prediction_source);
+                              PatternSource pattern_source);
 
   // Returns true if |scanner| points to a <select> field that appears to be the
   // phone country code by looking at its option contents.
diff --git a/components/autofill/core/browser/form_parsing/phone_field_unittest.cc b/components/autofill/core/browser/form_parsing/phone_field_unittest.cc
index d5b4ec1..19ae2bb 100644
--- a/components/autofill/core/browser/form_parsing/phone_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field_unittest.cc
@@ -44,9 +44,9 @@
   static std::unique_ptr<PhoneField> Parse(AutofillScanner* scanner) {
     // An empty page_language means the language is unknown and patterns of all
     // languages are used.
-    std::unique_ptr<FormField> field = PhoneField::Parse(
-        scanner, LanguageCode(""), PredictionSource::kDefaultHeuristics,
-        /*log_manager=*/nullptr);
+    std::unique_ptr<FormField> field =
+        PhoneField::Parse(scanner, LanguageCode(""), PatternSource::kDefault,
+                          /*log_manager=*/nullptr);
     return std::unique_ptr<PhoneField>(
         static_cast<PhoneField*>(field.release()));
   }
diff --git a/components/autofill/core/browser/form_parsing/price_field.cc b/components/autofill/core/browser/form_parsing/price_field.cc
index 8806a9c..a91e7a3 100644
--- a/components/autofill/core/browser/form_parsing/price_field.cc
+++ b/components/autofill/core/browser/form_parsing/price_field.cc
@@ -14,11 +14,11 @@
 // static
 std::unique_ptr<FormField> PriceField::Parse(AutofillScanner* scanner,
                                              const LanguageCode& page_language,
-                                             PredictionSource prediction_source,
+                                             PatternSource pattern_source,
                                              LogManager* log_manager) {
   AutofillField* field;
   base::span<const MatchPatternRef> price_patterns =
-      GetMatchPatterns("PRICE", page_language, prediction_source);
+      GetMatchPatterns("PRICE", page_language, pattern_source);
 
   if (ParseFieldSpecifics(
           scanner, kPriceRe,
diff --git a/components/autofill/core/browser/form_parsing/price_field.h b/components/autofill/core/browser/form_parsing/price_field.h
index bdb9a2ed0..e550b75 100644
--- a/components/autofill/core/browser/form_parsing/price_field.h
+++ b/components/autofill/core/browser/form_parsing/price_field.h
@@ -25,7 +25,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
   explicit PriceField(const AutofillField* field);
 
diff --git a/components/autofill/core/browser/form_parsing/price_field_unittest.cc b/components/autofill/core/browser/form_parsing/price_field_unittest.cc
index bad129e..db41dc7d 100644
--- a/components/autofill/core/browser/form_parsing/price_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/price_field_unittest.cc
@@ -20,8 +20,7 @@
   std::unique_ptr<FormField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language = LanguageCode("en")) override {
-    return PriceField::Parse(scanner, page_language,
-                             PredictionSource::kDefaultHeuristics,
+    return PriceField::Parse(scanner, page_language, PatternSource::kDefault,
                              /*log_manager=*/nullptr);
   }
 };
diff --git a/components/autofill/core/browser/form_parsing/regex_patterns.cc b/components/autofill/core/browser/form_parsing/regex_patterns.cc
index fad3e38..540dc23 100644
--- a/components/autofill/core/browser/form_parsing/regex_patterns.cc
+++ b/components/autofill/core/browser/form_parsing/regex_patterns.cc
@@ -24,29 +24,29 @@
 base::span<const MatchPatternRef> GetMatchPatterns(
     base::StringPiece name,
     base::StringPiece language_code,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   auto* it = kPatternMap.find(std::make_pair(name, language_code));
   if (!language_code.empty() && it == kPatternMap.end())
     it = kPatternMap.find(std::make_pair(name, ""));
   CHECK(it != kPatternMap.end());
 #if BUILDFLAG(USE_INTERNAL_AUTOFILL_HEADERS)
-  switch (prediction_source) {
-    case PredictionSource::kDefaultHeuristics:
+  switch (pattern_source) {
+    case PatternSource::kDefault:
       return it->second[0];
-    case PredictionSource::kExperimentalHeuristics:
+    case PatternSource::kExperimental:
       return it->second[1];
-    case PredictionSource::kNextGenHeuristics:
+    case PatternSource::kNextGen:
       return it->second[2];
-    case PredictionSource::kFallbackHeuristics:
+    case PatternSource::kLegacy:
       return it->second[3];
   }
 #else
-  switch (prediction_source) {
-    case PredictionSource::kDefaultHeuristics:
+  switch (pattern_source) {
+    case PatternSource::kDefault:
       return it->second[0];
-    case PredictionSource::kExperimentalHeuristics:
-    case PredictionSource::kNextGenHeuristics:
-    case PredictionSource::kFallbackHeuristics:
+    case PatternSource::kExperimental:
+    case PatternSource::kNextGen:
+    case PatternSource::kLegacy:
       break;
   }
 #endif
@@ -59,18 +59,17 @@
 base::span<const MatchPatternRef> GetMatchPatterns(
     base::StringPiece name,
     absl::optional<LanguageCode> language_code,
-    PredictionSource prediction_source) {
-  return language_code
-             ? GetMatchPatterns(name, **language_code, prediction_source)
-             : GetMatchPatterns(name, "", prediction_source);
+    PatternSource pattern_source) {
+  return language_code ? GetMatchPatterns(name, **language_code, pattern_source)
+                       : GetMatchPatterns(name, "", pattern_source);
 }
 
 base::span<const MatchPatternRef> GetMatchPatterns(
     ServerFieldType type,
     absl::optional<LanguageCode> language_code,
-    PredictionSource prediction_source) {
+    PatternSource pattern_source) {
   return GetMatchPatterns(FieldTypeToStringPiece(type), language_code,
-                          prediction_source);
+                          pattern_source);
 }
 
 // The dereferencing operator implements the distinction between ordinary and
diff --git a/components/autofill/core/browser/form_parsing/regex_patterns.h b/components/autofill/core/browser/form_parsing/regex_patterns.h
index f208510..a20658ab 100644
--- a/components/autofill/core/browser/form_parsing/regex_patterns.h
+++ b/components/autofill/core/browser/form_parsing/regex_patterns.h
@@ -9,7 +9,6 @@
 #include "base/strings/string_piece.h"
 #include "base/types/strong_alias.h"
 #include "components/autofill/core/browser/field_types.h"
-#include "components/autofill/core/browser/form_parsing/field_candidates.h"
 #include "components/autofill/core/common/language_code.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -69,6 +68,16 @@
   UnderlyingType value_;
 };
 
+// The pattern  source identifies the JSON file providing the set of parsing
+// patterns.
+enum class PatternSource {
+  kDefault,
+  kExperimental,
+  kNextGen,
+  kLegacy,
+  kMaxValue = kLegacy
+};
+
 // Looks up the patterns for the given name and language.
 // The name is typically a field type.
 //
@@ -82,12 +91,12 @@
 base::span<const MatchPatternRef> GetMatchPatterns(
     base::StringPiece name,
     absl::optional<LanguageCode> language,
-    PredictionSource prediction_source);
+    PatternSource pattern_source);
 
 base::span<const MatchPatternRef> GetMatchPatterns(
     ServerFieldType type,
     absl::optional<LanguageCode> language,
-    PredictionSource prediction_source);
+    PatternSource pattern_source);
 
 }  // namespace autofill
 
diff --git a/components/autofill/core/browser/form_parsing/regex_patterns_unittest.cc b/components/autofill/core/browser/form_parsing/regex_patterns_unittest.cc
index d6f5cc6926..6ae337d3 100644
--- a/components/autofill/core/browser/form_parsing/regex_patterns_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/regex_patterns_unittest.cc
@@ -122,19 +122,19 @@
   // The expected patterns are the patterns of all languages for `kSomeName`.
   std::vector<MatchPatternRef> expected;
   for (const std::string& lang : kLanguagesOfPattern) {
-    const auto& patterns = GetMatchPatterns(
-        kSomeName, LanguageCode(lang), PredictionSource::kDefaultHeuristics);
+    const auto& patterns = GetMatchPatterns(kSomeName, LanguageCode(lang),
+                                            PatternSource::kDefault);
     expected.insert(expected.end(), patterns.begin(), patterns.end());
   }
   base::EraseIf(expected,
                 [](auto p) { return test_api(p).is_supplementary(); });
 
-  EXPECT_THAT(GetMatchPatterns(kSomeName, absl::nullopt,
-                               PredictionSource::kDefaultHeuristics),
-              UnorderedElementsAreArray(expected));
-  EXPECT_THAT(GetMatchPatterns(kSomeName, absl::nullopt,
-                               PredictionSource::kDefaultHeuristics),
-              Each(Not(IsSupplementary)));
+  EXPECT_THAT(
+      GetMatchPatterns(kSomeName, absl::nullopt, PatternSource::kDefault),
+      UnorderedElementsAreArray(expected));
+  EXPECT_THAT(
+      GetMatchPatterns(kSomeName, absl::nullopt, PatternSource::kDefault),
+      Each(Not(IsSupplementary)));
 }
 
 // Tests that for a given pattern name, if the language doesn't isn't known we
@@ -142,11 +142,10 @@
 TEST_F(RegexPatternsTest, FallbackToPseudoLanguageIfLanguageDoesNotExist) {
   const std::string kSomeName = "ADDRESS_LINE_1";
   const LanguageCode kNonexistingLanguage("foo");
-  EXPECT_THAT(
-      GetMatchPatterns(kSomeName, kNonexistingLanguage,
-                       PredictionSource::kDefaultHeuristics),
-      ElementsAreArray(GetMatchPatterns(kSomeName, absl::nullopt,
-                                        PredictionSource::kDefaultHeuristics)));
+  EXPECT_THAT(GetMatchPatterns(kSomeName, kNonexistingLanguage,
+                               PatternSource::kDefault),
+              ElementsAreArray(GetMatchPatterns(kSomeName, absl::nullopt,
+                                                PatternSource::kDefault)));
 }
 
 // Tests that for a given pattern name, the non-English languages are
@@ -154,10 +153,10 @@
 TEST_F(RegexPatternsTest,
        EnglishPatternsAreAddedToOtherLanguagesAsSupplementaryPatterns) {
   const std::string kSomeName = "ADDRESS_LINE_1";
-  auto de_patterns = GetMatchPatterns(kSomeName, LanguageCode("de"),
-                                      PredictionSource::kDefaultHeuristics);
-  auto en_patterns = GetMatchPatterns(kSomeName, LanguageCode("en"),
-                                      PredictionSource::kDefaultHeuristics);
+  auto de_patterns =
+      GetMatchPatterns(kSomeName, LanguageCode("de"), PatternSource::kDefault);
+  auto en_patterns =
+      GetMatchPatterns(kSomeName, LanguageCode("en"), PatternSource::kDefault);
   ASSERT_FALSE(de_patterns.empty());
   ASSERT_FALSE(en_patterns.empty());
 
@@ -180,7 +179,7 @@
 struct PatternTestCase {
   // The set of patterns. In non-branded builds, only the default set is
   // supported.
-  PredictionSource prediction_source = PredictionSource::kDefaultHeuristics;
+  PatternSource pattern_source = PatternSource::kDefault;
   // Reference to the pattern name in the resources/regex_patterns.json file.
   const char* pattern_name;
   // Language selector for the pattern, refers to the detected language of a
@@ -209,8 +208,8 @@
     EXPECT_THAT(sample,
                 MatchesAny(GetMatchPatterns(test_case.pattern_name,
                                             LanguageCode(test_case.language),
-                                            test_case.prediction_source)))
-        << "prediction_source=" << static_cast<int>(test_case.prediction_source)
+                                            test_case.pattern_source)))
+        << "pattern_source=" << static_cast<int>(test_case.pattern_source)
         << ","
         << "pattern_name=" << test_case.pattern_name << ","
         << "language=" << test_case.language;
@@ -220,7 +219,7 @@
     EXPECT_THAT(sample,
                 Not(MatchesAny(GetMatchPatterns(
                     test_case.pattern_name, LanguageCode(test_case.language),
-                    test_case.prediction_source))))
+                    test_case.pattern_source))))
         << "pattern_name=" << test_case.pattern_name << ","
         << "language=" << test_case.language;
   }
@@ -232,39 +231,38 @@
     testing::Values(
 #if !BUILDFLAG(USE_INTERNAL_AUTOFILL_HEADERS)
         PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
+            .pattern_source = PatternSource::kDefault,
             .pattern_name = "PATTERN_SOURCE_DUMMY",
             .language = "en",
             .positive_samples = {"legacy"},
             .negative_samples = {"default", "experimental", "nextgen"}},
 #else
         PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
+            .pattern_source = PatternSource::kDefault,
             .pattern_name = "PATTERN_SOURCE_DUMMY",
             .language = "en",
             .positive_samples = {"default"},
             .negative_samples = {"legacy", "experimental", "nextgen"}},
+        PatternTestCase{.pattern_source = PatternSource::kExperimental,
+                        .pattern_name = "PATTERN_SOURCE_DUMMY",
+                        .language = "en",
+                        .positive_samples = {"experimental"},
+                        .negative_samples = {"default", "legacy", "nextgen"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kExperimentalHeuristics,
-            .pattern_name = "PATTERN_SOURCE_DUMMY",
-            .language = "en",
-            .positive_samples = {"experimental"},
-            .negative_samples = {"default", "legacy", "nextgen"}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kNextGenHeuristics,
+            .pattern_source = PatternSource::kNextGen,
             .pattern_name = "PATTERN_SOURCE_DUMMY",
             .language = "en",
             .positive_samples = {"nextgen"},
             .negative_samples = {"default", "legacy", "experimental"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kFallbackHeuristics,
+            .pattern_source = PatternSource::kLegacy,
             .pattern_name = "PATTERN_SOURCE_DUMMY",
             .language = "en",
             .positive_samples = {"legacy"},
             .negative_samples = {"default", "experimental", "nextgen"}},
 #endif
         PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
+            .pattern_source = PatternSource::kDefault,
             .pattern_name = "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -289,7 +287,7 @@
                  "Expiration Date MM - YYYY", "Expiration Date MM-YYYY",
                  "expiration date yyyy", "Exp Date     (MM / YYYY)"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
+            .pattern_source = PatternSource::kDefault,
             .pattern_name = "CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -314,29 +312,27 @@
                  "Expiration Date MM / YY", "Expiration Date MM/YY",
                  "Expiration Date MM - YY", "Expiration Date MM-YY",
                  "expiration date yy", "Exp Date     (MM / YY)"}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "en",
-            .positive_samples = {"Zip code", "postal code"},
-            .negative_samples =
-                {// Not matching for "en" language:
-                 "postleitzahl",
-                 // Not referring to a ZIP code:
-                 "Supported file formats: .docx, .rar, .zip."}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kDefaultHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "de",
-            .positive_samples =
-                {// Inherited from "en":
-                 "Zip code", "postal code",
-                 // Specifically added for "de":
-                 "postleitzahl"}}
+        PatternTestCase{.pattern_source = PatternSource::kDefault,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "en",
+                        .positive_samples = {"Zip code", "postal code"},
+                        .negative_samples =
+                            {// Not matching for "en" language:
+                             "postleitzahl",
+                             // Not referring to a ZIP code:
+                             "Supported file formats: .docx, .rar, .zip."}},
+        PatternTestCase{.pattern_source = PatternSource::kDefault,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "de",
+                        .positive_samples =
+                            {// Inherited from "en":
+                             "Zip code", "postal code",
+                             // Specifically added for "de":
+                             "postleitzahl"}}
 #if BUILDFLAG(USE_INTERNAL_AUTOFILL_HEADERS)
         ,
         PatternTestCase{
-            .prediction_source = PredictionSource::kExperimentalHeuristics,
+            .pattern_source = PatternSource::kExperimental,
             .pattern_name = "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -361,7 +357,7 @@
                  "Expiration Date MM - YYYY", "Expiration Date MM-YYYY",
                  "expiration date yyyy", "Exp Date     (MM / YYYY)"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kExperimentalHeuristics,
+            .pattern_source = PatternSource::kExperimental,
             .pattern_name = "CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -386,27 +382,25 @@
                  "Expiration Date MM / YY", "Expiration Date MM/YY",
                  "Expiration Date MM - YY", "Expiration Date MM-YY",
                  "expiration date yy", "Exp Date     (MM / YY)"}},
+        PatternTestCase{.pattern_source = PatternSource::kExperimental,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "en",
+                        .positive_samples = {"Zip code", "postal code"},
+                        .negative_samples =
+                            {// Not matching for "en" language:
+                             "postleitzahl",
+                             // Not referring to a ZIP code:
+                             "Supported file formats: .docx, .rar, .zip."}},
+        PatternTestCase{.pattern_source = PatternSource::kExperimental,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "de",
+                        .positive_samples =
+                            {// Inherited from "en":
+                             "Zip code", "postal code",
+                             // Specifically added for "de":
+                             "postleitzahl"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kExperimentalHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "en",
-            .positive_samples = {"Zip code", "postal code"},
-            .negative_samples =
-                {// Not matching for "en" language:
-                 "postleitzahl",
-                 // Not referring to a ZIP code:
-                 "Supported file formats: .docx, .rar, .zip."}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kExperimentalHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "de",
-            .positive_samples =
-                {// Inherited from "en":
-                 "Zip code", "postal code",
-                 // Specifically added for "de":
-                 "postleitzahl"}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kNextGenHeuristics,
+            .pattern_source = PatternSource::kNextGen,
             .pattern_name = "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -431,7 +425,7 @@
                  "Expiration Date MM - YYYY", "Expiration Date MM-YYYY",
                  "expiration date yyyy", "Exp Date     (MM / YYYY)"}},
         PatternTestCase{
-            .prediction_source = PredictionSource::kNextGenHeuristics,
+            .pattern_source = PatternSource::kNextGen,
             .pattern_name = "CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR",
             .language = "en",
             .positive_samples =
@@ -456,25 +450,23 @@
                  "Expiration Date MM / YY", "Expiration Date MM/YY",
                  "Expiration Date MM - YY", "Expiration Date MM-YY",
                  "expiration date yy", "Exp Date     (MM / YY)"}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kNextGenHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "en",
-            .positive_samples = {"Zip code", "postal code"},
-            .negative_samples =
-                {// Not matching for "en" language:
-                 "postleitzahl",
-                 // Not referring to a ZIP code:
-                 "Supported file formats: .docx, .rar, .zip."}},
-        PatternTestCase{
-            .prediction_source = PredictionSource::kNextGenHeuristics,
-            .pattern_name = "ZIP_CODE",
-            .language = "de",
-            .positive_samples =
-                {// Inherited from "en":
-                 "Zip code", "postal code",
-                 // Specifically added for "de":
-                 "postleitzahl"}}
+        PatternTestCase{.pattern_source = PatternSource::kNextGen,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "en",
+                        .positive_samples = {"Zip code", "postal code"},
+                        .negative_samples =
+                            {// Not matching for "en" language:
+                             "postleitzahl",
+                             // Not referring to a ZIP code:
+                             "Supported file formats: .docx, .rar, .zip."}},
+        PatternTestCase{.pattern_source = PatternSource::kNextGen,
+                        .pattern_name = "ZIP_CODE",
+                        .language = "de",
+                        .positive_samples =
+                            {// Inherited from "en":
+                             "Zip code", "postal code",
+                             // Specifically added for "de":
+                             "postleitzahl"}}
 #endif
         ));
 
diff --git a/components/autofill/core/browser/form_parsing/search_field.cc b/components/autofill/core/browser/form_parsing/search_field.cc
index a2d9e42..26867e2f 100644
--- a/components/autofill/core/browser/form_parsing/search_field.cc
+++ b/components/autofill/core/browser/form_parsing/search_field.cc
@@ -12,14 +12,13 @@
 namespace autofill {
 
 // static
-std::unique_ptr<FormField> SearchField::Parse(
-    AutofillScanner* scanner,
-    const LanguageCode& page_language,
-    PredictionSource prediction_source,
-    LogManager* log_manager) {
+std::unique_ptr<FormField> SearchField::Parse(AutofillScanner* scanner,
+                                              const LanguageCode& page_language,
+                                              PatternSource pattern_source,
+                                              LogManager* log_manager) {
   AutofillField* field;
   base::span<const MatchPatternRef> patterns =
-      GetMatchPatterns(SEARCH_TERM, page_language, prediction_source);
+      GetMatchPatterns(SEARCH_TERM, page_language, pattern_source);
 
   if (ParseFieldSpecifics(scanner, kSearchTermRe,
                           kDefaultMatchParamsWith<MatchFieldType::kSearch,
diff --git a/components/autofill/core/browser/form_parsing/search_field.h b/components/autofill/core/browser/form_parsing/search_field.h
index b6af21cd..91b7766 100644
--- a/components/autofill/core/browser/form_parsing/search_field.h
+++ b/components/autofill/core/browser/form_parsing/search_field.h
@@ -25,7 +25,7 @@
  public:
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
   SearchField(const AutofillField* field);
 
diff --git a/components/autofill/core/browser/form_parsing/search_field_unittest.cc b/components/autofill/core/browser/form_parsing/search_field_unittest.cc
index 02320258..71f750b 100644
--- a/components/autofill/core/browser/form_parsing/search_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/search_field_unittest.cc
@@ -21,8 +21,7 @@
   std::unique_ptr<FormField> Parse(
       AutofillScanner* scanner,
       const LanguageCode& page_language = LanguageCode("en")) override {
-    return SearchField::Parse(scanner, page_language,
-                              PredictionSource::kDefaultHeuristics,
+    return SearchField::Parse(scanner, page_language, PatternSource::kDefault,
                               /*log_manager=*/nullptr);
   }
 };
diff --git a/components/autofill/core/browser/form_parsing/travel_field.cc b/components/autofill/core/browser/form_parsing/travel_field.cc
index 85eaf6c..c6a696b 100644
--- a/components/autofill/core/browser/form_parsing/travel_field.cc
+++ b/components/autofill/core/browser/form_parsing/travel_field.cc
@@ -15,22 +15,21 @@
 TravelField::~TravelField() = default;
 
 // static
-std::unique_ptr<FormField> TravelField::Parse(
-    AutofillScanner* scanner,
-    const LanguageCode& page_language,
-    PredictionSource prediction_source,
-    LogManager* log_manager) {
+std::unique_ptr<FormField> TravelField::Parse(AutofillScanner* scanner,
+                                              const LanguageCode& page_language,
+                                              PatternSource pattern_source,
+                                              LogManager* log_manager) {
   if (!scanner || scanner->IsEnd())
     return nullptr;
 
   base::span<const MatchPatternRef> passport_patterns =
-      GetMatchPatterns("PASSPORT", page_language, prediction_source);
+      GetMatchPatterns("PASSPORT", page_language, pattern_source);
   base::span<const MatchPatternRef> travel_origin_patterns =
-      GetMatchPatterns("TRAVEL_ORIGIN", page_language, prediction_source);
+      GetMatchPatterns("TRAVEL_ORIGIN", page_language, pattern_source);
   base::span<const MatchPatternRef> travel_destination_patterns =
-      GetMatchPatterns("TRAVEL_DESTINATION", page_language, prediction_source);
+      GetMatchPatterns("TRAVEL_DESTINATION", page_language, pattern_source);
   base::span<const MatchPatternRef> flight_patterns =
-      GetMatchPatterns("FLIGHT", page_language, prediction_source);
+      GetMatchPatterns("FLIGHT", page_language, pattern_source);
 
   auto travel_field = std::make_unique<TravelField>();
   if (ParseField(scanner, kPassportRe, passport_patterns,
diff --git a/components/autofill/core/browser/form_parsing/travel_field.h b/components/autofill/core/browser/form_parsing/travel_field.h
index e4800e8d..17784dcc 100644
--- a/components/autofill/core/browser/form_parsing/travel_field.h
+++ b/components/autofill/core/browser/form_parsing/travel_field.h
@@ -21,7 +21,7 @@
 
   static std::unique_ptr<FormField> Parse(AutofillScanner* scanner,
                                           const LanguageCode& page_language,
-                                          PredictionSource prediction_source,
+                                          PatternSource pattern_source,
                                           LogManager* log_manager);
 
  protected:
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 52a66cbd..ad60cbf 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -689,13 +689,10 @@
   SCOPED_UMA_HISTOGRAM_TIMER("Autofill.Timing.DetermineHeuristicTypes");
 
   ParseFieldTypesFromAutocompleteAttributes();
-  ParseFieldTypesWithPatterns(PredictionSource::kDefaultHeuristics,
-                              log_manager);
+  ParseFieldTypesWithPatterns(PatternSource::kDefault, log_manager);
 #if BUILDFLAG(USE_INTERNAL_AUTOFILL_HEADERS)
-  ParseFieldTypesWithPatterns(PredictionSource::kExperimentalHeuristics,
-                              log_manager);
-  ParseFieldTypesWithPatterns(PredictionSource::kNextGenHeuristics,
-                              log_manager);
+  ParseFieldTypesWithPatterns(PatternSource::kExperimental, log_manager);
+  ParseFieldTypesWithPatterns(PatternSource::kNextGen, log_manager);
 #endif
 
   UpdateAutofillCount();
@@ -1188,9 +1185,8 @@
       if (!only_server_and_autofill_state) {
         // Transfer attributes of the cached AutofillField to the newly created
         // AutofillField.
-        for (int i = 0; i <= static_cast<int>(PredictionSource::kMaxValue);
-             ++i) {
-          PredictionSource s = static_cast<PredictionSource>(i);
+        for (int i = 0; i <= static_cast<int>(PatternSource::kMaxValue); ++i) {
+          PatternSource s = static_cast<PatternSource>(i);
           field->set_heuristic_type(s, cached_field->heuristic_type(s));
         }
         field->SetHtmlType(cached_field->html_type(),
@@ -1656,17 +1652,16 @@
   was_parsed_for_autocomplete_attributes_ = true;
 }
 
-void FormStructure::ParseFieldTypesWithPatterns(
-    PredictionSource prediction_source,
-    LogManager* log_manager) {
+void FormStructure::ParseFieldTypesWithPatterns(PatternSource pattern_source,
+                                                LogManager* log_manager) {
   FieldCandidatesMap field_type_map;
   if (ShouldRunHeuristics()) {
-    field_type_map = FormField::ParseFormFields(fields_, current_page_language_,
-                                                is_form_tag_, prediction_source,
-                                                log_manager);
+    field_type_map =
+        FormField::ParseFormFields(fields_, current_page_language_,
+                                   is_form_tag_, pattern_source, log_manager);
   } else if (ShouldRunPromoCodeHeuristics()) {
     field_type_map = FormField::ParseFormFieldsForPromoCodes(
-        fields_, current_page_language_, is_form_tag_, prediction_source,
+        fields_, current_page_language_, is_form_tag_, pattern_source,
         log_manager);
   }
   if (field_type_map.empty())
@@ -1677,8 +1672,7 @@
     if (iter == field_type_map.end())
       continue;
     const FieldCandidates& candidates = iter->second;
-    field->set_heuristic_type(prediction_source,
-                              candidates.BestHeuristicType());
+    field->set_heuristic_type(pattern_source, candidates.BestHeuristicType());
   }
 }
 
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 23fcb0b..51b21dd8 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -232,7 +232,7 @@
   void ParseFieldTypesFromAutocompleteAttributes();
 
   // Classifies each field in |fields_| using the regular expressions.
-  void ParseFieldTypesWithPatterns(PredictionSource prediction_source,
+  void ParseFieldTypesWithPatterns(PatternSource pattern_source,
                                    LogManager* log_manager);
 
   // Returns the values that can be filled into the form structure for the
@@ -376,8 +376,7 @@
   void set_overall_field_type_for_testing(size_t field_index,
                                           ServerFieldType type) {
     if (field_index < fields_.size() && type > 0 && type < MAX_VALID_FIELD_TYPE)
-      fields_[field_index]->set_heuristic_type(
-          PredictionSource::kDefaultHeuristics, type);
+      fields_[field_index]->set_heuristic_type(PatternSource::kDefault, type);
   }
   // Set the server field type for |fields_[field_index]| to |type| for testing
   // purposes.
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
index 04188f8..5299935 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
@@ -30,44 +30,41 @@
 MockAutofillClient::~MockAutofillClient() = default;
 
 AutofillMetricsBaseTest::AutofillMetricsBaseTest(bool is_in_any_main_frame)
-    : is_in_any_main_frame_(is_in_any_main_frame) {
-  test_ukm_recorder_ = autofill_client_.GetTestUkmRecorder();
-}
+    : is_in_any_main_frame_(is_in_any_main_frame) {}
 
 AutofillMetricsBaseTest::~AutofillMetricsBaseTest() = default;
 
 void AutofillMetricsBaseTest::SetUp() {
-  autofill_client_.SetPrefs(test::PrefServiceForTesting());
+  autofill_client_ = std::make_unique<MockAutofillClient>();
+  autofill_client_->SetPrefs(test::PrefServiceForTesting());
+  test_ukm_recorder_ = autofill_client_->GetTestUkmRecorder();
 
-  personal_data_ = std::make_unique<TestPersonalDataManager>();
-  personal_data_->set_auto_accept_address_imports_for_testing(true);
-  personal_data_->SetPrefService(autofill_client_.GetPrefs());
-  personal_data_->OnSyncServiceInitialized(&sync_service_);
+  personal_data().set_auto_accept_address_imports_for_testing(true);
+  personal_data().SetPrefService(autofill_client_->GetPrefs());
+  personal_data().OnSyncServiceInitialized(&sync_service_);
 
   autofill_driver_ = std::make_unique<TestAutofillDriver>();
   autofill_driver_->SetIsInAnyMainFrame(is_in_any_main_frame_);
 
   payments::TestPaymentsClient* payments_client =
       new payments::TestPaymentsClient(autofill_driver_->GetURLLoaderFactory(),
-                                       autofill_client_.GetIdentityManager(),
-                                       personal_data_.get());
-  autofill_client_.set_test_payments_client(
+                                       autofill_client_->GetIdentityManager(),
+                                       &personal_data());
+  autofill_client_->set_test_payments_client(
       std::unique_ptr<payments::TestPaymentsClient>(payments_client));
-  TestCreditCardSaveManager* credit_card_save_manager =
-      new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_,
-                                    payments_client, personal_data_.get());
-  TestFormDataImporter* test_form_data_importer = new TestFormDataImporter(
-      &autofill_client_, payments_client,
-      std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager),
-      personal_data_.get(), "en-US");
-  autofill_client_.set_test_form_data_importer(
-      std::unique_ptr<TestFormDataImporter>(test_form_data_importer));
-  autofill_client_.set_autofill_offer_manager(
+  auto credit_card_save_manager = std::make_unique<TestCreditCardSaveManager>(
+      autofill_driver_.get(), autofill_client_.get(), payments_client,
+      &personal_data());
+  autofill_client_->set_test_form_data_importer(
+      std::make_unique<TestFormDataImporter>(
+          autofill_client_.get(), payments_client,
+          std::move(credit_card_save_manager), &personal_data(), "en-US"));
+  autofill_client_->set_autofill_offer_manager(
       std::make_unique<AutofillOfferManager>(
-          personal_data_.get(), /*coupon_service_delegate=*/nullptr));
+          &personal_data(), /*coupon_service_delegate=*/nullptr));
 
   auto browser_autofill_manager = std::make_unique<TestBrowserAutofillManager>(
-      autofill_driver_.get(), &autofill_client_, personal_data_.get());
+      autofill_driver_.get(), autofill_client_.get());
   autofill_driver_->set_autofill_manager(std::move(browser_autofill_manager));
 
   auto external_delegate = std::make_unique<AutofillExternalDelegate>(
@@ -80,7 +77,7 @@
       .GetCreditCardAccessManager()
       ->set_fido_authenticator_for_testing(
           std::make_unique<TestCreditCardFIDOAuthenticator>(
-              autofill_driver_.get(), &autofill_client_));
+              autofill_driver_.get(), autofill_client_.get()));
 #endif
 
   // Initialize the TestPersonalDataManager with some default data.
@@ -88,23 +85,19 @@
 }
 
 void AutofillMetricsBaseTest::TearDown() {
-  // Order of destruction is important as BrowserAutofillManager and
-  // AutofillOfferManager rely on PersonalDataManager to be around when they
-  // gets destroyed.
-  autofill_driver_.reset();
-  autofill_client_.set_autofill_offer_manager(nullptr);
-  personal_data_.reset();
   test_ukm_recorder_->Purge();
+  autofill_driver_.reset();
+  autofill_client_.reset();
 }
 
 void AutofillMetricsBaseTest::PurgeUKM() {
   autofill_manager().Reset();
   test_ukm_recorder_->Purge();
-  autofill_client_.InitializeUKMSources();
+  autofill_client_->InitializeUKMSources();
 }
 
 void AutofillMetricsBaseTest::CreateAmbiguousProfiles() {
-  personal_data_->ClearProfiles();
+  personal_data().ClearProfiles();
   CreateTestAutofillProfiles();
 
   AutofillProfile profile;
@@ -112,24 +105,24 @@
                        "Company", "123 Main St.", "unit 7", "Springfield",
                        "Texas", "79401", "US", "2345678901");
   profile.set_guid("00000000-0000-0000-0000-000000000003");
-  personal_data_->AddProfile(profile);
-  personal_data_->Refresh();
+  personal_data().AddProfile(profile);
+  personal_data().Refresh();
 }
 
 void AutofillMetricsBaseTest::RecreateProfile(bool is_server) {
-  personal_data_->ClearProfiles();
+  personal_data().ClearProfiles();
 
   if (is_server) {
     AutofillProfile profile(AutofillProfile::SERVER_PROFILE, "server_id");
     SetProfileTestData(&profile);
-    personal_data_->AddProfile(profile);
+    personal_data().AddProfile(profile);
   } else {
     AutofillProfile profile;
     SetProfileTestData(&profile);
-    personal_data_->AddProfile(profile);
+    personal_data().AddProfile(profile);
   }
 
-  personal_data_->Refresh();
+  personal_data().Refresh();
 }
 
 void AutofillMetricsBaseTest::SetFidoEligibility(bool is_verifiable) {
@@ -141,7 +134,7 @@
       ->SetUserVerifiable(is_verifiable);
 #endif
   static_cast<payments::TestPaymentsClient*>(
-      autofill_client_.GetPaymentsClient())
+      autofill_client_->GetPaymentsClient())
       ->AllowFidoRegistration(true);
   access_manager->is_authentication_in_progress_ = false;
   access_manager->can_fetch_unmask_details_ = true;
@@ -210,13 +203,13 @@
     bool include_masked_server_credit_card,
     bool include_full_server_credit_card,
     bool masked_card_is_enrolled_for_virtual_card) {
-  personal_data_->ClearCreditCards();
+  personal_data().ClearCreditCards();
   if (include_local_credit_card) {
     CreditCard local_credit_card;
     test::SetCreditCardInfo(&local_credit_card, "Test User",
                             "4111111111111111" /* Visa */, "11", "2022", "1");
     local_credit_card.set_guid("10000000-0000-0000-0000-000000000001");
-    personal_data_->AddCreditCard(local_credit_card);
+    personal_data().AddCreditCard(local_credit_card);
   }
   if (include_masked_server_credit_card) {
     CreditCard masked_server_credit_card(CreditCard::MASKED_SERVER_CARD,
@@ -229,16 +222,16 @@
       masked_server_credit_card.set_virtual_card_enrollment_state(
           CreditCard::ENROLLED);
     }
-    personal_data_->AddServerCreditCard(masked_server_credit_card);
+    personal_data().AddServerCreditCard(masked_server_credit_card);
   }
   if (include_full_server_credit_card) {
     CreditCard full_server_credit_card(CreditCard::FULL_SERVER_CARD,
                                        "server_id_2");
     full_server_credit_card.set_guid("10000000-0000-0000-0000-000000000003");
     full_server_credit_card.set_instrument_id(2);
-    personal_data_->AddFullServerCreditCard(full_server_credit_card);
+    personal_data().AddFullServerCreditCard(full_server_credit_card);
   }
-  personal_data_->Refresh();
+  personal_data().Refresh();
 }
 
 void AutofillMetricsBaseTest::AddMaskedServerCreditCardWithOffer(
@@ -253,7 +246,7 @@
   masked_server_credit_card.set_instrument_id(id);
   masked_server_credit_card.SetNetworkForMaskedCard(kDiscoverCard);
   masked_server_credit_card.SetNumber(u"9424");
-  personal_data_->AddServerCreditCard(masked_server_credit_card);
+  personal_data().AddServerCreditCard(masked_server_credit_card);
 
   AutofillOfferData offer_data;
   offer_data.offer_id = id;
@@ -266,8 +259,8 @@
   offer_data.merchant_origins = {url};
   offer_data.eligible_instrument_id = {
       masked_server_credit_card.instrument_id()};
-  personal_data_->AddAutofillOfferData(offer_data);
-  personal_data_->Refresh();
+  personal_data().AddAutofillOfferData(offer_data);
+  personal_data().Refresh();
 }
 
 void AutofillMetricsBaseTest::CreateTestAutofillProfiles() {
@@ -277,14 +270,14 @@
                        "Apt. 10", "Memphis", "Tennessee", "38116", "US",
                        "12345678901");
   profile1.set_guid(kTestGuid);
-  personal_data_->AddProfile(profile1);
+  personal_data().AddProfile(profile1);
 
   AutofillProfile profile2;
   test::SetProfileInfo(&profile2, "Charles", "Hardin", "Holley",
                        "buddy@gmail.com", "Decca", "123 Apple St.", "unit 6",
                        "Lubbock", "Texas", "79401", "US", "2345678901");
   profile2.set_guid("00000000-0000-0000-0000-000000000002");
-  personal_data_->AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 }
 
 }  // namespace autofill::metrics
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
index e9391a0..9054d3a 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
+++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
@@ -89,12 +89,15 @@
         *autofill_driver_->autofill_manager());
   }
 
+  TestPersonalDataManager& personal_data() {
+    return *autofill_client_->GetPersonalDataManager();
+  }
+
   const bool is_in_any_main_frame_ = true;
   base::test::TaskEnvironment task_environment_;
-  MockAutofillClient autofill_client_;
+  std::unique_ptr<MockAutofillClient> autofill_client_;
   raw_ptr<ukm::TestUkmRecorder> test_ukm_recorder_;
   syncer::TestSyncService sync_service_;
-  std::unique_ptr<TestPersonalDataManager> personal_data_;
   std::unique_ptr<TestAutofillDriver> autofill_driver_;
   raw_ptr<AutofillExternalDelegate> external_delegate_;
   base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
index 18b80a65..9220ae42 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -397,7 +397,7 @@
                                      .is_autofilled = true}},
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {
       NAME_FULL,         PHONE_HOME_NUMBER, NAME_FULL,
@@ -477,7 +477,7 @@
                                      .is_autofilled = true}},
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {
       NAME_FULL,         PHONE_HOME_NUMBER, NAME_FULL,
@@ -549,7 +549,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
                                                   ADDRESS_HOME_CITY};
@@ -599,7 +599,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
                                                   ADDRESS_HOME_CITY};
@@ -648,7 +648,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS,
                                                   ADDRESS_HOME_CITY};
@@ -693,7 +693,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {CREDIT_CARD_NAME_FULL,
                                                   CREDIT_CARD_NUMBER};
@@ -738,7 +738,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {CREDIT_CARD_NAME_FULL,
                                                   CREDIT_CARD_NUMBER};
@@ -784,7 +784,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {NAME_FULL,
                                                   CREDIT_CARD_NUMBER};
@@ -830,7 +830,7 @@
                              },
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {NAME_FULL,
                                                   CREDIT_CARD_NUMBER};
@@ -887,7 +887,7 @@
                                      .is_autofilled = true}},
                          .unique_renderer_id = test::MakeFormRendererId(),
                          .main_frame_origin = url::Origin::Create(
-                             autofill_client_.form_origin())});
+                             autofill_client_->form_origin())});
 
   std::vector<ServerFieldType> heuristic_types = {
       NAME_FULL,         PHONE_HOME_NUMBER, NAME_FULL,
@@ -1877,7 +1877,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -2033,7 +2033,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FieldSignature field_signature[2];
 
@@ -2141,7 +2141,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FieldSignature field_signature[3];
 
@@ -2659,7 +2659,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   std::vector<ServerFieldType> heuristic_types, server_types, actual_types;
   AutofillField field;
@@ -2880,7 +2880,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   std::vector<ServerFieldType> heuristic_types, server_types;
   FormFieldData field;
@@ -3611,7 +3611,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   std::vector<ServerFieldType> heuristic_types, server_types;
 
@@ -3662,7 +3662,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -3759,7 +3759,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -3806,7 +3806,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -3858,7 +3858,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -4101,11 +4101,11 @@
 // Test that we correctly log when Profile Autofill is enabled at startup.
 TEST_F(AutofillMetricsTest, AutofillProfileIsEnabledAtStartup) {
   base::HistogramTester histogram_tester;
-  personal_data_->SetAutofillProfileEnabled(true);
-  personal_data_->Init(scoped_refptr<AutofillWebDataService>(nullptr),
+  personal_data().SetAutofillProfileEnabled(true);
+  personal_data().Init(scoped_refptr<AutofillWebDataService>(nullptr),
                        /*account_database=*/nullptr,
-                       /*pref_service=*/autofill_client_.GetPrefs(),
-                       /*local_state=*/autofill_client_.GetPrefs(),
+                       /*pref_service=*/autofill_client_->GetPrefs(),
+                       /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
                        /*strike_database=*/nullptr,
@@ -4118,11 +4118,11 @@
 // Test that we correctly log when Profile Autofill is disabled at startup.
 TEST_F(AutofillMetricsTest, AutofillProfileIsDisabledAtStartup) {
   base::HistogramTester histogram_tester;
-  personal_data_->SetAutofillProfileEnabled(false);
-  personal_data_->Init(scoped_refptr<AutofillWebDataService>(nullptr),
+  personal_data().SetAutofillProfileEnabled(false);
+  personal_data().Init(scoped_refptr<AutofillWebDataService>(nullptr),
                        /*account_database=*/nullptr,
-                       /*pref_service=*/autofill_client_.GetPrefs(),
-                       /*local_state=*/autofill_client_.GetPrefs(),
+                       /*pref_service=*/autofill_client_->GetPrefs(),
+                       /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
                        /*strike_database=*/nullptr,
@@ -4135,11 +4135,11 @@
 // Test that we correctly log when CreditCard Autofill is enabled at startup.
 TEST_F(AutofillMetricsTest, AutofillCreditCardIsEnabledAtStartup) {
   base::HistogramTester histogram_tester;
-  personal_data_->SetAutofillCreditCardEnabled(true);
-  personal_data_->Init(scoped_refptr<AutofillWebDataService>(nullptr),
+  personal_data().SetAutofillCreditCardEnabled(true);
+  personal_data().Init(scoped_refptr<AutofillWebDataService>(nullptr),
                        /*account_database=*/nullptr,
-                       /*pref_service=*/autofill_client_.GetPrefs(),
-                       /*local_state=*/autofill_client_.GetPrefs(),
+                       /*pref_service=*/autofill_client_->GetPrefs(),
+                       /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
                        /*strike_database=*/nullptr,
@@ -4152,11 +4152,11 @@
 // Test that we correctly log when CreditCard Autofill is disabled at startup.
 TEST_F(AutofillMetricsTest, AutofillCreditCardIsDisabledAtStartup) {
   base::HistogramTester histogram_tester;
-  personal_data_->SetAutofillCreditCardEnabled(false);
-  personal_data_->Init(scoped_refptr<AutofillWebDataService>(nullptr),
+  personal_data().SetAutofillCreditCardEnabled(false);
+  personal_data().Init(scoped_refptr<AutofillWebDataService>(nullptr),
                        /*account_database=*/nullptr,
-                       /*pref_service=*/autofill_client_.GetPrefs(),
-                       /*local_state=*/autofill_client_.GetPrefs(),
+                       /*pref_service=*/autofill_client_->GetPrefs(),
+                       /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
                        /*strike_database=*/nullptr,
@@ -4175,7 +4175,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4249,7 +4249,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4292,7 +4292,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4479,7 +4479,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
   FormFieldData field;
   test::CreateTestFormField("Enter VPA", "upi-vpa", "unique_id@upi", "text",
                             &field);
@@ -4513,7 +4513,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4720,7 +4720,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4743,13 +4743,13 @@
     // In order to test that the QueriedCreditCardFormIsSecure is logged as
     // false, we need to set the main frame origin, otherwise this fill is
     // skipped due to the form being detected as mixed content.
-    GURL client_form_origin = autofill_client_.form_origin();
+    GURL client_form_origin = autofill_client_->form_origin();
     GURL::Replacements replacements;
     replacements.SetSchemeStr(url::kHttpScheme);
-    autofill_client_.set_form_origin(
+    autofill_client_->set_form_origin(
         client_form_origin.ReplaceComponents(replacements));
     form.main_frame_origin =
-        url::Origin::Create(autofill_client_.form_origin());
+        url::Origin::Create(autofill_client_->form_origin());
     autofill_manager().AddSeenForm(form, field_types, field_types);
 
     // Simulate an Autofill query on a credit card field (HTTP, non-secure
@@ -4761,7 +4761,7 @@
     histogram_tester.ExpectUniqueSample(
         "Autofill.QueriedCreditCardFormIsSecure", false, 1);
     // Reset the main frame origin to secure for other tests
-    autofill_client_.set_form_origin(client_form_origin);
+    autofill_client_->set_form_origin(client_form_origin);
   }
 
   {
@@ -4772,7 +4772,7 @@
     form.url = GURL("https://example.com/form.html");
     form.action = GURL("https://example.com/submit.html");
     form.main_frame_origin =
-        url::Origin::Create(autofill_client_.form_origin());
+        url::Origin::Create(autofill_client_->form_origin());
     autofill_manager().AddSeenForm(form, field_types, field_types);
 
     // Simulate an Autofill query on a credit card field (HTTPS form).
@@ -4797,7 +4797,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4856,7 +4856,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4891,7 +4891,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -4949,7 +4949,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5009,7 +5009,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5091,7 +5091,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5267,7 +5267,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5411,7 +5411,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5700,7 +5700,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -5900,7 +5900,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6040,7 +6040,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6089,7 +6089,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6138,7 +6138,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6199,7 +6199,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6243,7 +6243,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -6796,7 +6796,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7142,7 +7142,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7204,7 +7204,8 @@
 
   // Add another masked server card, this time with a linked offer.
   std::string guid("12340000-0000-0000-0000-000000000001");
-  AddMaskedServerCreditCardWithOffer(guid, "$4", autofill_client_.form_origin(),
+  AddMaskedServerCreditCardWithOffer(guid, "$4",
+                                     autofill_client_->form_origin(),
                                      /*id=*/0x4fff);
   // Reset the autofill manager state.
   autofill_manager().Reset();
@@ -7326,8 +7327,9 @@
                       true /* include_full_server_credit_card */,
                       false /* masked_card_is_enrolled_for_virtual_card */);
   guid = "12340000-0000-0000-0000-000000000002";
-  AddMaskedServerCreditCardWithOffer(guid, "$4", autofill_client_.form_origin(),
-                                     /*id=*/0x3fff, /*expired=*/true);
+  AddMaskedServerCreditCardWithOffer(guid, "$4",
+                                     autofill_client_->form_origin(),
+                                     /*id=*/0x3fff, /*offer_expired=*/true);
 
   // Reset the autofill manager state.
   autofill_manager().Reset();
@@ -7396,7 +7398,8 @@
                       true /* include_full_server_credit_card */,
                       false /* masked_card_is_enrolled_for_virtual_card */);
   guid = "12340000-0000-0000-0000-000000000003";
-  AddMaskedServerCreditCardWithOffer(guid, "$5", autofill_client_.form_origin(),
+  AddMaskedServerCreditCardWithOffer(guid, "$5",
+                                     autofill_client_->form_origin(),
                                      /*id=*/0x5fff);
 
   // Reset the autofill manager state.
@@ -7599,7 +7602,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7645,7 +7648,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7690,7 +7693,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7768,7 +7771,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7863,7 +7866,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -7976,7 +7979,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8097,7 +8100,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8311,7 +8314,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8497,7 +8500,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8522,7 +8525,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8640,7 +8643,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -8657,7 +8660,7 @@
   // Simulate having seen this form on page load.
   // |form_structure| will be owned by `autofill_manager()`.
   autofill_manager().AddSeenForm(form, field_types, field_types);
-  personal_data_->ClearProfiles();
+  personal_data().ClearProfiles();
 
   {
     // Simulate activating the autofill popup for the street field.
@@ -8843,7 +8846,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -9128,7 +9131,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -9269,7 +9272,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   std::vector<FormData> forms(1, form);
 
@@ -9299,7 +9302,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   // Construct a valid credit card form.
   FormFieldData field;
@@ -9471,7 +9474,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -9732,7 +9735,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -10172,7 +10175,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   // Create the form's fields.
   FormFieldData field;
@@ -10466,7 +10469,7 @@
   form.action = GURL("http://example.com/submit.html");
   GURL frame_origin("http://example_root.com/form.html");
   form.main_frame_origin = url::Origin::Create(frame_origin);
-  autofill_client_.set_form_origin(frame_origin);
+  autofill_client_->set_form_origin(frame_origin);
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -10576,10 +10579,10 @@
 TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) {
   GURL url("https://www.google.com");
   int upload_decision = 1;
-  autofill_client_.set_form_origin(url);
+  autofill_client_->set_form_origin(url);
 
   AutofillMetrics::LogCardUploadDecisionsUkm(test_ukm_recorder_,
-                                             autofill_client_.GetUkmSourceId(),
+                                             autofill_client_->GetUkmSourceId(),
                                              url, upload_decision);
   auto entries = test_ukm_recorder_->GetEntriesByName(
       UkmCardUploadDecisionType::kEntryName);
@@ -10597,10 +10600,10 @@
   GURL url("https://www.google.com");
   int form_structure_metric = 1;
   FormSignature form_signature(100);
-  autofill_client_.set_form_origin(url);
+  autofill_client_->set_form_origin(url);
 
   AutofillMetrics::LogDeveloperEngagementUkm(
-      test_ukm_recorder_, autofill_client_.GetUkmSourceId(), url, true,
+      test_ukm_recorder_, autofill_client_->GetUkmSourceId(), url, true,
       {FormType::kCreditCardForm}, form_structure_metric, form_signature);
   auto entries = test_ukm_recorder_->GetEntriesByName(
       UkmDeveloperEngagementType::kEntryName);
@@ -10654,7 +10657,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example_cc.com/form.html");
   form.action = GURL("http://example_cc.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -10817,7 +10820,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("Name", "name", "", "text", &field);
@@ -10832,7 +10835,7 @@
   // Simulate seeing the form.
   {
     base::HistogramTester histogram_tester;
-    autofill_client_.set_security_level(
+    autofill_client_->set_security_level(
         security_state::SecurityLevel::DANGEROUS);
     autofill_manager().OnFormsSeen(/*updated_forms=*/forms,
                                    /*removed_forms=*/{});
@@ -10844,7 +10847,8 @@
   // Simulate suggestions shown twice with separate popups.
   {
     base::HistogramTester histogram_tester;
-    autofill_client_.set_security_level(security_state::SecurityLevel::WARNING);
+    autofill_client_->set_security_level(
+        security_state::SecurityLevel::WARNING);
     autofill_manager().DidShowSuggestions(true, form, field);
     autofill_manager().DidShowSuggestions(true, form, field);
     histogram_tester.ExpectBucketCount("Autofill.UserHappiness.Address.WARNING",
@@ -11123,7 +11127,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
 
@@ -11157,7 +11161,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<FormData> forms_without_one_time_code(1, form);
@@ -11186,7 +11190,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
 
@@ -11222,7 +11226,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<FormData> forms_with_single_phone_number_field(1, form);
@@ -11249,7 +11253,7 @@
 // autocomplete attribute.
 TEST_F(AutofillMetricsTest, FrameHasPhoneNumberFieldWithAutocomplete) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("phone", form);
   std::vector<FormData> forms_with_phone_number(1, form);
 
@@ -11274,7 +11278,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<FormData> forms_without_phone_number(1, form);
@@ -11300,7 +11304,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kNone.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStateNone) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("password", form);
 
   std::vector<FormData> forms(1, form);
@@ -11317,7 +11321,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kOTC.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStateOTC) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("one-time-code", form);
 
   std::vector<FormData> forms(1, form);
@@ -11346,7 +11350,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kWebOTPPlusOTC.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStateWebOTPPlusOTC) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("one-time-code", form);
 
   std::vector<FormData> forms(1, form);
@@ -11364,7 +11368,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kPhone.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStatePhone) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("tel", form);
 
   std::vector<FormData> forms(1, form);
@@ -11381,7 +11385,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kPhonePlusOTC.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStatePhonePlusOTC) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("tel", form);
   AddAutoCompleteFieldToForm("one-time-code", form);
 
@@ -11400,7 +11404,7 @@
 // Verify that we correctly log PhoneCollectionMetricState::kPhonePlusWebOTP.
 TEST_F(AutofillMetricsTest, WebOTPPhoneCollectionMetricsStatePhonePlusWebOTP) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("tel", form);
 
   std::vector<FormData> forms(1, form);
@@ -11420,7 +11424,7 @@
 TEST_F(AutofillMetricsTest,
        WebOTPPhoneCollectionMetricsStatePhonePlusWebOTPPlusOTC) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   AddAutoCompleteFieldToForm("tel", form);
   AddAutoCompleteFieldToForm("one-time-code", form);
 
@@ -11443,7 +11447,7 @@
   ASSERT_TRUE(entries.empty());
 
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
   // Document collects phone number
   AddAutoCompleteFieldToForm("tel", form);
   // Document uses OntTimeCode
@@ -11476,7 +11480,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   test::CreateTestFormField("", "", "", "password", &field);
@@ -11734,7 +11738,7 @@
   form.name = u"TestForm";
   form.url = GURL("http://example.com/form.html");
   form.action = GURL("http://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -11762,7 +11766,7 @@
 
   if (!user_saw_suggestion) {
     // Remove the profile to prevent suggestion from being shown.
-    personal_data_->ClearProfiles();
+    personal_data().ClearProfiles();
   }
 
   // Simulate interacting with the form.
@@ -11888,7 +11892,7 @@
   form.name = u"TestForm";
   form.url = GURL("https://example.com/form.html");
   form.action = GURL("https://example.com/submit.html");
-  form.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form.main_frame_origin = url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -11966,7 +11970,8 @@
   form_.name = u"TestForm";
   form_.url = GURL("http://example.com/form.html");
   form_.action = GURL("http://example.com/submit.html");
-  form_.main_frame_origin = url::Origin::Create(autofill_client_.form_origin());
+  form_.main_frame_origin =
+      url::Origin::Create(autofill_client_->form_origin());
 
   FormFieldData field;
   std::vector<ServerFieldType> field_types;
@@ -12021,7 +12026,7 @@
   base::HistogramTester histogram_tester;
 
   // Simulate that no data is available.
-  personal_data_->ClearProfiles();
+  personal_data().ClearProfiles();
   autofill_manager().OnFormsSeen(/*updated_forms=*/{form_},
                                  /*removed_forms=*/{});
   autofill_manager().OnAskForValuesToFill(
@@ -12181,14 +12186,14 @@
 // |AutofillClient| and logged upon form submission.
 TEST_F(AutofillMetricsTest, PageLanguageMetricsExpectedCase) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
 
   // Set up language state.
   translate::LanguageDetectionDetails language_detection_details;
   language_detection_details.adopted_language = "ub";
   autofill_manager().OnLanguageDetermined(language_detection_details);
-  autofill_client_.GetLanguageState()->SetSourceLanguage("ub");
-  autofill_client_.GetLanguageState()->SetCurrentLanguage("ub");
+  autofill_client_->GetLanguageState()->SetSourceLanguage("ub");
+  autofill_client_->GetLanguageState()->SetCurrentLanguage("ub");
   int language_code = 'u' * 256 + 'b';
 
   // Simulate form submission.
@@ -12206,14 +12211,14 @@
 // get logged as invalid.
 TEST_F(AutofillMetricsTest, PageLanguageMetricsInvalidLanguage) {
   FormData form;
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
 
   // Set up language state.
   translate::LanguageDetectionDetails language_detection_details;
   language_detection_details.adopted_language = "en";
   autofill_manager().OnLanguageDetermined(language_detection_details);
-  autofill_client_.GetLanguageState()->SetSourceLanguage("en");
-  autofill_client_.GetLanguageState()->SetCurrentLanguage("other");
+  autofill_client_->GetLanguageState()->SetSourceLanguage("en");
+  autofill_client_->GetLanguageState()->SetCurrentLanguage("other");
 
   // Simulate form submission.
   base::HistogramTester histogram_tester;
@@ -12364,7 +12369,7 @@
   // GIVEN
   FormData form =
       test::GetFormData({.fields = {{.role = ServerFieldType::NAME_FULL}}});
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
 
   std::vector<ServerFieldType> field_types = {NAME_FULL};
   autofill_manager().AddSeenForm(form, field_types, field_types);
@@ -12399,7 +12404,7 @@
   // GIVEN
   FormData form =
       test::GetFormData({.fields = {{.role = ServerFieldType::NAME_FULL}}});
-  CreateSimpleForm(autofill_client_.form_origin(), form);
+  CreateSimpleForm(autofill_client_->form_origin(), form);
 
   std::vector<ServerFieldType> field_types = {NAME_FULL};
   autofill_manager().AddSeenForm(form, field_types, field_types);
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index c543b55..12c5ed8 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -172,29 +172,29 @@
 
   void SetUp() override {
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
-    personal_data_manager_.Init(/*profile_database=*/database_,
-                                /*account_database=*/nullptr,
-                                /*pref_service=*/autofill_client_.GetPrefs(),
-                                /*local_state=*/autofill_client_.GetPrefs(),
-                                /*identity_manager=*/nullptr,
-                                /*history_service=*/nullptr,
-                                /*strike_database=*/nullptr,
-                                /*image_fetcher=*/nullptr,
-                                /*is_off_the_record=*/false);
-    personal_data_manager_.SetPrefService(autofill_client_.GetPrefs());
+    personal_data().Init(/*profile_database=*/database_,
+                         /*account_database=*/nullptr,
+                         /*pref_service=*/autofill_client_.GetPrefs(),
+                         /*local_state=*/autofill_client_.GetPrefs(),
+                         /*identity_manager=*/nullptr,
+                         /*history_service=*/nullptr,
+                         /*strike_database=*/nullptr,
+                         /*image_fetcher=*/nullptr,
+                         /*is_off_the_record=*/false);
+    personal_data().SetPrefService(autofill_client_.GetPrefs());
 
     accessor_ = std::make_unique<TestAccessor>();
     autofill_driver_ = std::make_unique<TestAutofillDriver>();
 
     payments_client_ = new payments::TestPaymentsClient(
         autofill_driver_->GetURLLoaderFactory(),
-        autofill_client_.GetIdentityManager(), &personal_data_manager_);
+        autofill_client_.GetIdentityManager(), &personal_data());
     autofill_client_.set_test_payments_client(
         std::unique_ptr<payments::TestPaymentsClient>(payments_client_));
     autofill_client_.set_test_strike_database(
         std::make_unique<TestStrikeDatabase>());
     browser_autofill_manager_ = std::make_unique<TestBrowserAutofillManager>(
-        autofill_driver_.get(), &autofill_client_, &personal_data_manager_);
+        autofill_driver_.get(), &autofill_client_);
     credit_card_access_manager_ =
         browser_autofill_manager_->GetCreditCardAccessManager();
 
@@ -220,8 +220,8 @@
     // PersonalDataManager to be around when it gets destroyed.
     autofill_driver_.reset();
 
-    personal_data_manager_.SetPrefService(nullptr);
-    personal_data_manager_.ClearCreditCards();
+    personal_data().SetPrefService(nullptr);
+    personal_data().ClearCreditCards();
   }
 
   bool IsAuthenticationInProgress() {
@@ -235,7 +235,7 @@
     credit_card_access_manager_->is_user_verifiable_ = absl::nullopt;
   }
 
-  void ClearCards() { personal_data_manager_.ClearCreditCards(); }
+  void ClearCards() { personal_data().ClearCreditCards(); }
 
   void CreateLocalCard(std::string guid, std::string number = std::string()) {
     CreditCard local_card = CreditCard();
@@ -245,7 +245,7 @@
     local_card.set_guid(guid);
     local_card.set_record_type(CreditCard::LOCAL_CARD);
 
-    personal_data_manager_.AddCreditCard(local_card);
+    personal_data().AddCreditCard(local_card);
   }
 
   void CreateServerCard(std::string guid,
@@ -260,7 +260,7 @@
     server_card.set_record_type(masked ? CreditCard::MASKED_SERVER_CARD
                                        : CreditCard::FULL_SERVER_CARD);
     server_card.set_server_id(server_id);
-    personal_data_manager_.AddServerCreditCard(server_card);
+    personal_data().AddServerCreditCard(server_card);
   }
 
   CreditCardCVCAuthenticator* GetCVCAuthenticator() {
@@ -517,6 +517,10 @@
   }
 
  protected:
+  TestPersonalDataManager& personal_data() {
+    return *autofill_client_.GetPersonalDataManager();
+  }
+
   std::unique_ptr<TestAccessor> accessor_;
   base::test::TaskEnvironment task_environment_;
   variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
@@ -525,7 +529,6 @@
   TestAutofillClient autofill_client_;
   std::unique_ptr<TestAutofillDriver> autofill_driver_;
   scoped_refptr<AutofillWebDataService> database_;
-  TestPersonalDataManager personal_data_manager_;
   // TODO(crbug.com/1249665): Remove this member variable and use test-local
   // feature lists.
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -556,9 +559,9 @@
   CreateLocalCard(kTestGUID);
   CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID);
 
-  EXPECT_TRUE(personal_data_manager_.GetCreditCardWithGUID(kTestGUID));
+  EXPECT_TRUE(personal_data().GetCreditCardWithGUID(kTestGUID));
   EXPECT_TRUE(credit_card_access_manager_->DeleteCard(card));
-  EXPECT_FALSE(personal_data_manager_.GetCreditCardWithGUID(kTestGUID));
+  EXPECT_FALSE(personal_data().GetCreditCardWithGUID(kTestGUID));
 }
 
 // Ensures DeleteCard() does nothing for server cards.
@@ -566,11 +569,11 @@
   CreateServerCard(kTestGUID);
   CreditCard* card = credit_card_access_manager_->GetCreditCard(kTestGUID);
 
-  EXPECT_TRUE(personal_data_manager_.GetCreditCardWithGUID(kTestGUID));
+  EXPECT_TRUE(personal_data().GetCreditCardWithGUID(kTestGUID));
   EXPECT_FALSE(credit_card_access_manager_->DeleteCard(card));
 
   // Cannot delete server cards.
-  EXPECT_TRUE(personal_data_manager_.GetCreditCardWithGUID(kTestGUID));
+  EXPECT_TRUE(personal_data().GetCreditCardWithGUID(kTestGUID));
 }
 
 // Ensures GetDeletionConfirmationText(~) returns correct values for local
@@ -622,7 +625,7 @@
 
 // Ensures that FetchCreditCard() reports a failure when a card does not exist.
 TEST_F(CreditCardAccessManagerTest, FetchNullptrFailure) {
-  personal_data_manager_.ClearCreditCards();
+  personal_data().ClearCreditCards();
 
   credit_card_access_manager_->PrepareToFetchCreditCard();
   WaitForCallbacks();
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
index 8933c9da..5e37a50 100644
--- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -130,37 +130,37 @@
         std::make_unique<TestStrikeDatabase>();
     strike_database_ = test_strike_database.get();
     autofill_client_.set_test_strike_database(std::move(test_strike_database));
-    personal_data_.set_auto_accept_address_imports_for_testing(true);
-    personal_data_.Init(/*profile_database=*/database_,
-                        /*account_database=*/nullptr,
-                        /*pref_service=*/autofill_client_.GetPrefs(),
-                        /*local_state=*/autofill_client_.GetPrefs(),
-                        /*identity_manager=*/nullptr,
-                        /*history_service=*/nullptr,
-                        /*strike_database=*/nullptr,
-                        /*image_fetcher=*/nullptr,
-                        /*is_off_the_record=*/false);
-    personal_data_.OnSyncServiceInitialized(&sync_service_);
+    personal_data().set_auto_accept_address_imports_for_testing(true);
+    personal_data().Init(/*profile_database=*/database_,
+                         /*account_database=*/nullptr,
+                         /*pref_service=*/autofill_client_.GetPrefs(),
+                         /*local_state=*/autofill_client_.GetPrefs(),
+                         /*identity_manager=*/nullptr,
+                         /*history_service=*/nullptr,
+                         /*strike_database=*/nullptr,
+                         /*image_fetcher=*/nullptr,
+                         /*is_off_the_record=*/false);
+    personal_data().OnSyncServiceInitialized(&sync_service_);
     autofill_driver_ = std::make_unique<TestAutofillDriver>();
     payments_client_ = new payments::TestPaymentsClient(
         autofill_driver_->GetURLLoaderFactory(),
-        autofill_client_.GetIdentityManager(), &personal_data_);
+        autofill_client_.GetIdentityManager(), &personal_data());
     autofill_client_.set_test_payments_client(
         std::unique_ptr<payments::TestPaymentsClient>(payments_client_));
     credit_card_save_manager_ =
         new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_,
-                                      payments_client_, &personal_data_);
+                                      payments_client_, &personal_data());
     credit_card_save_manager_->SetCreditCardUploadEnabled(true);
     autofill::TestFormDataImporter* test_form_data_importer =
         new TestFormDataImporter(
             &autofill_client_, payments_client_,
             std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager_),
-            &personal_data_, "en-US");
+            &personal_data(), "en-US");
     autofill_client_.set_test_form_data_importer(
         std::unique_ptr<TestFormDataImporter>(test_form_data_importer));
     autofill_client_.GetStrikeDatabase();
     browser_autofill_manager_ = std::make_unique<TestBrowserAutofillManager>(
-        autofill_driver_.get(), &autofill_client_, &personal_data_);
+        autofill_driver_.get(), &autofill_client_);
     browser_autofill_manager_->SetExpectedObservedSubmission(true);
   }
 
@@ -170,8 +170,8 @@
     browser_autofill_manager_.reset();
     autofill_driver_.reset();
 
-    personal_data_.SetPrefService(nullptr);
-    personal_data_.ClearCreditCards();
+    personal_data().SetPrefService(nullptr);
+    personal_data().ClearCreditCards();
   }
 
   void FormsSeen(const std::vector<FormData>& forms) {
@@ -340,12 +340,17 @@
   }
 
  protected:
+  MockPersonalDataManager& personal_data() {
+    return static_cast<MockPersonalDataManager&>(
+        *autofill_client_.GetPersonalDataManager());
+  }
+
   base::test::TaskEnvironment task_environment_;
-  TestAutofillClient autofill_client_;
+  TestAutofillClient autofill_client_{
+      std::make_unique<MockPersonalDataManager>()};
   std::unique_ptr<TestAutofillDriver> autofill_driver_;
   std::unique_ptr<TestBrowserAutofillManager> browser_autofill_manager_;
   scoped_refptr<AutofillWebDataService> database_;
-  MockPersonalDataManager personal_data_;
   syncer::TestSyncService sync_service_;
   // TODO(crbug.com/1291003): Refactor to use the real CreditCardSaveManager.
   // Ends up getting owned (and destroyed) by TestFormDataImporter:
@@ -511,7 +516,7 @@
 
   // Verify that even though the full address profile was saved, only the
   // country was included in the upload details request to payments.
-  EXPECT_EQ(1U, personal_data_.GetProfiles().size());
+  EXPECT_EQ(1U, personal_data().GetProfiles().size());
   AutofillProfile only_country;
   only_country.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
   EXPECT_EQ(1U, payments_client_->addresses_in_upload_details().size());
@@ -521,7 +526,7 @@
                    only_country));
 
   // Server did not send a server_id, expect copy of card is not stored.
-  EXPECT_TRUE(personal_data_.GetCreditCards().empty());
+  EXPECT_TRUE(personal_data().GetCreditCards().empty());
 
   // Verify that the correct histogram entry (and only that) was logged.
   ExpectUniqueCardUploadDecision(histogram_tester,
@@ -535,7 +540,7 @@
   // even though only countries were included in GetUploadDetails.
   EXPECT_THAT(
       payments_client_->addresses_in_upload_card(),
-      testing::UnorderedElementsAreArray({*personal_data_.GetProfiles()[0]}));
+      testing::UnorderedElementsAreArray({*personal_data().GetProfiles()[0]}));
 }
 #endif
 
@@ -1138,7 +1143,7 @@
   EXPECT_TRUE(payments_client_->active_experiments_in_request().empty());
 
   // Server did not send a server_id, expect copy of card is not stored.
-  EXPECT_TRUE(personal_data_.GetCreditCards().empty());
+  EXPECT_TRUE(personal_data().GetCreditCards().empty());
   // Verify that the correct histogram entry (and only that) was logged.
   ExpectUniqueCardUploadDecision(histogram_tester,
                                  AutofillMetrics::UPLOAD_OFFERED);
@@ -1216,7 +1221,7 @@
   EXPECT_TRUE(payments_client_->active_experiments_in_request().empty());
 
   // Server did not send a server_id, expect copy of card is not stored.
-  EXPECT_TRUE(personal_data_.GetCreditCards().empty());
+  EXPECT_TRUE(personal_data().GetCreditCards().empty());
   // Verify that the correct histogram entry (and only that) was logged.
   ExpectUniqueCardUploadDecision(histogram_tester,
                                  AutofillMetrics::UPLOAD_OFFERED);
@@ -1233,8 +1238,8 @@
 #endif
 
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_NotSavedLocally) {
-  personal_data_.ClearCreditCards();
-  personal_data_.ClearProfiles();
+  personal_data().ClearCreditCards();
+  personal_data().ClearProfiles();
 
   credit_card_save_manager_->SetCreditCardUploadEnabled(true);
 
@@ -1270,7 +1275,7 @@
   EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
 
   // Don't keep a copy of the card on this device.
-  EXPECT_TRUE(personal_data_.GetCreditCards().empty());
+  EXPECT_TRUE(personal_data().GetCreditCards().empty());
 }
 
 TEST_F(CreditCardSaveManagerTest, UploadCreditCard_FeatureNotEnabled) {
@@ -1975,14 +1980,14 @@
   profile1.SetInfo(NAME_FULL, u"Flo Master", "en-US");
   profile1.SetInfo(ADDRESS_HOME_ZIP, u"H3B2Y5", "en-US");
   profile1.SetInfo(ADDRESS_HOME_COUNTRY, u"CA", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
 
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000002");
   profile2.SetInfo(NAME_FULL, u"Flo Master", "en-US");
   profile2.SetInfo(ADDRESS_HOME_ZIP, u"h3b 2y5", "en-US");
   profile2.SetInfo(ADDRESS_HOME_COUNTRY, u"CA", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -2594,7 +2599,7 @@
 #if !BUILDFLAG(IS_IOS)
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Create, fill and submit an address form in order to establish a recent
@@ -2644,7 +2649,7 @@
 #if !BUILDFLAG(IS_IOS)
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Create, fill and submit an address form in order to establish a recent
@@ -2725,13 +2730,13 @@
 
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Run through the form submit in exactly the same way (but now Chrome knows
   // that the user is a Google Payments customer).
-  personal_data_.ClearCreditCards();
-  personal_data_.ClearProfiles();
+  personal_data().ClearCreditCards();
+  personal_data().ClearProfiles();
   FormSubmitted(credit_card_form);
 
   // Verify the |credit_card_save_manager_| is NOT requesting cardholder name.
@@ -2802,7 +2807,7 @@
   // submitting.
 #if !BUILDFLAG(IS_IOS)
   // Wallet Sync Transport is enabled.
-  personal_data_.SetSyncAndSignInState(
+  personal_data().SetSyncAndSignInState(
       AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled);
 
   // Create, fill and submit an address form in order to establish a recent
@@ -2844,7 +2849,7 @@
   // submitting.
 #if !BUILDFLAG(IS_IOS)
   // Wallet Sync Transport is not enabled.
-  personal_data_.SetSyncAndSignInState(
+  personal_data().SetSyncAndSignInState(
       AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled);
 
   // Create, fill and submit an address form in order to establish a recent
@@ -3271,7 +3276,7 @@
                           test::NextMonth().c_str(), test::NextYear().c_str(),
                           "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(credit_card);
+  personal_data().AddServerCreditCard(credit_card);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3372,7 +3377,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(NAME_FULL, u"John Smith", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3401,7 +3406,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(NAME_FULL, u"John Smith", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3431,7 +3436,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(NAME_FULL, u"John Smith", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3459,7 +3464,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3488,11 +3493,11 @@
   AutofillProfile profile1;
   profile1.set_guid("00000000-0000-0000-0000-000000000200");
   profile1.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000201");
   profile2.SetInfo(ADDRESS_HOME_ZIP, u"95051", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3517,7 +3522,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(ADDRESS_HOME_LINE1, u"123 Testing St.", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3546,7 +3551,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3574,7 +3579,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3603,7 +3608,7 @@
   AutofillProfile profile;
   profile.set_guid("00000000-0000-0000-0000-000000000200");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3630,7 +3635,7 @@
 TEST_F(CreditCardSaveManagerTest, DetectHasGooglePaymentAccount) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Set up our credit card form data.
@@ -3665,7 +3670,7 @@
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3704,7 +3709,7 @@
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
   profile.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3739,19 +3744,19 @@
   AutofillProfile profile1;
   profile1.set_guid("00000000-0000-0000-0000-000000000200");
   profile1.SetInfo(ADDRESS_HOME_LINE1, u"123 Testing St.", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000201");
   profile2.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
   AutofillProfile profile3;
   profile3.set_guid("00000000-0000-0000-0000-000000000202");
   profile3.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
-  personal_data_.AddProfile(profile3);
+  personal_data().AddProfile(profile3);
   AutofillProfile profile4;
   profile4.set_guid("00000000-0000-0000-0000-000000000203");
   profile4.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile4);
+  personal_data().AddProfile(profile4);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3794,7 +3799,7 @@
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3853,7 +3858,7 @@
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -3893,7 +3898,7 @@
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data with credit card first and last name
   // fields.
@@ -3941,7 +3946,7 @@
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -4126,7 +4131,7 @@
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -4175,7 +4180,7 @@
   profile1.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile1.SetInfo(ADDRESS_HOME_ZIP, u"94043", "en-US");
   profile1.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile1);
+  personal_data().AddProfile(profile1);
   AutofillProfile profile2;
   profile2.set_guid("00000000-0000-0000-0000-000000000201");
   profile2.SetInfo(NAME_FULL, u"Flo Master", "en-US");
@@ -4184,7 +4189,7 @@
   profile2.SetInfo(ADDRESS_HOME_STATE, u"Stateland", "en-US");
   profile2.SetInfo(ADDRESS_HOME_ZIP, u"12345", "en-US");
   profile2.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile2);
+  personal_data().AddProfile(profile2);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -4231,7 +4236,7 @@
   profile.SetInfo(ADDRESS_HOME_CITY, u"Mountain View", "en-US");
   profile.SetInfo(ADDRESS_HOME_STATE, u"California", "en-US");
   profile.SetInfo(ADDRESS_HOME_COUNTRY, u"US", "en-US");
-  personal_data_.AddProfile(profile);
+  personal_data().AddProfile(profile);
 
   // Set up our credit card form data.
   FormData credit_card_form;
@@ -4284,7 +4289,7 @@
                           test::NextMonth().c_str(), test::NextYear().c_str(),
                           "1");
   local_card.set_record_type(CreditCard::LOCAL_CARD);
-  personal_data_.AddCreditCard(local_card);
+  personal_data().AddCreditCard(local_card);
 
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -4380,7 +4385,7 @@
                           test::NextMonth().c_str(), test::NextYear().c_str(),
                           "1");
   local_card.set_record_type(CreditCard::LOCAL_CARD);
-  personal_data_.AddCreditCard(local_card);
+  personal_data().AddCreditCard(local_card);
 
   // Create, fill and submit an address form in order to establish a recent
   // profile which can be selected for the upload request.
@@ -4481,7 +4486,7 @@
        UploadCreditCard_ShouldAddBillingCustomerNumberInRequest) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Create, fill and submit an address form in order to establish a recent
@@ -5098,7 +5103,7 @@
 // Make sure that the PersonalDataManager gets notified when the user accepts
 // an upload offer.
 TEST_F(CreditCardSaveManagerTest, OnUserDidAcceptUpload_NotifiesPDM) {
-  EXPECT_CALL(personal_data_, OnUserAcceptedUpstreamOffer);
+  EXPECT_CALL(personal_data(), OnUserAcceptedUpstreamOffer);
 
   // Simulate that the user has accepted the upload from the prompt.
   UserHasAcceptedUpload({});
@@ -5149,7 +5154,7 @@
                           test::NextMonth().c_str(), test::NextYear().c_str(),
                           "1");
   local_card.set_record_type(CreditCard::LOCAL_CARD);
-  personal_data_.AddCreditCard(local_card);
+  personal_data().AddCreditCard(local_card);
 
   // Edit the data, and submit.
   credit_card_form.fields[0].value = u"Flo Master";
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
index d1ed735..3182b70 100644
--- a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
@@ -67,21 +67,21 @@
  public:
   void SetUp() override {
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
-    personal_data_.SetPrefService(autofill_client_.GetPrefs());
-    personal_data_.OnSyncServiceInitialized(&sync_service_);
+    personal_data().SetPrefService(autofill_client_.GetPrefs());
+    personal_data().OnSyncServiceInitialized(&sync_service_);
     autofill_driver_ = std::make_unique<TestAutofillDriver>();
     payments_client_ = new payments::TestPaymentsClient(
         autofill_driver_->GetURLLoaderFactory(),
-        autofill_client_.GetIdentityManager(), &personal_data_);
+        autofill_client_.GetIdentityManager(), &personal_data());
     autofill_client_.set_test_payments_client(
         std::unique_ptr<payments::TestPaymentsClient>(payments_client_));
     credit_card_save_manager_ =
         new TestCreditCardSaveManager(autofill_driver_.get(), &autofill_client_,
-                                      payments_client_, &personal_data_);
+                                      payments_client_, &personal_data());
     credit_card_save_manager_->SetCreditCardUploadEnabled(true);
     local_card_migration_manager_ = new TestLocalCardMigrationManager(
         autofill_driver_.get(), &autofill_client_, payments_client_,
-        &personal_data_);
+        &personal_data());
     std::unique_ptr<TestStrikeDatabase> test_strike_database =
         std::make_unique<TestStrikeDatabase>();
     strike_database_ = test_strike_database.get();
@@ -90,13 +90,13 @@
         new TestFormDataImporter(
             &autofill_client_, payments_client_,
             std::unique_ptr<CreditCardSaveManager>(credit_card_save_manager_),
-            &personal_data_, "en-US",
+            &personal_data(), "en-US",
             std::unique_ptr<LocalCardMigrationManager>(
                 local_card_migration_manager_));
     autofill_client_.set_test_form_data_importer(
         std::unique_ptr<TestFormDataImporter>(test_form_data_importer));
     browser_autofill_manager_ = std::make_unique<TestBrowserAutofillManager>(
-        autofill_driver_.get(), &autofill_client_, &personal_data_);
+        autofill_driver_.get(), &autofill_client_);
     browser_autofill_manager_->SetExpectedObservedSubmission(true);
   }
 
@@ -106,8 +106,8 @@
     browser_autofill_manager_.reset();
     autofill_driver_.reset();
 
-    personal_data_.SetPrefService(nullptr);
-    personal_data_.ClearCreditCards();
+    personal_data().SetPrefService(nullptr);
+    personal_data().ClearCreditCards();
   }
 
   void FormsSeen(const std::vector<FormData>& updated_forms) {
@@ -170,16 +170,16 @@
   void UseNewCardWithLocalCardsOnFile() {
     // Set the billing_customer_number to designate existence of a Payments
     // account.
-    personal_data_.SetPaymentsCustomerData(
+    personal_data().SetPaymentsCustomerData(
         std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
     // Add a local credit card (but it will not match what we will enter below).
-    AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
     // Add another local credit card (but it will not match what we will enter
     // below).
-    AddLocalCreditCard(personal_data_, "Flo Master", "4444333322221111", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4444333322221111", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
 
@@ -197,16 +197,16 @@
   void UseLocalCardWithOtherLocalCardsOnFile() {
     // Set the billing_customer_number to designate existence of a Payments
     // account.
-    personal_data_.SetPaymentsCustomerData(
+    personal_data().SetPaymentsCustomerData(
         std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
     // Add a local credit card whose |TypeAndLastFourDigits| matches what we
     // will enter below.
-    AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
     // Add another local credit card.
-    AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
 
@@ -224,20 +224,20 @@
   void UseLocalCardWithInvalidLocalCardsOnFile() {
     // Set the billing_customer_number to designate existence of a Payments
     // account.
-    personal_data_.SetPaymentsCustomerData(
+    personal_data().SetPaymentsCustomerData(
         std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
     // Add a local credit card whose |TypeAndLastFourDigits| matches what we
     // will enter below.
-    AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
     // Add other invalid local credit cards (invalid card number or expired), so
     // it will not trigger migration.
-    AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111112", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111112", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
-    AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                        test::LastYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
 
@@ -255,7 +255,7 @@
   void UseServerCardWithOtherValidLocalCardsOnFile() {
     // Set the billing_customer_number to designate existence of a Payments
     // account.
-    personal_data_.SetPaymentsCustomerData(
+    personal_data().SetPaymentsCustomerData(
         std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
     // Add a masked server credit card whose |TypeAndLastFourDigits| matches
@@ -265,9 +265,9 @@
     test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                             test::NextYear().c_str(), "1");
     credit_card.SetNetworkForMaskedCard(kVisaCard);
-    personal_data_.AddServerCreditCard(credit_card);
+    personal_data().AddServerCreditCard(credit_card);
     // Add one valid local credit card, so it will trigger migration
-    AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
 
@@ -285,7 +285,7 @@
   void UseServerCardWithInvalidLocalCardsOnFile() {
     // Set the billing_customer_number to designate existence of a Payments
     // account.
-    personal_data_.SetPaymentsCustomerData(
+    personal_data().SetPaymentsCustomerData(
         std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
     // Add a masked credit card whose |TypeAndLastFourDigits| matches what we
@@ -295,13 +295,13 @@
     test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                             test::NextYear().c_str(), "1");
     credit_card.SetNetworkForMaskedCard(kVisaCard);
-    personal_data_.AddServerCreditCard(credit_card);
+    personal_data().AddServerCreditCard(credit_card);
     // Add other invalid local credit cards (invalid card number or expired), so
     // it will not trigger migration.
-    AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111112", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111112", "11",
                        test::NextYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
-    AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+    AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                        test::LastYear().c_str(), "1",
                        base::GUID::GenerateRandomV4());
 
@@ -317,11 +317,14 @@
   }
 
  protected:
+  TestPersonalDataManager& personal_data() {
+    return *autofill_client_.GetPersonalDataManager();
+  }
+
   base::test::TaskEnvironment task_environment_;
   TestAutofillClient autofill_client_;
   std::unique_ptr<TestAutofillDriver> autofill_driver_;
   std::unique_ptr<TestBrowserAutofillManager> browser_autofill_manager_;
-  TestPersonalDataManager personal_data_;
   syncer::TestSyncService sync_service_;
   base::test::ScopedFeatureList scoped_feature_list_;
   // Ends up getting owned (and destroyed) by TestAutofillClient:
@@ -339,12 +342,12 @@
        MigrateCreditCard_UseLocalCardWithOneLocal) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -427,11 +430,11 @@
 TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) {
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -453,7 +456,7 @@
        MigrateCreditCard_LocalCardMatchMaskedServerCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a masked server card whose |TypeAndLastFourDigits| matches a local
@@ -462,14 +465,14 @@
   test::SetCreditCardInfo(&server_card, "Flo Master", "1111", "11",
                           test::NextYear().c_str(), "1");
   server_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(server_card);
+  personal_data().AddServerCreditCard(server_card);
   // Add a local card whose |TypeAndLastFourDigits| matches a masked server
   // card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -491,20 +494,20 @@
        MigrateCreditCard_LocalCardMatchFullServerCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a full server card whose number matches a local card.
   CreditCard server_card(CreditCard::FULL_SERVER_CARD, "a123");
   test::SetCreditCardInfo(&server_card, "Flo Master", "4111111111111111", "11",
                           test::NextYear().c_str(), "1");
-  personal_data_.AddServerCreditCard(server_card);
+  personal_data().AddServerCreditCard(server_card);
   // Add a local credit card whose number matches a full server card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -524,16 +527,16 @@
 TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card with a different cardholder name.
-  AddLocalCreditCard(personal_data_, "John Smith", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "John Smith", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -557,16 +560,16 @@
        GetDetectedValues_OneCardWithoutCardHolderName) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card without card holder name.
-  AddLocalCreditCard(personal_data_, "", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Set up our credit card form data.
@@ -610,7 +613,7 @@
        MigrateCreditCard_ShouldAddMigrateCardsBillingCustomerNumberInRequest) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Use one local card with more valid local cards available.
@@ -636,12 +639,12 @@
        MigrateCreditCard_ShouldAddUploadCardSourceInRequest_SettingsPage) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card. One migratable credit card will still trigger
   // migration on settings page.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -664,12 +667,12 @@
        MigrateCreditCard_TriggerFromSettingsPage) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card. One migratable credit card will still trigger
   // migration on settings page.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -697,16 +700,16 @@
 TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card for migration.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
   // Verify that it exists in the local database.
-  EXPECT_TRUE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_TRUE(personal_data().GetCreditCardByNumber("4111111111111111"));
 
   // Get the migratable credit cards.
   local_card_migration_manager_->GetMigratableCreditCards();
@@ -729,7 +732,7 @@
             autofill::MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD);
 
   // Local card should *not* be present as it is migrated already.
-  EXPECT_FALSE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_FALSE(personal_data().GetCreditCardByNumber("4111111111111111"));
 }
 
 // Verify that given the parsed response from the payments client, the migration
@@ -738,17 +741,17 @@
        MigrateCreditCard_MigrationTemporaryFailure) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card. One migratable credit card will still trigger
   // migration on settings page.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
   // Verify that it exists in local database.
-  EXPECT_TRUE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_TRUE(personal_data().GetCreditCardByNumber("4111111111111111"));
 
   // Get the migratable credit cards.
   local_card_migration_manager_->GetMigratableCreditCards();
@@ -772,7 +775,7 @@
             autofill::MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD);
 
   // Local card should be present as it is not migrated.
-  EXPECT_TRUE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_TRUE(personal_data().GetCreditCardByNumber("4111111111111111"));
 }
 
 // Verify that given the parsed response from the payments client, the migration
@@ -781,17 +784,17 @@
        MigrateCreditCard_MigrationPermanentFailure) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card. One migratable credit card will still trigger
   // migration on settings page.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
   // Verify that it exists in local database.
-  EXPECT_TRUE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_TRUE(personal_data().GetCreditCardByNumber("4111111111111111"));
 
   // Get the migratable credit cards.
   local_card_migration_manager_->GetMigratableCreditCards();
@@ -815,22 +818,22 @@
             autofill::MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD);
 
   // Local card should be present as it is not migrated.
-  EXPECT_TRUE(personal_data_.GetCreditCardByNumber("4111111111111111"));
+  EXPECT_TRUE(personal_data().GetCreditCardByNumber("4111111111111111"));
 }
 
 // Verify selected cards are correctly passed to manager.
 TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) {
   const base::GUID guid1 = base::GUID::GenerateRandomV4();
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1", guid1);
 
   const base::GUID guid2 = base::GUID::GenerateRandomV4();
-  AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5454545454545454", "11",
                      test::NextYear().c_str(), "1", guid2);
 
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   local_card_migration_manager_->GetMigratableCreditCards();
@@ -850,16 +853,16 @@
 
 TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) {
   const base::GUID guid = base::GUID::GenerateRandomV4();
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1", guid);
 
   const std::string guid_str = guid.AsLowercaseString();
-  EXPECT_TRUE(personal_data_.GetCreditCardWithGUID(guid_str.c_str()));
+  EXPECT_TRUE(personal_data().GetCreditCardWithGUID(guid_str.c_str()));
 
   local_card_migration_manager_->OnUserDeletedLocalCardViaMigrationDialog(
       guid_str);
 
-  EXPECT_FALSE(personal_data_.GetCreditCardWithGUID(guid_str.c_str()));
+  EXPECT_FALSE(personal_data().GetCreditCardWithGUID(guid_str.c_str()));
 }
 
 // Use one local card with more valid local cards available, don't show prompt
@@ -916,16 +919,16 @@
 // strike count is logged.
 TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_StrikeCountUMALogged) {
   const base::GUID guid1 = base::GUID::GenerateRandomV4();
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1", guid1);
 
   const base::GUID guid2 = base::GUID::GenerateRandomV4();
-  AddLocalCreditCard(personal_data_, "Flo Master", "5454545454545454", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5454545454545454", "11",
                      test::NextYear().c_str(), "1", guid2);
 
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
   local_card_migration_manager_->GetMigratableCreditCards();
 
@@ -954,16 +957,16 @@
        MigrateCreditCard_MigrationAbortWhenUseUnsupportedLocalCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -991,16 +994,16 @@
        MigrateCreditCard_MigrateWhenHasSupportedLocalCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1037,7 +1040,7 @@
     MigrateCreditCard_MigrateWhenUseUnsupportedServerCardWithSupportedLocalCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
@@ -1046,9 +1049,9 @@
   test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                           test::NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(credit_card);
+  personal_data().AddServerCreditCard(credit_card);
   // Add one valid local credit card, so it will trigger migration
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1078,7 +1081,7 @@
     MigrateCreditCard_MigrateAbortWhenUseSupportedServerCardWithUnsupportedLocalCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
@@ -1087,9 +1090,9 @@
   test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                           test::NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(credit_card);
+  personal_data().AddServerCreditCard(credit_card);
   // Add one valid local credit card, so it will trigger migration
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1192,12 +1195,12 @@
        LogMigrationOrigin_TriggerFromSettingsPage) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card. One migratable credit card will still trigger
   // migration on settings page.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1241,11 +1244,11 @@
   base::HistogramTester histogram_tester;
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1332,16 +1335,16 @@
        LogMigrationDecisionMetric_UseUnsupportedLocalCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a local credit card whose |TypeAndLastFourDigits| matches what we will
   // enter below.
-  AddLocalCreditCard(personal_data_, "Flo Master", "4111111111111111", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "4111111111111111", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
   // Add another local credit card.
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1374,7 +1377,7 @@
        LogMigrationDecisionMetric_NoSupportedCardsForSupportedServerCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
@@ -1383,9 +1386,9 @@
   test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                           test::NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(credit_card);
+  personal_data().AddServerCreditCard(credit_card);
   // Add one valid local credit card, so it will trigger migration
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
@@ -1418,7 +1421,7 @@
        LogMigrationDecisionMetric_NoSupportedCardsForUnsupportedServerCard) {
   // Set the billing_customer_number to designate existence of a Payments
   // account.
-  personal_data_.SetPaymentsCustomerData(
+  personal_data().SetPaymentsCustomerData(
       std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456"));
 
   // Add a masked server credit card whose |TypeAndLastFourDigits| matches what
@@ -1427,9 +1430,9 @@
   test::SetCreditCardInfo(&credit_card, "Flo Master", "1111", "11",
                           test::NextYear().c_str(), "1");
   credit_card.SetNetworkForMaskedCard(kVisaCard);
-  personal_data_.AddServerCreditCard(credit_card);
+  personal_data().AddServerCreditCard(credit_card);
   // Add one valid local credit card, so it will trigger migration
-  AddLocalCreditCard(personal_data_, "Flo Master", "5555555555554444", "11",
+  AddLocalCreditCard(personal_data(), "Flo Master", "5555555555554444", "11",
                      test::NextYear().c_str(), "1",
                      base::GUID::GenerateRandomV4());
 
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc
index 8fda384..45299b6e 100644
--- a/components/autofill/core/browser/test_autofill_client.cc
+++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -18,18 +18,21 @@
 
 namespace autofill {
 
-TestAutofillClient::TestAutofillClient()
-    : form_origin_(GURL("https://example.test")),
+TestAutofillClient::TestAutofillClient(
+    std::unique_ptr<TestPersonalDataManager> pdm)
+    : test_personal_data_manager_(
+          pdm ? std::move(pdm) : std::make_unique<TestPersonalDataManager>()),
+      form_origin_(GURL("https://example.test")),
       last_committed_url_(GURL("https://example.test")) {}
 
-TestAutofillClient::~TestAutofillClient() {}
+TestAutofillClient::~TestAutofillClient() = default;
 
 version_info::Channel TestAutofillClient::GetChannel() const {
   return channel_for_testing_;
 }
 
-PersonalDataManager* TestAutofillClient::GetPersonalDataManager() {
-  return &test_personal_data_manager_;
+TestPersonalDataManager* TestAutofillClient::GetPersonalDataManager() {
+  return test_personal_data_manager_.get();
 }
 
 AutocompleteHistoryManager*
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h
index 30261f3e..c8c125e5 100644
--- a/components/autofill/core/browser/test_autofill_client.h
+++ b/components/autofill/core/browser/test_autofill_client.h
@@ -40,7 +40,8 @@
 // This class is for easier writing of tests.
 class TestAutofillClient : public AutofillClient {
  public:
-  TestAutofillClient();
+  explicit TestAutofillClient(
+      std::unique_ptr<TestPersonalDataManager> pdm = nullptr);
 
   TestAutofillClient(const TestAutofillClient&) = delete;
   TestAutofillClient& operator=(const TestAutofillClient&) = delete;
@@ -49,7 +50,7 @@
 
   // AutofillClient:
   version_info::Channel GetChannel() const override;
-  PersonalDataManager* GetPersonalDataManager() override;
+  TestPersonalDataManager* GetPersonalDataManager() override;
   AutocompleteHistoryManager* GetAutocompleteHistoryManager() override;
   PrefService* GetPrefs() override;
   const PrefService* GetPrefs() const override;
@@ -184,6 +185,10 @@
     prefs_ = std::move(prefs);
   }
 
+  void set_personal_data_manager(std::unique_ptr<TestPersonalDataManager> pdm) {
+    test_personal_data_manager_ = std::move(pdm);
+  }
+
   void set_test_strike_database(
       std::unique_ptr<TestStrikeDatabase> test_strike_database) {
     test_strike_database_ = std::move(test_strike_database);
@@ -285,16 +290,20 @@
   signin::IdentityTestEnvironment identity_test_env_;
   raw_ptr<syncer::SyncService> test_sync_service_ = nullptr;
   TestAddressNormalizer test_address_normalizer_;
-  TestPersonalDataManager test_personal_data_manager_;
   ::testing::NiceMock<MockAutocompleteHistoryManager>
       mock_autocomplete_history_manager_;
-  std::unique_ptr<AutofillOfferManager> autofill_offer_manager_;
 
   // NULL by default.
   std::unique_ptr<PrefService> prefs_;
   std::unique_ptr<TestStrikeDatabase> test_strike_database_;
   std::unique_ptr<payments::PaymentsClient> payments_client_;
   std::unique_ptr<TestFormDataImporter> form_data_importer_;
+
+  // AutofillOfferManager must be destroyed before TestPersonalDataManager
+  // because the former's destructor refers to the latter.
+  std::unique_ptr<TestPersonalDataManager> test_personal_data_manager_;
+  std::unique_ptr<AutofillOfferManager> autofill_offer_manager_;
+
   GURL form_origin_;
   ukm::SourceId source_id_ = -1;
   std::string variation_config_country_code_;
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.cc b/components/autofill/core/browser/test_browser_autofill_manager.cc
index 9e0318b..ad3bb532 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.cc
+++ b/components/autofill/core/browser/test_browser_autofill_manager.cc
@@ -8,6 +8,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/mock_single_field_form_fill_router.h"
+#include "components/autofill/core/browser/test_autofill_client.h"
+#include "components/autofill/core/browser/test_autofill_driver.h"
 #include "components/autofill/core/browser/test_form_structure.h"
 #include "components/autofill/core/browser/test_personal_data_manager.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -16,13 +18,16 @@
 namespace autofill {
 
 TestBrowserAutofillManager::TestBrowserAutofillManager(
-    AutofillDriver* driver,
-    AutofillClient* client,
-    TestPersonalDataManager* personal_data)
-    : BrowserAutofillManager(driver, client, personal_data),
-      personal_data_(personal_data) {}
+    TestAutofillDriver* driver,
+    TestAutofillClient* client)
+    : BrowserAutofillManager(driver,
+                             client,
+                             "en-US",
+                             EnableDownloadManager(false)),
+      client_(client),
+      driver_(driver) {}
 
-TestBrowserAutofillManager::~TestBrowserAutofillManager() {}
+TestBrowserAutofillManager::~TestBrowserAutofillManager() = default;
 
 bool TestBrowserAutofillManager::IsAutofillProfileEnabled() const {
   return autofill_profile_enabled_;
@@ -98,14 +103,14 @@
     const FormData& form,
     const std::vector<ServerFieldType>& heuristic_types,
     const std::vector<ServerFieldType>& server_types) {
-  std::vector<std::vector<std::pair<PredictionSource, ServerFieldType>>>
+  std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>
       all_heuristic_types;
 
   base::ranges::transform(
       heuristic_types, std::back_inserter(all_heuristic_types),
       [](ServerFieldType type)
-          -> std::vector<std::pair<PredictionSource, ServerFieldType>> {
-        return {{PredictionSource::kDefaultHeuristics, type}};
+          -> std::vector<std::pair<PatternSource, ServerFieldType>> {
+        return {{PatternSource::kDefault, type}};
       });
 
   AddSeenForm(form, all_heuristic_types, server_types);
@@ -113,8 +118,7 @@
 
 void TestBrowserAutofillManager::AddSeenForm(
     const FormData& form,
-    const std::vector<
-        std::vector<std::pair<PredictionSource, ServerFieldType>>>&
+    const std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>&
         heuristic_types,
     const std::vector<ServerFieldType>& server_types) {
   FormData empty_form = form;
@@ -148,17 +152,19 @@
 void TestBrowserAutofillManager::SetAutofillProfileEnabled(
     bool autofill_profile_enabled) {
   autofill_profile_enabled_ = autofill_profile_enabled;
-  if (!autofill_profile_enabled_)
+  if (!autofill_profile_enabled_) {
     // Profile data is refreshed when this pref is changed.
-    personal_data_->ClearProfiles();
+    client()->GetPersonalDataManager()->ClearProfiles();
+  }
 }
 
 void TestBrowserAutofillManager::SetAutofillCreditCardEnabled(
     bool autofill_credit_card_enabled) {
   autofill_credit_card_enabled_ = autofill_credit_card_enabled;
-  if (!autofill_credit_card_enabled_)
+  if (!autofill_credit_card_enabled_) {
     // Credit card data is refreshed when this pref is changed.
-    personal_data_->ClearCreditCards();
+    client()->GetPersonalDataManager()->ClearCreditCards();
+  }
 }
 
 void TestBrowserAutofillManager::SetExpectedSubmittedFieldTypes(
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.h b/components/autofill/core/browser/test_browser_autofill_manager.h
index 83fcc91..4612f7a 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.h
+++ b/components/autofill/core/browser/test_browser_autofill_manager.h
@@ -18,16 +18,15 @@
 
 namespace autofill {
 
-class AutofillClient;
-class AutofillDriver;
+class TestAutofillClient;
+class TestAutofillDriver;
 class FormStructure;
 class TestPersonalDataManager;
 
 class TestBrowserAutofillManager : public BrowserAutofillManager {
  public:
-  TestBrowserAutofillManager(AutofillDriver* driver,
-                             AutofillClient* client,
-                             TestPersonalDataManager* personal_data);
+  TestBrowserAutofillManager(TestAutofillDriver* driver,
+                             TestAutofillClient* client);
 
   TestBrowserAutofillManager(const TestBrowserAutofillManager&) = delete;
   TestBrowserAutofillManager& operator=(const TestBrowserAutofillManager&) =
@@ -35,6 +34,9 @@
 
   ~TestBrowserAutofillManager() override;
 
+  TestAutofillClient* client() { return client_; }
+  TestAutofillDriver* driver() { return driver_; }
+
   // BrowserAutofillManager overrides.
   bool IsAutofillProfileEnabled() const override;
   bool IsAutofillCreditCardEnabled() const override;
@@ -58,8 +60,7 @@
 
   void AddSeenForm(
       const FormData& form,
-      const std::vector<
-          std::vector<std::pair<PredictionSource, ServerFieldType>>>&
+      const std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>&
           heuristic_types,
       const std::vector<ServerFieldType>& server_types);
 
@@ -83,7 +84,9 @@
   using BrowserAutofillManager::pending_form_data;
 
  private:
-  raw_ptr<TestPersonalDataManager> personal_data_;  // Weak reference.
+  TestAutofillClient* client_;
+  TestAutofillDriver* driver_;
+
   bool autofill_profile_enabled_ = true;
   bool autofill_credit_card_enabled_ = true;
   bool call_parent_upload_form_data_ = false;
diff --git a/components/autofill/core/browser/test_form_structure.cc b/components/autofill/core/browser/test_form_structure.cc
index 9a15b818..e76f96c2 100644
--- a/components/autofill/core/browser/test_form_structure.cc
+++ b/components/autofill/core/browser/test_form_structure.cc
@@ -23,27 +23,26 @@
 void TestFormStructure::SetFieldTypes(
     const std::vector<ServerFieldType>& heuristic_types,
     const std::vector<ServerFieldType>& server_types) {
-  std::vector<std::vector<std::pair<PredictionSource, ServerFieldType>>>
+  std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>
       all_heuristic_types;
 
   base::ranges::transform(
       heuristic_types, std::back_inserter(all_heuristic_types),
       [](ServerFieldType type)
-          -> std::vector<std::pair<PredictionSource, ServerFieldType>> {
-        return {{PredictionSource::kDefaultHeuristics, type}};
+          -> std::vector<std::pair<PatternSource, ServerFieldType>> {
+        return {{PatternSource::kDefault, type}};
       });
 
   SetFieldTypes(all_heuristic_types, server_types);
 }
 
 void TestFormStructure::SetFieldTypes(
-    const std::vector<std::vector<
-        std::pair<PredictionSource, ServerFieldType>>>& heuristic_types,
+    const std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>&
+        heuristic_types,
     const std::vector<ServerFieldType>& server_types) {
   ASSERT_EQ(field_count(), heuristic_types.size());
   ASSERT_EQ(field_count(), server_types.size());
-  ASSERT_THAT(heuristic_types,
-              Each(Contains(Pair(PredictionSource::kDefaultHeuristics, _))))
+  ASSERT_THAT(heuristic_types, Each(Contains(Pair(PatternSource::kDefault, _))))
       << "There must be a default heuristic prediction for every field.";
 
   for (size_t i = 0; i < field_count(); ++i) {
diff --git a/components/autofill/core/browser/test_form_structure.h b/components/autofill/core/browser/test_form_structure.h
index 07fc965..a9c2982 100644
--- a/components/autofill/core/browser/test_form_structure.h
+++ b/components/autofill/core/browser/test_form_structure.h
@@ -30,11 +30,11 @@
   // Set the heuristic and server types for each field. The `heuristic_types`
   // and `server_types` vectors must be aligned with the indices of the fields
   // in the form. For each field in `heuristic_types` there must be exactly
-  // `PredictionSource::kDefaultHeuristics` prediction and any number of
-  // alternative predictions.
+  // `PatternSource::kDefault` prediction and any number of alternative
+  // predictions.
   void SetFieldTypes(
-      const std::vector<std::vector<
-          std::pair<PredictionSource, ServerFieldType>>>& heuristic_types,
+      const std::vector<std::vector<std::pair<PatternSource, ServerFieldType>>>&
+          heuristic_types,
       const std::vector<ServerFieldType>& server_types);
 };
 
diff --git a/components/background_task_scheduler/internal/BUILD.gn b/components/background_task_scheduler/internal/BUILD.gn
index d448257..e00f235 100644
--- a/components/background_task_scheduler/internal/BUILD.gn
+++ b/components/background_task_scheduler/internal/BUILD.gn
@@ -104,7 +104,6 @@
       "$google_play_services_package:google_play_services_basement_java",
       "$google_play_services_package:google_play_services_gcm_java",
       "$google_play_services_package:google_play_services_tasks_java",
-      "//base:base_java",
       "//base:base_java_test_support",
       "//build/android:build_java",
       "//components/background_task_scheduler:background_task_scheduler_task_ids_java",
diff --git a/components/bookmarks/common/android/BUILD.gn b/components/bookmarks/common/android/BUILD.gn
index c2f728a9..7423d635 100644
--- a/components/bookmarks/common/android/BUILD.gn
+++ b/components/bookmarks/common/android/BUILD.gn
@@ -18,17 +18,11 @@
 
 android_library("bookmarks_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
-    "//components/url_formatter/android:url_formatter_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
-    "//url:gurl_java",
   ]
   srcjar_deps = [ ":bookmark_type_javagen" ]
-  sources = [
-    "java/src/org/chromium/components/bookmarks/BookmarkId.java",
-    "java/src/org/chromium/components/bookmarks/BookmarkItem.java",
-  ]
+  sources = [ "java/src/org/chromium/components/bookmarks/BookmarkId.java" ]
 }
 
 generate_jni("bookmarks_jni_headers") {
diff --git a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkItem.java b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkItem.java
deleted file mode 100644
index 5192b1c..0000000
--- a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkItem.java
+++ /dev/null
@@ -1,129 +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.
-
-package org.chromium.components.bookmarks;
-
-import org.chromium.components.url_formatter.SchemeDisplay;
-import org.chromium.components.url_formatter.UrlFormatter;
-import org.chromium.url.GURL;
-
-/**
- * Contains data about a bookmark or bookmark folder.
- */
-public class BookmarkItem {
-    private final String mTitle;
-    private final GURL mUrl;
-    private final BookmarkId mId;
-    private final BookmarkId mParentId;
-    private final long mDateAdded;
-    private final boolean mIsFolder;
-    private final boolean mIsEditable;
-    private final boolean mIsManaged;
-    private final boolean mRead;
-    private final boolean mReadingListSwappable;
-
-    private boolean mForceEditableForTesting;
-
-    /**
-     * Constructs a bookmark item.
-     * @param id The id.
-     * @param title The title of the bookmark/folder.
-     * @param url The url of the bookmark.
-     * @param isFolder Whether this item is a folder.
-     * @param parentId The id of the parent.
-     * @param isEditable Whether this item is editable.
-     * @param isManaged Whether this item is managed.
-     * @param dateAdded The date this item was added.
-     * @param read Whether this item has been read (reading list only).
-     * @param readingListSwappable Whether this item is swappable to/from reading list.
-     */
-    public BookmarkItem(BookmarkId id, String title, GURL url, boolean isFolder,
-            BookmarkId parentId, boolean isEditable, boolean isManaged, long dateAdded,
-            boolean read, boolean readingListSwappable) {
-        mId = id;
-        mTitle = title;
-        mUrl = url;
-        mIsFolder = isFolder;
-        mParentId = parentId;
-        mIsEditable = isEditable;
-        mIsManaged = isManaged;
-        mDateAdded = dateAdded;
-        mRead = read;
-        mReadingListSwappable = readingListSwappable;
-    }
-
-    /** Returns the title of the bookmark item. */
-    public String getTitle() {
-        return mTitle;
-    }
-
-    /** Returns the url of the bookmark item. */
-    public GURL getUrl() {
-        return mUrl;
-    }
-
-    /** Returns the string to display for the item's url. */
-    public String getUrlForDisplay() {
-        return UrlFormatter.formatUrlForSecurityDisplay(
-                getUrl(), SchemeDisplay.OMIT_HTTP_AND_HTTPS);
-    }
-
-    /** Returns whether item is a folder or a bookmark. */
-    public boolean isFolder() {
-        return mIsFolder;
-    }
-
-    /** Returns the parent id of the bookmark item. */
-    public BookmarkId getParentId() {
-        return mParentId;
-    }
-
-    /** Returns whether this bookmark can be edited. */
-    public boolean isEditable() {
-        return mForceEditableForTesting || mIsEditable;
-    }
-
-    /** Returns whether this bookmark's URL can be edited */
-    public boolean isUrlEditable() {
-        return isEditable() && mId.getType() == BookmarkType.NORMAL;
-    }
-
-    /** Returns whether this bookmark can be moved */
-    public boolean isMovable() {
-        return mReadingListSwappable || isReorderable();
-    }
-
-    /** Returns whether this bookmark can be moved */
-    public boolean isReorderable() {
-        return isEditable() && mId.getType() == BookmarkType.NORMAL;
-    }
-
-    /** Returns whether this is a managed bookmark. */
-    public boolean isManaged() {
-        return mIsManaged;
-    }
-
-    /** Returns the {@link BookmarkId}. */
-    public BookmarkId getId() {
-        return mId;
-    }
-
-    /** Returns the timestamp in milliseconds since epoch that the bookmark is added. */
-    public long getDateAdded() {
-        return mDateAdded;
-    }
-
-    /**
-     * Returns whether the bookmark is read. Only valid for {@link BookmarkType#READING_LIST}.
-     * Defaults to "false" for other types.
-     */
-    public boolean isRead() {
-        return mRead;
-    }
-
-    // TODO(https://crbug.com/1019217): Remove when BookmarkModel is stubbed in tests instead.
-    public void forceEditableForTesting() {
-        mForceEditableForTesting = true;
-    }
-}
\ No newline at end of file
diff --git a/components/browser_ui/bottomsheet/android/BUILD.gn b/components/browser_ui/bottomsheet/android/BUILD.gn
index e797df6..d8220f0 100644
--- a/components/browser_ui/bottomsheet/android/BUILD.gn
+++ b/components/browser_ui/bottomsheet/android/BUILD.gn
@@ -49,7 +49,6 @@
   deps = [
     ":java",
     ":manager_java",
-    "//base:base_java",
     "//components/browser_ui/widget/android:java",
     "//ui/android:ui_full_java",
     "//ui/android:ui_utils_java",
diff --git a/components/browser_ui/http_auth/android/BUILD.gn b/components/browser_ui/http_auth/android/BUILD.gn
index 6136efe..c55b609 100644
--- a/components/browser_ui/http_auth/android/BUILD.gn
+++ b/components/browser_ui/http_auth/android/BUILD.gn
@@ -11,7 +11,6 @@
 
   deps = [
     ":java_resources",
-    "//base:base_java",
     "//components/browser_ui/widget/android:java",
     "//components/strings:components_strings_grd",
     "//third_party/android_deps:material_design_java",
diff --git a/components/browser_ui/media/android/BUILD.gn b/components/browser_ui/media/android/BUILD.gn
index 7719302..28171ff 100644
--- a/components/browser_ui/media/android/BUILD.gn
+++ b/components/browser_ui/media/android/BUILD.gn
@@ -85,7 +85,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/browser_ui/styles/android/BUILD.gn b/components/browser_ui/styles/android/BUILD.gn
index 960c2dbc..5a924ecd 100644
--- a/components/browser_ui/styles/android/BUILD.gn
+++ b/components/browser_ui/styles/android/BUILD.gn
@@ -12,7 +12,6 @@
   ]
   deps = [
     ":java_resources",
-    "//base:base_java",
     "//third_party/android_deps:material_design_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
diff --git a/components/browser_ui/webshare/android/BUILD.gn b/components/browser_ui/webshare/android/BUILD.gn
index cc96c6e..fb2d4248 100644
--- a/components/browser_ui/webshare/android/BUILD.gn
+++ b/components/browser_ui/webshare/android/BUILD.gn
@@ -34,7 +34,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn
index bc93581b..e02ebeb 100644
--- a/components/browser_ui/widget/android/BUILD.gn
+++ b/components/browser_ui/widget/android/BUILD.gn
@@ -394,7 +394,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java
index d2afdbd..921f22250 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java
@@ -19,12 +19,13 @@
  */
 public interface BackPressHandler {
     // The smaller the value is, the higher the priority is.
-    @IntDef({Type.TEXT_BUBBLE, Type.TEST})
+    @IntDef({Type.TEXT_BUBBLE, Type.TEST, Type.AR_DELEGATE})
     @Retention(RetentionPolicy.SOURCE)
     @interface Type {
         int TEXT_BUBBLE = 0;
+        int AR_DELEGATE = 1;
         // Add new type here and then increment the value of TEST by one.
-        int TEST = 1; // This is for test only. Do not use it in production.
+        int TEST = 2; // This is for test only. Do not use it in production.
         int NUM_TYPES = TEST + 1;
     }
 
diff --git a/components/client_hints/README.md b/components/client_hints/README.md
index e23f5c83..e9bf94a 100644
--- a/components/client_hints/README.md
+++ b/components/client_hints/README.md
@@ -62,7 +62,7 @@
 
 Client Hint preferences are stored in the preferences service as a content setting (`ContentSettingsType::CLIENT_HINTS`), keyed to the origin. This storage is accessed through the [content::ClientHintsControllerDelegate] interface, with the principle implementation being [client_hints::ClientHints] in //components (to share across multiple platforms). The delegate is accessible in the browser process as a property of the [content::BrowserContext] (in //chrome land, this is implemented as the Profile and “Off The Record” Profile. An important note is that there is an “incognito profile” that gets its own client hints storage).
 
-This storage is marked as `content_settings::SessionModel::UserSession`. This means that when settings are read in from disk (on browser start up) there’s also a check for a flag that’s set on graceful shutdown. (This is to exclude crashes and browser updates). If that flag is set, the settings are cleared. Practically, this means that the settings are cleared after closing the browser.
+This storage is marked as `content_settings::SessionModel::Durable`. This means that the client hint settings are read in from disk on browser start up and loaded into memory. Practically, this means that the client hint settings persist until the user clears site data or cookies for the origin.
 
 The code for reading from and writing to the client hint preferences in content is in [/content/browser/client_hints/client_hints.cc]
 
diff --git a/components/commerce/core/android/BUILD.gn b/components/commerce/core/android/BUILD.gn
index 3eaf399..a922f2b 100644
--- a/components/commerce/core/android/BUILD.gn
+++ b/components/commerce/core/android/BUILD.gn
@@ -10,7 +10,6 @@
       [ "java/src/org/chromium/components/commerce/core/ShoppingService.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
diff --git a/components/component_updater/configurator_impl.cc b/components/component_updater/configurator_impl.cc
index c6d75f0..b9dd594e 100644
--- a/components/component_updater/configurator_impl.cc
+++ b/components/component_updater/configurator_impl.cc
@@ -149,7 +149,10 @@
 
 absl::optional<bool> ConfiguratorImpl::IsMachineExternallyManaged() const {
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
-  return base::IsMachineExternallyManaged();
+  // TODO (crbug.com/1320776): For legacy compatibility, this uses
+  // IsEnterpriseDevice() which effectively equates to a domain join check.
+  // Consider whether this should use IsManagedDevice() instead.
+  return base::IsEnterpriseDevice();
 #else
   return absl::nullopt;
 #endif
diff --git a/components/content_capture/android/junit/BUILD.gn b/components/content_capture/android/junit/BUILD.gn
index 3c567a7..17337b0ea 100644
--- a/components/content_capture/android/junit/BUILD.gn
+++ b/components/content_capture/android/junit/BUILD.gn
@@ -15,7 +15,6 @@
     "src/org/chromium/components/content_capture/UrlAllowlistTest.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//components/content_capture/android:java",
diff --git a/components/content_capture/android/test_support/BUILD.gn b/components/content_capture/android/test_support/BUILD.gn
index 2e1a7a3..9761b86 100644
--- a/components/content_capture/android/test_support/BUILD.gn
+++ b/components/content_capture/android/test_support/BUILD.gn
@@ -17,7 +17,6 @@
 
 android_library("java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/android:content_java",
diff --git a/components/content_settings/android/BUILD.gn b/components/content_settings/android/BUILD.gn
index c3807247..9338396 100644
--- a/components/content_settings/android/BUILD.gn
+++ b/components/content_settings/android/BUILD.gn
@@ -19,7 +19,6 @@
   ]
   deps = [
     ":content_settings_enums_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/android:content_java",
diff --git a/components/contextual_search/core/BUILD.gn b/components/contextual_search/core/BUILD.gn
index 96ef8db..6a97b013 100644
--- a/components/contextual_search/core/BUILD.gn
+++ b/components/contextual_search/core/BUILD.gn
@@ -4,12 +4,8 @@
 
 static_library("browser") {
   sources = [
-    "browser/ctr_aggregator.cc",
-    "browser/ctr_aggregator.h",
     "browser/public.cc",
     "browser/public.h",
-    "browser/weekly_activity_storage.cc",
-    "browser/weekly_activity_storage.h",
   ]
   deps = [
     "//base",
@@ -17,14 +13,3 @@
     "//components/prefs:prefs",
   ]
 }
-
-source_set("unit_tests") {
-  testonly = true
-  sources = [ "browser/ctr_aggregator_unittest.cc" ]
-
-  deps = [
-    ":browser",
-    "//base",
-    "//testing/gtest",
-  ]
-}
diff --git a/components/contextual_search/core/browser/ctr_aggregator.cc b/components/contextual_search/core/browser/ctr_aggregator.cc
deleted file mode 100644
index f591cc9..0000000
--- a/components/contextual_search/core/browser/ctr_aggregator.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/contextual_search/core/browser/ctr_aggregator.h"
-
-#include "base/numerics/safe_conversions.h"
-#include "base/time/time.h"
-
-namespace {
-
-const double kSecondsPerWeek =
-    base::Time::kMicrosecondsPerWeek / base::Time::kMicrosecondsPerSecond;
-// Used for validation in debug build.  Week numbers are > 2300 as of year 2016.
-// TODO(donnd): reenable this const.  https://crbug.com/1094008. See below.
-// const int kReasonableMinWeek = 2000;
-
-}  // namespace
-
-namespace contextual_search {
-
-CtrAggregator::CtrAggregator(WeeklyActivityStorage& storage)
-    : storage_(storage) {
-  base::Time now = base::Time::NowFromSystemTime();
-  double now_in_seconds = now.ToDoubleT();
-  week_number_ = now_in_seconds / kSecondsPerWeek;
-  // TODO(donnd): reenable this DCHECK.  Some bots have bad clocks or time
-  // settings, causing flaky test failures. https://crbug.com/1094008.
-  // DCHECK(week_number_ >= kReasonableMinWeek);
-  // NOTE: This initialization may callback into the storage implementation so
-  // that needs to be fully initialized when constructing this aggregator.
-  storage_.AdvanceToWeek(week_number_);
-}
-
-// Testing only
-CtrAggregator::CtrAggregator(WeeklyActivityStorage& storage, int week_number)
-    : storage_(storage), week_number_(week_number) {
-  storage_.AdvanceToWeek(week_number_);
-}
-
-CtrAggregator::~CtrAggregator() {}
-
-void CtrAggregator::RecordImpression(bool did_click) {
-  storage_.WriteImpressions(week_number_,
-                            1 + storage_.ReadImpressions(week_number_));
-  if (did_click)
-    storage_.WriteClicks(week_number_, 1 + storage_.ReadClicks(week_number_));
-}
-
-int CtrAggregator::GetCurrentWeekNumber() {
-  return week_number_;
-}
-
-bool CtrAggregator::HasPreviousWeekData() {
-  return storage_.HasData(week_number_ - 1);
-}
-
-int CtrAggregator::GetPreviousWeekImpressions() {
-  return storage_.ReadImpressions(week_number_ - 1);
-}
-
-float CtrAggregator::GetPreviousWeekCtr() {
-  if (!HasPreviousWeekData())
-    return NAN;
-
-  int clicks = GetPreviousWeekClicks();
-  int impressions = GetPreviousWeekImpressions();
-  if (impressions == 0)
-    return 0.0;
-  return base::saturated_cast<float>(clicks) / impressions;
-}
-
-bool CtrAggregator::HasPrevious28DayData() {
-  for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) {
-    if (!storage_.HasData(week_number_ - previous))
-      return false;
-  }
-  return true;
-}
-
-float CtrAggregator::GetPrevious28DayCtr() {
-  if (!HasPrevious28DayData())
-    return NAN;
-
-  int clicks = GetPrevious28DayClicks();
-  int impressions = GetPrevious28DayImpressions();
-  if (impressions == 0)
-    return 0.0;
-  return base::saturated_cast<float>(clicks) / impressions;
-}
-
-int CtrAggregator::GetPrevious28DayImpressions() {
-  int impressions = 0;
-  for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) {
-    impressions += storage_.ReadImpressions(week_number_ - previous);
-  }
-  return impressions;
-}
-
-// private
-
-int CtrAggregator::GetPreviousWeekClicks() {
-  return storage_.ReadClicks(week_number_ - 1);
-}
-
-int CtrAggregator::GetPrevious28DayClicks() {
-  int clicks = 0;
-  for (int previous = 1; previous <= kNumWeeksNeededFor28DayData; previous++) {
-    clicks += storage_.ReadClicks(week_number_ - previous);
-  }
-  return clicks;
-}
-
-// Testing only
-
-void CtrAggregator::IncrementWeek(int weeks) {
-  week_number_ += weeks;
-  storage_.AdvanceToWeek(week_number_);
-}
-
-}  // namespace contextual_search
diff --git a/components/contextual_search/core/browser/ctr_aggregator.h b/components/contextual_search/core/browser/ctr_aggregator.h
deleted file mode 100644
index 4f50cc9..0000000
--- a/components/contextual_search/core/browser/ctr_aggregator.h
+++ /dev/null
@@ -1,117 +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.
-
-// Provides aggregation of feature usage by tracking impressions and clicks
-// over 1-week and 28-day intervals.  Impressions are views of some UX and
-// clicks are any measured interaction with that UX, yielding CTR -- Click
-// Through Rate.
-// Used by Contextual Search to record impressions of the Bar and CTR of
-// panel opens to use as signals for Tap triggering.
-
-#ifndef COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_CTR_AGGREGATOR_H_
-#define COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_CTR_AGGREGATOR_H_
-
-#include "base/gtest_prod_util.h"
-#include "components/contextual_search/core/browser/weekly_activity_storage.h"
-
-namespace contextual_search {
-
-// Number of weeks of data needed for 28 days.
-const int kNumWeeksNeededFor28DayData = 4;
-
-// Usage: Create a CtrAggregator and start recording impressions or reading
-// aggregated data.  Get data from the previous week or previous 4-week period
-// that ended with the previous week.
-// A new week starts at an arbitrary time based on seconds since the Epoch.
-// The data from the previous week and previous 28-day period are guaranteed to
-// be complete only if the HasPrevious method returns true.  If one of the data
-// accessors is called when the data is not complete invalid data may be
-// returned.
-class CtrAggregator {
- public:
-  // Constructs a CtrAggregator using the given |storage| mechanism.
-  // Data is stored by |storage| typically on persistent device-local storage.
-  // A callback through the storage interface may occur at construction time,
-  // so the |storage| must be fully initialized when this constructor is
-  // called.
-  CtrAggregator(WeeklyActivityStorage& storage);
-
-  CtrAggregator(const CtrAggregator&) = delete;
-  CtrAggregator& operator=(const CtrAggregator&) = delete;
-
-  ~CtrAggregator();
-
-  // Records an impression.  Records a click if |did_click| is true.
-  void RecordImpression(bool did_click);
-
-  // Returns the number for the current week. Useful for checking when the
-  // current week changes.
-  int GetCurrentWeekNumber();
-
-  // Returns whether we have the previous week's data for this user.
-  bool HasPreviousWeekData();
-
-  // Gets the number of impressions from the previous week.
-  // Callers must check if there is previous week's data for this user, or
-  // invalid data may be returned.
-  int GetPreviousWeekImpressions();
-
-  // Gets the CTR from the previous week.
-  // Callers must check if there is previous week's data for this user, or
-  // invalid data may be returned.
-  float GetPreviousWeekCtr();
-
-  // Returns whether we have data from a 28 day period ending in the previous
-  // week.
-  bool HasPrevious28DayData();
-
-  // Gets the number of impressions from a 28 day period ending in the previous
-  // week.
-  // Callers must check if there is previous 28 day data for this user, or
-  // invalid data may be returned.
-  int GetPrevious28DayImpressions();
-
-  // Gets the CTR from a 28 day period ending in the previous week.
-  // Callers must check if there is previous 28 day data for this user, or
-  // invalid data may be returned.
-  float GetPrevious28DayCtr();
-
- private:
-  // This implementation uses a fixed number of bins to store integer impression
-  // and click data for the most recent N weeks, where N = 5 (in order to keep 4
-  // complete weeks).  Another bin keeps track of the current week being
-  // written.  Yet another bin records when data was first stored or accessed so
-  // we can know when a time period has complete data.
-  friend class CtrAggregatorTest;
-  FRIEND_TEST_ALL_PREFIXES(CtrAggregatorTest, SimpleOperationTest);
-  FRIEND_TEST_ALL_PREFIXES(CtrAggregatorTest, MultiWeekTest);
-  FRIEND_TEST_ALL_PREFIXES(CtrAggregatorTest, SkipOneWeekTest);
-  FRIEND_TEST_ALL_PREFIXES(CtrAggregatorTest, SkipThreeWeeksTest);
-  FRIEND_TEST_ALL_PREFIXES(CtrAggregatorTest, SkipFourWeeksTest);
-
-  // Constructs an instance for testing; sets the week.
-  CtrAggregator(WeeklyActivityStorage& storage, int week_number);
-  // For testing, increments the current week number by |weeks|.
-  void IncrementWeek(int weeks);
-
-  // Gets the number of clicks from the previous week.
-  // Callers must check if there is previous week's data for this user, or
-  // invalid data may be returned.
-  int GetPreviousWeekClicks();
-  // Gets the number of clicks from a 28 day period ending in the previous
-  // week.
-  // Callers must check if there is previous 28 day data for this user, or
-  // invalid data may be returned.
-  int GetPrevious28DayClicks();
-
-  // Stores the weekly activity data.
-  WeeklyActivityStorage& storage_;
-
-  // The current week number, expressed as the number of weeks since Epoch.
-  int week_number_;
-};
-
-}  // namespace contextual_search
-
-#endif  // COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_CTR_AGGREGATOR_H_
diff --git a/components/contextual_search/core/browser/ctr_aggregator_unittest.cc b/components/contextual_search/core/browser/ctr_aggregator_unittest.cc
deleted file mode 100644
index 3a3f3d5..0000000
--- a/components/contextual_search/core/browser/ctr_aggregator_unittest.cc
+++ /dev/null
@@ -1,176 +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.
-
-#include "components/contextual_search/core/browser/ctr_aggregator.h"
-
-#include <memory>
-#include <unordered_map>
-
-#include "base/gtest_prod_util.h"
-#include "base/values.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::Value;
-
-namespace {
-const int kTestWeek = 2500;
-}
-
-namespace contextual_search {
-
-class CtrAggregatorTest : public testing::Test {
- public:
-  CtrAggregatorTest() {}
-
-  CtrAggregatorTest(const CtrAggregatorTest&) = delete;
-  CtrAggregatorTest& operator=(const CtrAggregatorTest&) = delete;
-
-  ~CtrAggregatorTest() override {}
-
-  class WeeklyActivityStorageStub : public WeeklyActivityStorage {
-   public:
-    WeeklyActivityStorageStub();
-
-   private:
-    int ReadClicksForWeekRemainder(int week_remainder) override;
-    int ReadImpressionsForWeekRemainder(int week_remainder) override;
-    int ReadOldestWeekWritten() override;
-    int ReadNewestWeekWritten() override;
-    void WriteClicksForWeekRemainder(int week_remainder, int value) override;
-    void WriteImpressionsForWeekRemainder(int week_remainder,
-                                          int value) override;
-    void WriteOldestWeekWritten(int value) override;
-    void WriteNewestWeekWritten(int value) override;
-
-    std::unordered_map<int, int> clicks_;
-    std::unordered_map<int, int> impressions_;
-    int oldest_week_;
-    int newest_week_;
-  };
-
-  // Test helpers
-  void Fill4Weeks();  // Fill 4 weeks with 2 impressions, 1 click.
-
-  // The class under test.
-  std::unique_ptr<CtrAggregator> aggregator_;
-
- protected:
-  // The storage stub.
-  std::unique_ptr<WeeklyActivityStorage> storage_;
-
-  void SetUp() override {
-    storage_ = std::make_unique<WeeklyActivityStorageStub>();
-    aggregator_.reset(new CtrAggregator(*storage_, kTestWeek));
-  }
-
-  void TearDown() override {}
-};
-
-CtrAggregatorTest::WeeklyActivityStorageStub::WeeklyActivityStorageStub()
-    : WeeklyActivityStorage(4), oldest_week_(0), newest_week_(0) {}
-
-int CtrAggregatorTest::WeeklyActivityStorageStub::ReadClicksForWeekRemainder(
-    int week_remainder) {
-  return clicks_[week_remainder];
-}
-
-int CtrAggregatorTest::WeeklyActivityStorageStub::
-    ReadImpressionsForWeekRemainder(int week_remainder) {
-  return impressions_[week_remainder];
-}
-
-int CtrAggregatorTest::WeeklyActivityStorageStub::ReadOldestWeekWritten() {
-  return oldest_week_;
-}
-
-int CtrAggregatorTest::WeeklyActivityStorageStub::ReadNewestWeekWritten() {
-  return newest_week_;
-}
-
-void CtrAggregatorTest::WeeklyActivityStorageStub::WriteClicksForWeekRemainder(
-    int week_remainder,
-    int value) {
-  clicks_[week_remainder] = value;
-}
-
-void CtrAggregatorTest::WeeklyActivityStorageStub::
-    WriteImpressionsForWeekRemainder(int week_remainder, int value) {
-  impressions_[week_remainder] = value;
-}
-
-void CtrAggregatorTest::WeeklyActivityStorageStub::WriteOldestWeekWritten(
-    int value) {
-  oldest_week_ = value;
-}
-
-void CtrAggregatorTest::WeeklyActivityStorageStub::WriteNewestWeekWritten(
-    int value) {
-  newest_week_ = value;
-}
-
-void CtrAggregatorTest::Fill4Weeks() {
-  int weeks_to_record = 4;
-  for (int i = 0; i < weeks_to_record; i++) {
-    aggregator_->RecordImpression(true);
-    aggregator_->RecordImpression(false);
-    EXPECT_FALSE(aggregator_->HasPrevious28DayData());
-    aggregator_->IncrementWeek(1);
-  }
-  EXPECT_TRUE(aggregator_->HasPrevious28DayData());
-}
-
-// NaN has the property that it is not equal to itself.
-#define EXPECT_NAN(x) EXPECT_NE(x, x)
-
-TEST_F(CtrAggregatorTest, SimpleOperationTest) {
-  aggregator_->RecordImpression(true);
-  aggregator_->RecordImpression(false);
-  EXPECT_FALSE(aggregator_->HasPreviousWeekData());
-  EXPECT_EQ(0, aggregator_->GetPreviousWeekImpressions());
-  EXPECT_NAN(aggregator_->GetPreviousWeekCtr());
-
-  aggregator_->IncrementWeek(1);
-  EXPECT_TRUE(aggregator_->HasPreviousWeekData());
-  EXPECT_EQ(2, aggregator_->GetPreviousWeekImpressions());
-  EXPECT_FLOAT_EQ(0.5f, aggregator_->GetPreviousWeekCtr());
-}
-
-TEST_F(CtrAggregatorTest, MultiWeekTest) {
-  Fill4Weeks();
-  aggregator_->RecordImpression(false);
-  aggregator_->IncrementWeek(1);
-  EXPECT_TRUE(aggregator_->HasPrevious28DayData());
-  EXPECT_FLOAT_EQ(static_cast<float>(3.0 / 7),
-                  aggregator_->GetPrevious28DayCtr());
-  aggregator_->RecordImpression(false);
-  aggregator_->IncrementWeek(1);
-  EXPECT_TRUE(aggregator_->HasPrevious28DayData());
-  EXPECT_FLOAT_EQ(static_cast<float>(2.0 / 6),
-                  aggregator_->GetPrevious28DayCtr());
-}
-
-TEST_F(CtrAggregatorTest, SkipOneWeekTest) {
-  Fill4Weeks();
-  aggregator_->IncrementWeek(1);
-  EXPECT_EQ(0, aggregator_->GetPreviousWeekCtr());
-  EXPECT_FLOAT_EQ(static_cast<float>(3.0 / 6),
-                  aggregator_->GetPrevious28DayCtr());
-}
-
-TEST_F(CtrAggregatorTest, SkipThreeWeeksTest) {
-  Fill4Weeks();
-  aggregator_->IncrementWeek(3);
-  EXPECT_EQ(0, aggregator_->GetPreviousWeekCtr());
-  EXPECT_FLOAT_EQ(static_cast<float>(1.0 / 2),
-                  aggregator_->GetPrevious28DayCtr());
-}
-
-TEST_F(CtrAggregatorTest, SkipFourWeeksTest) {
-  Fill4Weeks();
-  aggregator_->IncrementWeek(4);
-  EXPECT_EQ(0, aggregator_->GetPreviousWeekCtr());
-  EXPECT_EQ(0, aggregator_->GetPrevious28DayCtr());
-}
-
-}  // namespace contextual_search
diff --git a/components/contextual_search/core/browser/weekly_activity_storage.cc b/components/contextual_search/core/browser/weekly_activity_storage.cc
deleted file mode 100644
index b60e9a6..0000000
--- a/components/contextual_search/core/browser/weekly_activity_storage.cc
+++ /dev/null
@@ -1,98 +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.
-
-#include "components/contextual_search/core/browser/weekly_activity_storage.h"
-
-#include <algorithm>  // std::min
-
-#include "base/check.h"
-
-namespace {
-
-// Used for validation in debug build.  Week numbers are > 2300 as of year 2016.
-// TODO(donnd): reenable this const.  https://crbug.com/1094008. See below.
-// const int kReasonableMinWeek = 2000;
-
-}  // namespace
-
-namespace contextual_search {
-
-WeeklyActivityStorage::WeeklyActivityStorage(int weeks_needed) {
-  weeks_needed_ = weeks_needed;
-}
-
-WeeklyActivityStorage::~WeeklyActivityStorage() {}
-
-int WeeklyActivityStorage::ReadClicks(int week_number) {
-  return ReadClicksForWeekRemainder(GetWeekRemainder(week_number));
-}
-
-void WeeklyActivityStorage::WriteClicks(int week_number, int value) {
-  WriteClicksForWeekRemainder(GetWeekRemainder(week_number), value);
-}
-
-int WeeklyActivityStorage::ReadImpressions(int week_number) {
-  return ReadImpressionsForWeekRemainder(GetWeekRemainder(week_number));
-}
-
-void WeeklyActivityStorage::WriteImpressions(int week_number, int value) {
-  WriteImpressionsForWeekRemainder(GetWeekRemainder(week_number), value);
-}
-
-bool WeeklyActivityStorage::HasData(int week_number) {
-  return ReadOldestWeekWritten() <= week_number &&
-         ReadNewestWeekWritten() >= week_number;
-}
-
-void WeeklyActivityStorage::AdvanceToWeek(int week_number) {
-  EnsureHasActivity(week_number);
-}
-
-// private
-
-// Round-robin implementation:
-// GetWeekRemainder and EnsureHasActivity are implemented with a round-robin
-// implementation that simply recycles usage of the last N weeks, where N is
-// less than weeks_needed_.
-
-int WeeklyActivityStorage::GetWeekRemainder(int which_week) {
-  return which_week % (weeks_needed_ + 1);
-}
-
-void WeeklyActivityStorage::EnsureHasActivity(int which_week) {
-  // TODO(donnd): reenable this DCHECK.  Some bots have bad clocks or time
-  // settings, causing flaky test failures. https://crbug.com/1094008.
-  // DCHECK(which_week > kReasonableMinWeek);
-
-  // If still on the newest week we're done!
-  int newest_week = ReadNewestWeekWritten();
-  if (newest_week == which_week)
-    return;
-
-  // Update the newest and oldest week written.
-  if (which_week > newest_week) {
-    WriteNewestWeekWritten(which_week);
-  }
-  int oldest_week = ReadOldestWeekWritten();
-  if (oldest_week == 0 || oldest_week > which_week)
-    WriteOldestWeekWritten(which_week);
-
-  // Any stale weeks to update?
-  if (newest_week == 0)
-    return;
-
-  // Moved to some new week beyond the newest previously recorded.
-  // Since we recycle storage we must clear the new week and all that we
-  // may have skipped since our last access.
-  int weeks_to_clear = std::min(which_week - newest_week, weeks_needed_);
-  int week = which_week;
-  while (weeks_to_clear > 0) {
-    WriteImpressionsForWeekRemainder(GetWeekRemainder(week), 0);
-    WriteClicksForWeekRemainder(GetWeekRemainder(week), 0);
-    week--;
-    weeks_to_clear--;
-  }
-}
-
-}  // namespace contextual_search
diff --git a/components/contextual_search/core/browser/weekly_activity_storage.h b/components/contextual_search/core/browser/weekly_activity_storage.h
deleted file mode 100644
index 4a1f599b..0000000
--- a/components/contextual_search/core/browser/weekly_activity_storage.h
+++ /dev/null
@@ -1,76 +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.
-
-#ifndef COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_WEEKLY_ACTIVITY_STORAGE_H_
-#define COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_WEEKLY_ACTIVITY_STORAGE_H_
-
-namespace contextual_search {
-
-// An abstract class that stores weekly user interaction data in device-specific
-// integer storage. Only a limited storage window is supported, set through the
-// constructor. Allows callers to read and write user actions to persistent
-// storage on the device by overriding the ReadStorage and WriteStorage calls.
-// A user view of some UX is an "Impression", and user interaction is considered
-// a "Click" even if the triggering gesture was something else.  Together they
-// produce the Click-Through-Rate, or CTR.
-class WeeklyActivityStorage {
- public:
-  // Constructs an instance that will manage at least |weeks_needed| weeks of
-  // data.
-  WeeklyActivityStorage(int weeks_needed);
-
-  WeeklyActivityStorage(const WeeklyActivityStorage&) = delete;
-  WeeklyActivityStorage& operator=(const WeeklyActivityStorage&) = delete;
-
-  virtual ~WeeklyActivityStorage();
-
-  // Advances the accessible storage range to end at the given |week_number|.
-  // Since only a limited number of storage weeks are supported, advancing to
-  // a different week makes data from weeks than the range size inaccessible.
-  // This must be called for each week before reading or writing any data
-  // for that week.
-  // HasData will return true for all the weeks that still have accessible data.
-  void AdvanceToWeek(int week_number);
-
-  // Returns the number of clicks for the given week.
-  int ReadClicks(int week_number);
-  // Writes |value| into the number of clicks for the given |week_number|.
-  void WriteClicks(int week_number, int value);
-
-  // Returns the number of impressions for the given week.
-  int ReadImpressions(int week_number);
-  // Writes |value| into the number of impressions for the given |week_number|.
-  void WriteImpressions(int week_number, int value);
-
-  // Returns whether the given |week_number| has data, based on whether
-  // InitData has ever been called for that week.
-  bool HasData(int week_number);
-
-  // Reads and returns values from persistent storage.
-  // If there is no stored value then 0 is returned.
-  virtual int ReadClicksForWeekRemainder(int week_remainder) = 0;
-  virtual int ReadImpressionsForWeekRemainder(int week_remainder) = 0;
-  virtual int ReadOldestWeekWritten() = 0;
-  virtual int ReadNewestWeekWritten() = 0;
-  // Writes values to persistent storage.
-  virtual void WriteClicksForWeekRemainder(int week_remainder, int value) = 0;
-  virtual void WriteImpressionsForWeekRemainder(int week_remainder,
-                                                int value) = 0;
-  virtual void WriteOldestWeekWritten(int value) = 0;
-  virtual void WriteNewestWeekWritten(int value) = 0;
-
- private:
-  // Returns the key to bin information about the given week |which_week|.
-  int GetWeekRemainder(int which_week);
-
-  // Ensures that activity data is initialized for the given week |which_week|.
-  void EnsureHasActivity(int which_week);
-
-  // The number of weeks of data that this instance needs to support.
-  int weeks_needed_;
-};
-
-}  // namespace contextual_search
-
-#endif  // COMPONENTS_CONTEXTUAL_SEARCH_CORE_BROWSER_WEEKLY_ACTIVITY_STORAGE_H_
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn
index 65ec7fa..63a0d91 100644
--- a/components/crash/android/BUILD.gn
+++ b/components/crash/android/BUILD.gn
@@ -64,7 +64,6 @@
     ":anr_collector_java",
     ":anr_data_proto_java",
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//third_party/android_deps:robolectric_all_java",
@@ -105,7 +104,6 @@
 
 android_library("handler_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
diff --git a/components/cronet/ios/Cronet.h b/components/cronet/ios/Cronet.h
index 13bf535..4759d30 100644
--- a/components/cronet/ios/Cronet.h
+++ b/components/cronet/ios/Cronet.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef COMPONENTS_CRONET_IOS_CRONET_H_
+#define COMPONENTS_CRONET_IOS_CRONET_H_
+
 #import <Foundation/Foundation.h>
 
 #include "bidirectional_stream_c.h"
@@ -208,3 +211,5 @@
 + (void)enableTestCertVerifierForTesting;
 
 @end
+
+#endif  // COMPONENTS_CRONET_IOS_CRONET_H_
diff --git a/components/cronet/ios/test/start_cronet.h b/components/cronet/ios/test/start_cronet.h
index 47962b1..9d506663 100644
--- a/components/cronet/ios/test/start_cronet.h
+++ b/components/cronet/ios/test/start_cronet.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef COMPONENTS_CRONET_IOS_TEST_START_CRONET_H_
+#define COMPONENTS_CRONET_IOS_TEST_START_CRONET_H_
+
 namespace cronet {
 
 // Starts Cronet, or restarts if Cronet is already running.  Will have Cronet
@@ -9,3 +12,5 @@
 void StartCronet(int port);
 
 }  // namespace cronet
+
+#endif  // COMPONENTS_CRONET_IOS_TEST_START_CRONET_H_
diff --git a/components/cronet/native/perftest/perf_test.h b/components/cronet/native/perftest/perf_test.h
index c3ccb99b..b97e4d2 100644
--- a/components/cronet/native/perftest/perf_test.h
+++ b/components/cronet/native/perftest/perf_test.h
@@ -2,6 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef COMPONENTS_CRONET_NATIVE_PERFTEST_PERF_TEST_H_
+#define COMPONENTS_CRONET_NATIVE_PERFTEST_PERF_TEST_H_
+
 // Run Cronet native performance test. |json_args| is the string containing
 // the JSON formatted arguments from components/cronet/native/perftest/run.py.
 void PerfTest(const char* json_args);
+
+#endif  // COMPONENTS_CRONET_NATIVE_PERFTEST_PERF_TEST_H_
diff --git a/components/dom_distiller/content/browser/android/BUILD.gn b/components/dom_distiller/content/browser/android/BUILD.gn
index 939fdabd..741eb0e 100644
--- a/components/dom_distiller/content/browser/android/BUILD.gn
+++ b/components/dom_distiller/content/browser/android/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("dom_distiller_content_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/dom_distiller/core/android:dom_distiller_core_java",
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn
index 9d74c12..cb5c98c 100644
--- a/components/download/public/common/BUILD.gn
+++ b/components/download/public/common/BUILD.gn
@@ -120,7 +120,6 @@
     srcjar_deps = [ ":jni_enums" ]
 
     deps = [
-      "//base:base_java",
       "//components/download/internal/common:internal_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
     ]
diff --git a/components/download/public/task/BUILD.gn b/components/download/public/task/BUILD.gn
index 699fcd2..124cbba 100644
--- a/components/download/public/task/BUILD.gn
+++ b/components/download/public/task/BUILD.gn
@@ -32,10 +32,7 @@
   android_library("public_java") {
     srcjar_deps = [ ":jni_enums" ]
 
-    deps = [
-      "//base:base_java",
-      "//third_party/androidx:androidx_annotation_annotation_java",
-    ]
+    deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
   }
 
   java_cpp_enum("jni_enums") {
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn
index 58a6a4b..1819696 100644
--- a/components/embedder_support/android/BUILD.gn
+++ b/components/embedder_support/android/BUILD.gn
@@ -21,10 +21,7 @@
 
 android_library("simple_factory_key_java") {
   sources = [ "java/src/org/chromium/components/embedder_support/simple_factory_key/SimpleFactoryKeyHandle.java" ]
-  deps = [
-    "//base:base_java",
-    "//base:jni_java",
-  ]
+  deps = [ "//base:jni_java" ]
 }
 
 generate_jni("simple_factory_key_jni_headers") {
@@ -149,7 +146,6 @@
 
 android_library("view_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/android:content_java",
@@ -264,7 +260,6 @@
 
 android_library("context_menu_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -280,7 +275,6 @@
   testonly = true
   deps = [
     ":util_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/junit",
@@ -335,7 +329,6 @@
     ":util_java",
     ":web_contents_delegate_java",
     ":web_contents_delegate_java_resources",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//content/public/test/android:content_java_test_support",
diff --git a/components/favicon/android/BUILD.gn b/components/favicon/android/BUILD.gn
index 63d3eac..076d0cd 100644
--- a/components/favicon/android/BUILD.gn
+++ b/components/favicon/android/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [ "java/src/org/chromium/components/favicon/LargeIconBridge.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/browser_ui/util/android:java",
diff --git a/components/feed/core/proto/BUILD.gn b/components/feed/core/proto/BUILD.gn
index 2b1d9bc..59e042d2 100644
--- a/components/feed/core/proto/BUILD.gn
+++ b/components/feed/core/proto/BUILD.gn
@@ -42,6 +42,7 @@
     "v2/wire/feed_query.proto",
     "v2/wire/feed_request.proto",
     "v2/wire/feed_response.proto",
+    "v2/wire/info_card.proto",
     "v2/wire/next_page_token.proto",
     "v2/wire/payload_metadata.proto",
     "v2/wire/reliability_logging_enums.proto",
diff --git a/components/feed/core/proto/v2/wire/chrome_fulfillment_info.proto b/components/feed/core/proto/v2/wire/chrome_fulfillment_info.proto
index 31fc375..321b0a16 100644
--- a/components/feed/core/proto/v2/wire/chrome_fulfillment_info.proto
+++ b/components/feed/core/proto/v2/wire/chrome_fulfillment_info.proto
@@ -6,9 +6,12 @@
 
 package feedwire;
 
+import "components/feed/core/proto/v2/wire/info_card.proto";
+
 option optimize_for = LITE_RUNTIME;
 
 message ChromeFulfillmentInfo {
   optional bool notice_card_acknowledged = 1;
   repeated string acknowledged_notice_key = 2;
+  repeated InfoCardTrackingState info_card_tracking_state = 3;
 }
diff --git a/components/feed/core/proto/v2/wire/info_card.proto b/components/feed/core/proto/v2/wire/info_card.proto
new file mode 100644
index 0000000..7e19343
--- /dev/null
+++ b/components/feed/core/proto/v2/wire/info_card.proto
@@ -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.
+
+syntax = "proto2";
+
+package feedwire;
+
+option optimize_for = LITE_RUNTIME;
+
+enum InfoCardType {
+  INFO_CARD_NONE = 0;
+  INFO_CARD_MAIN_PRIVACY_NOTICE = 1;
+  INFO_CARD_YOUTUBE_PRIVACY_NOTICE = 2;
+}
+message InfoCardTrackingState {
+  optional InfoCardType type = 1;
+  optional int32 explicitly_dismissed_count = 2;
+  optional int32 view_count = 3;
+  optional int32 click_count = 4;
+  optional uint64 first_view_timestamp = 5;
+  optional uint64 last_view_timestamp = 6;
+}
\ No newline at end of file
diff --git a/components/gcm_driver/instance_id/android/BUILD.gn b/components/gcm_driver/instance_id/android/BUILD.gn
index 889f30f..251afe2d 100644
--- a/components/gcm_driver/instance_id/android/BUILD.gn
+++ b/components/gcm_driver/instance_id/android/BUILD.gn
@@ -37,7 +37,6 @@
   deps = [
     ":instance_id_driver_java",
     "$google_play_services_package:google_play_services_iid_java",
-    "//base:base_java",
     "//base:jni_java",
   ]
 
diff --git a/components/heap_profiling/multi_process/BUILD.gn b/components/heap_profiling/multi_process/BUILD.gn
index a29e806..42400d5 100644
--- a/components/heap_profiling/multi_process/BUILD.gn
+++ b/components/heap_profiling/multi_process/BUILD.gn
@@ -34,10 +34,7 @@
   android_library("heap_profiling_java_test_support") {
     testonly = true
     sources = [ "javatests/src/org/chromium/components/heap_profiling/multi_process/HeapProfilingTestShim.java" ]
-    deps = [
-      "//base:base_java",
-      "//build/android:build_java",
-    ]
+    deps = [ "//build/android:build_java" ]
   }
 }
 
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc
index 455f6f18..56807a3c5 100644
--- a/components/history_clusters/core/config.cc
+++ b/components/history_clusters/core/config.cc
@@ -73,6 +73,10 @@
       internal::kOmniboxAction, "omnibox_action_on_urls",
       omnibox_action_on_urls);
 
+  omnibox_action_on_noisy_urls = base::GetFieldTrialParamByFeatureAsBool(
+      internal::kOmniboxAction, "omnibox_action_on_noisy_urls",
+      omnibox_action_on_noisy_urls);
+
   non_user_visible_debug =
       base::FeatureList::IsEnabled(internal::kNonUserVisibleDebug);
 
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h
index b36919a..6f3e8b2 100644
--- a/components/history_clusters/core/config.h
+++ b/components/history_clusters/core/config.h
@@ -79,6 +79,10 @@
   // does nothing if `omnibox_action` is disabled.
   bool omnibox_action_on_urls = false;
 
+  // If enabled, allows the Omnibox Action chip to appear on URLs from noisy
+  // visits. This does nothing if `omnibox_action_on_urls` is false.
+  bool omnibox_action_on_noisy_urls = true;
+
   // Enables debug info in non-user-visible surfaces, like Chrome Inspector.
   // Does nothing if `kJourneys` is disabled.
   bool non_user_visible_debug = false;
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc
index 01a16f6..3f1b69e 100644
--- a/components/history_clusters/core/history_clusters_service.cc
+++ b/components/history_clusters/core/history_clusters_service.cc
@@ -317,6 +317,15 @@
     // Push a simplified form of the URL for each visit into the cache.
     if (url_keyword_accumulator->size() < max_keyword_phrases) {
       for (const auto& visit : cluster.visits) {
+        if (visit.engagement_score >
+                GetConfig().noisy_cluster_visits_engagement_threshold &&
+            !GetConfig().omnibox_action_on_noisy_urls) {
+          // Do not add a noisy visit to the URL keyword accumulator if not
+          // enabled via flag. Note that this is at the visit-level rather than
+          // at the cluster-level, which is handled by the NoisyClusterFinalizer
+          // in the ClusteringBackend.
+          continue;
+        }
         url_keyword_accumulator->insert(
             (!visit.annotated_visit.content_annotations.search_normalized_url
                   .is_empty())
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc
index 775546b..5aa1fe44 100644
--- a/components/history_clusters/core/history_clusters_service_unittest.cc
+++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -29,6 +29,7 @@
 #include "components/history_clusters/core/features.h"
 #include "components/history_clusters/core/history_clusters_service_test_api.h"
 #include "components/history_clusters/core/history_clusters_types.h"
+#include "components/history_clusters/core/history_clusters_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -58,13 +59,16 @@
 
   // Fetches a scored visit by an ID. `visit_id` must be valid. This is a
   // convenience method used for constructing the fake response.
-  history::ClusterVisit GetVisitById(int visit_id, float score = 0.5) {
+  history::ClusterVisit GetVisitById(int visit_id,
+                                     float score = 0.5,
+                                     int engagement_score = 0) {
     for (auto& visit : last_clustered_visits_) {
       if (visit.visit_row.visit_id == visit_id) {
         history::ClusterVisit cluster_visit;
         cluster_visit.annotated_visit = visit;
         cluster_visit.normalized_url = visit.url_row.url();
         cluster_visit.score = score;
+        cluster_visit.engagement_score = engagement_score;
         return cluster_visit;
       }
     }
@@ -738,6 +742,183 @@
   EXPECT_TRUE(history_clusters_service_->DoesQueryMatchAnyCluster("peach"));
 }
 
+TEST_F(HistoryClustersServiceTest, DoesURLMatchAnyClusterWithNoisyURLs) {
+  Config config;
+  config.omnibox_action_on_urls = true;
+  config.omnibox_action_on_noisy_urls = true;
+  SetConfigForTesting(config);
+
+  AddHardcodedTestDataToHistoryService();
+
+  // Verify that initially, the test URL doesn't match anything, but this
+  // query should have kicked off a cache population request. This is the URL
+  // for visit 5.
+  EXPECT_FALSE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Helper to flush out the multiple history and cluster backend requests made
+  // by `DoesURLMatchAnyCluster()`. It won't populate the cache until all its
+  // requests have been completed. It makes 1 request (to each) per unique day
+  // with at least 1 visit; i.e. `number_of_days_with_visits`.
+  const auto flush_keyword_requests = [&](size_t number_of_days_with_visits) {
+    test_clustering_backend_->WaitForGetClustersCall();
+
+    std::vector<history::Cluster> clusters;
+    clusters.push_back(history::Cluster(
+        0,
+        {
+            test_clustering_backend_->GetVisitById(5),
+            test_clustering_backend_->GetVisitById(
+                /*visit_id=*/2, /*score=*/0.0, /*engagement_score=*/20.0),
+        },
+        {u"apples", u"oranges", u"z", u"apples bananas"},
+        /*should_show_on_prominent_ui_surfaces=*/true));
+    clusters.push_back(
+        history::Cluster(0,
+                         {
+                             test_clustering_backend_->GetVisitById(5),
+                             test_clustering_backend_->GetVisitById(2),
+                         },
+                         {u"sensitive"},
+                         /*should_show_on_prominent_ui_surfaces=*/false));
+    clusters.push_back(
+        history::Cluster(0,
+                         {
+                             test_clustering_backend_->GetVisitById(2),
+                         },
+                         {u"singlevisit"},
+                         /*should_show_on_prominent_ui_surfaces=*/true));
+
+    test_clustering_backend_->FulfillCallback(clusters);
+
+    // `DoesQueryMatchAnyCluster()` will continue making history and cluster
+    // backend requests until it has exhausted history. We have to flush out
+    // these requests before it will populate the cache.
+    for (size_t i = 0; i < number_of_days_with_visits - 1; ++i) {
+      test_clustering_backend_->WaitForGetClustersCall();
+      history::BlockUntilHistoryProcessesPendingRequests(
+          history_service_.get());
+      test_clustering_backend_->FulfillCallback({});
+    }
+    // One last wait to flush out the last, empty history request.
+    history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
+  };
+
+  // Hardcoded test visits span 3 days (1-day-old, 2-days-old, and 60-day-old).
+  flush_keyword_requests(3);
+
+  // Now the exact query should match the populated cache.
+  EXPECT_TRUE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Github should be shown since we are including visits from noisy URLs.
+  EXPECT_TRUE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://github.com/"))));
+
+  // Deleting a history entry should clear the keyword cache.
+  history_service_->DeleteURLs({GURL{"https://google.com/"}});
+  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
+  EXPECT_FALSE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Visits now span 2 days (1-day-old and 60-day-old) since we deleted the only
+  // 2-day-old visit.
+  flush_keyword_requests(2);
+
+  // The keyword cache should be repopulated.
+  EXPECT_TRUE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+}
+
+TEST_F(HistoryClustersServiceTest, DoesURLMatchAnyClusterNoNoisyURLs) {
+  Config config;
+  config.omnibox_action_on_urls = true;
+  config.omnibox_action_on_noisy_urls = false;
+  SetConfigForTesting(config);
+
+  AddHardcodedTestDataToHistoryService();
+
+  // Verify that initially, the test URL doesn't match anything, but this
+  // query should have kicked off a cache population request. This is the URL
+  // for visit 5.
+  EXPECT_FALSE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Helper to flush out the multiple history and cluster backend requests made
+  // by `DoesURLMatchAnyCluster()`. It won't populate the cache until all its
+  // requests have been completed. It makes 1 request (to each) per unique day
+  // with at least 1 visit; i.e. `number_of_days_with_visits`.
+  const auto flush_keyword_requests = [&](size_t number_of_days_with_visits) {
+    test_clustering_backend_->WaitForGetClustersCall();
+
+    std::vector<history::Cluster> clusters;
+    clusters.push_back(history::Cluster(
+        0,
+        {
+            test_clustering_backend_->GetVisitById(5),
+            test_clustering_backend_->GetVisitById(
+                /*visit_id=*/2, /*score=*/0.0, /*engagement_score=*/20.0),
+        },
+        {u"apples", u"oranges", u"z", u"apples bananas"},
+        /*should_show_on_prominent_ui_surfaces=*/true));
+    clusters.push_back(
+        history::Cluster(0,
+                         {
+                             test_clustering_backend_->GetVisitById(5),
+                             test_clustering_backend_->GetVisitById(2),
+                         },
+                         {u"sensitive"},
+                         /*should_show_on_prominent_ui_surfaces=*/false));
+    clusters.push_back(
+        history::Cluster(0,
+                         {
+                             test_clustering_backend_->GetVisitById(2),
+                         },
+                         {u"singlevisit"},
+                         /*should_show_on_prominent_ui_surfaces=*/true));
+
+    test_clustering_backend_->FulfillCallback(clusters);
+
+    // `DoesQueryMatchAnyCluster()` will continue making history and cluster
+    // backend requests until it has exhausted history. We have to flush out
+    // these requests before it will populate the cache.
+    for (size_t i = 0; i < number_of_days_with_visits - 1; ++i) {
+      test_clustering_backend_->WaitForGetClustersCall();
+      history::BlockUntilHistoryProcessesPendingRequests(
+          history_service_.get());
+      test_clustering_backend_->FulfillCallback({});
+    }
+    // One last wait to flush out the last, empty history request.
+    history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
+  };
+
+  // Hardcoded test visits span 3 days (1-day-old, 2-days-old, and 60-day-old).
+  flush_keyword_requests(3);
+
+  // Now the exact query should match the populated cache.
+  EXPECT_TRUE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Github should never be shown (highly-engaged for cluster 1, sensitive for
+  // cluster 2, single visit cluster for cluster 3).
+  EXPECT_FALSE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://github.com/"))));
+
+  // Deleting a history entry should clear the keyword cache.
+  history_service_->DeleteURLs({GURL{"https://google.com/"}});
+  history::BlockUntilHistoryProcessesPendingRequests(history_service_.get());
+  EXPECT_FALSE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+
+  // Visits now span 2 days (1-day-old and 60-day-old) since we deleted the only
+  // 2-day-old visit.
+  flush_keyword_requests(2);
+
+  // The keyword cache should be repopulated.
+  EXPECT_TRUE(history_clusters_service_->DoesURLMatchAnyCluster(
+      ComputeURLKeywordForLookup(GURL("https://second-1-day-old-visit.com/"))));
+}
+
 class HistoryClustersServiceMaxKeywordsTest
     : public HistoryClustersServiceTestBase {
  public:
diff --git a/components/infobars/android/BUILD.gn b/components/infobars/android/BUILD.gn
index c5ae7fe..ee9a72f 100644
--- a/components/infobars/android/BUILD.gn
+++ b/components/infobars/android/BUILD.gn
@@ -109,7 +109,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//components/browser_ui/theme/android:java_resources",
     "//components/browser_ui/widget/android:java",
diff --git a/components/installedapp/android/BUILD.gn b/components/installedapp/android/BUILD.gn
index d82a65d5..be179a1 100644
--- a/components/installedapp/android/BUILD.gn
+++ b/components/installedapp/android/BUILD.gn
@@ -71,7 +71,6 @@
       [ "java/src/org/chromium/components/installedapp/PackageHashTest.java" ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/language/android/BUILD.gn b/components/language/android/BUILD.gn
index 12461e9a..b79765e 100644
--- a/components/language/android/BUILD.gn
+++ b/components/language/android/BUILD.gn
@@ -49,8 +49,6 @@
     "java/src/org/chromium/components/language/LanguageProfileDelegateImpl.java",
   ]
 
-  deps = [ "//base:base_java" ]
-
   # Allow downstream targets to provide their own implementations.
   jar_excluded_patterns = [ "*/LanguageProfileDelegateImpl.class" ]
 }
@@ -60,7 +58,6 @@
 
   deps = [
     ":ulp_delegate_java",
-    "//base:base_java",
     "//build/android:build_java",
   ]
 }
diff --git a/components/messages/android/internal/java/res/layout/message_banner_view.xml b/components/messages/android/internal/java/res/layout/message_banner_view.xml
index 68afc88d..41af96e 100644
--- a/components/messages/android/internal/java/res/layout/message_banner_view.xml
+++ b/components/messages/android/internal/java/res/layout/message_banner_view.xml
@@ -94,4 +94,15 @@
         android:layout_height="match_parent"
         android:layout_gravity="center_vertical"
         android:visibility="gone" />
+
+    <ProgressBar
+        style="@style/ProgressBarStyle"
+        android:id="@+id/message_primary_progress_spinner"
+        android:indeterminate="true"
+        android:maxWidth="@dimen/message_primary_button_max_width"
+        android:minWidth="@dimen/button_min_width"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/message_progress_spinner_height"
+        android:layout_gravity="center_vertical"
+        android:visibility="gone" />
 </org.chromium.components.messages.MessageBannerView>
diff --git a/components/messages/android/internal/java/res/values/dimens.xml b/components/messages/android/internal/java/res/values/dimens.xml
index 83bea47..43a0647 100644
--- a/components/messages/android/internal/java/res/values/dimens.xml
+++ b/components/messages/android/internal/java/res/values/dimens.xml
@@ -28,5 +28,6 @@
     <dimen name="message_secondary_menu_max_size_small">180dp</dimen>
     <dimen name="message_secondary_menu_max_size_medium">250dp</dimen>
     <dimen name="message_secondary_menu_max_size_large">300dp</dimen>
+    <dimen name="message_progress_spinner_height">24dp</dimen>
 
 </resources>
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
index de98ea4a..1c142c2 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
@@ -43,7 +43,10 @@
     private ImageView mIconView;
     private TextView mTitle;
     private TextViewWithCompoundDrawables mDescription;
+    private @PrimaryWidgetAppearance int mPrimaryWidgetAppearance =
+            PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET;
     private TextView mPrimaryButton;
+    private View mPrimaryProgressSpinner;
     private ListMenuButton mSecondaryButton;
     private View mDivider;
     private String mSecondaryButtonMenuText;
@@ -65,6 +68,7 @@
         mTitle = findViewById(R.id.message_title);
         mDescription = findViewById(R.id.message_description);
         mPrimaryButton = findViewById(R.id.message_primary_button);
+        mPrimaryProgressSpinner = findViewById(R.id.message_primary_progress_spinner);
         mIconView = findViewById(R.id.message_icon);
         mSecondaryButton = findViewById(R.id.message_secondary_button);
         mDivider = findViewById(R.id.message_divider);
@@ -139,9 +143,25 @@
         mIconView.setImageDrawable(bitmap);
     }
 
+    void setPrimaryWidgetAppearance(@PrimaryWidgetAppearance int primaryWidgetAppearance) {
+        mPrimaryWidgetAppearance = primaryWidgetAppearance;
+        updatePrimaryWidgetAppearance();
+    }
+
     void setPrimaryButtonText(String text) {
-        mPrimaryButton.setVisibility(VISIBLE);
         mPrimaryButton.setText(text);
+        updatePrimaryWidgetAppearance();
+    }
+
+    private void updatePrimaryWidgetAppearance() {
+        mPrimaryButton.setVisibility(
+                mPrimaryWidgetAppearance == PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET
+                                && !TextUtils.isEmpty(mPrimaryButton.getText())
+                        ? VISIBLE
+                        : GONE);
+        mPrimaryProgressSpinner.setVisibility(
+                mPrimaryWidgetAppearance == PrimaryWidgetAppearance.PROGRESS_SPINNER ? VISIBLE
+                                                                                     : GONE);
     }
 
     void setPrimaryButtonClickListener(OnClickListener listener) {
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java
index 654b084..e69a445 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java
@@ -17,6 +17,7 @@
 import static org.chromium.components.messages.MessageBannerProperties.ON_TOUCH_RUNNABLE;
 import static org.chromium.components.messages.MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER;
 import static org.chromium.components.messages.MessageBannerProperties.PRIMARY_BUTTON_TEXT;
+import static org.chromium.components.messages.MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE;
 import static org.chromium.components.messages.MessageBannerProperties.RESIZE_DESCRIPTION_ICON;
 import static org.chromium.components.messages.MessageBannerProperties.SECONDARY_BUTTON_MENU_TEXT;
 import static org.chromium.components.messages.MessageBannerProperties.SECONDARY_ICON;
@@ -42,7 +43,9 @@
 public class MessageBannerViewBinder {
     @SuppressLint("ClickableViewAccessibility")
     public static void bind(PropertyModel model, MessageBannerView view, PropertyKey propertyKey) {
-        if (propertyKey == PRIMARY_BUTTON_TEXT) {
+        if (propertyKey == PRIMARY_WIDGET_APPEARANCE) {
+            view.setPrimaryWidgetAppearance(model.get(PRIMARY_WIDGET_APPEARANCE));
+        } else if (propertyKey == PRIMARY_BUTTON_TEXT) {
             view.setPrimaryButtonText(model.get(PRIMARY_BUTTON_TEXT));
         } else if (propertyKey == PRIMARY_BUTTON_CLICK_LISTENER) {
             view.setPrimaryButtonClickListener(model.get(PRIMARY_BUTTON_CLICK_LISTENER));
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
index 76aaad6..a030ced 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewTest.java
@@ -12,11 +12,13 @@
 
 import android.app.Activity;
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
 import androidx.test.filters.MediumTest;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
@@ -49,6 +51,7 @@
 @RunWith(BaseJUnit4ClassRunner.class)
 @Batch(Batch.UNIT_TESTS)
 public class MessageBannerViewTest {
+    private static final String PRIMARY_BUTTON_TEXT = "PrimaryButtonText";
     private static final String SECONDARY_BUTTON_MENU_TEXT = "SecondaryActionText";
 
     @ClassRule
@@ -66,6 +69,8 @@
     public MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     @Mock
+    Runnable mPrimaryActionCallback;
+    @Mock
     Runnable mSecondaryActionCallback;
 
     MessageBannerView mMessageBannerView;
@@ -224,4 +229,316 @@
         onView(withText(SECONDARY_BUTTON_MENU_TEXT)).perform(click());
         Mockito.verify(mSecondaryActionCallback).run();
     }
+
+    /**
+     * Setting PRIMARY_WIDGET_APPEARANCE to BUTTON_IF_TEXT_IS_SET without setting the
+     * PRIMARY_BUTTON_TEXT should mean that no primary widget is visible.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceButtonWithUnsetText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * Setting PRIMARY_WIDGET_APPEARANCE to BUTTON_IF_TEXT_IS_SET with PRIMARY_BUTTON_TEXT set to
+     * null should mean that no primary widget is visible.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceButtonWithNullText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, null)
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * Setting PRIMARY_WIDGET_APPEARANCE to BUTTON_IF_TEXT_IS_SET with PRIMARY_BUTTON_TEXT set to an
+     * empty string should mean that no primary widget is visible.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceButtonWithEmptyText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, "")
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * Setting PRIMARY_WIDGET_APPEARANCE to BUTTON_IF_TEXT_IS_SET with PRIMARY_BUTTON_TEXT set to a
+     * non-empty string should show the primary action button.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceButtonWithNonEmptyText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_TEXT)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER,
+                                    new View.OnClickListener() {
+                                        @Override
+                                        public void onClick(View v) {
+                                            mPrimaryActionCallback.run();
+                                        }
+                                    })
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+
+        onView(withId(R.id.message_primary_button)).perform(click());
+        Mockito.verify(mPrimaryActionCallback).run();
+    }
+
+    /**
+     * Changing PRIMARY_BUTTON_TEXT to a non-empty string when PRIMARY_WIDGET_APPEARANCE is set to
+     * BUTTON_IF_TEXT_IS_SET should show the primary action button.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceButtonChangeTextFromEmptyToNonEmpty() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, "")
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER,
+                                    new View.OnClickListener() {
+                                        @Override
+                                        public void onClick(View v) {
+                                            mPrimaryActionCallback.run();
+                                        }
+                                    })
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+            // Change the PRIMARY_BUTTON_TEXT to a non-empty string after the view has already been
+            // put together.
+            propertyModel.set(MessageBannerProperties.PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_TEXT);
+        });
+
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+
+        onView(withId(R.id.message_primary_button)).perform(click());
+        Mockito.verify(mPrimaryActionCallback).run();
+    }
+
+    /**
+     * Setting PRIMARY_WIDGET_APPEARANCE to PROGRESS_SPINNER should show the progress spinner.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceProgressSpinner() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.PROGRESS_SPINNER)
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * Changing PRIMARY_WIDGET_APPEARANCE to PROGRESS_SPINNER should show the progress spinner.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceChangeFromButtonToProgressSpinner() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_TEXT)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER,
+                                    new View.OnClickListener() {
+                                        @Override
+                                        public void onClick(View v) {
+                                            mPrimaryActionCallback.run();
+                                        }
+                                    })
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+            // Change the PRIMARY_WIDGET_APPEARANCE to PROGRESS_SPINNER after the view has already
+            // been put together.
+            propertyModel.set(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                    PrimaryWidgetAppearance.PROGRESS_SPINNER);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * Setting the PRIMARY_BUTTON_TEXT to a non-empty string should not override the
+     * PROGRESS_SPINNER appearance, so the progress spinner should be shown.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceProgressSpinnerWithNonEmptyButtonText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                                    PrimaryWidgetAppearance.PROGRESS_SPINNER)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_TEXT)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER,
+                                    new View.OnClickListener() {
+                                        @Override
+                                        public void onClick(View v) {
+                                            mPrimaryActionCallback.run();
+                                        }
+                                    })
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * With neither PRIMARY_WIDGET_APPEARANCE nor PRIMARY_BUTTON_TEXT set, no primary widget should
+     * be visible, since PRIMARY_WIDGET_APPEARANCE should default to BUTTON_IF_TEXT_IS_SET.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceUnsetWithUnsetText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+    }
+
+    /**
+     * When PRIMARY_WIDGET_APPEARANCE is left unset, it should default to BUTTON_IF_TEXT_IS_SET, so
+     * setting PRIMARY_BUTTON_TEXT to a non-empty string should show the primary action button.
+     */
+    @Test
+    @MediumTest
+    public void testPrimaryWidgetAppearanceUnsetWithNonEmptyText() {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PropertyModel propertyModel =
+                    new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                            .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                    MessageIdentifier.TEST_MESSAGE)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_TEXT)
+                            .with(MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER,
+                                    new View.OnClickListener() {
+                                        @Override
+                                        public void onClick(View v) {
+                                            mPrimaryActionCallback.run();
+                                        }
+                                    })
+                            .build();
+            PropertyModelChangeProcessor.create(
+                    propertyModel, mMessageBannerView, MessageBannerViewBinder::bind);
+        });
+
+        Assert.assertEquals(View.VISIBLE,
+                mMessageBannerView.findViewById(R.id.message_primary_button).getVisibility());
+        Assert.assertEquals(View.GONE,
+                mMessageBannerView.findViewById(R.id.message_primary_progress_spinner)
+                        .getVisibility());
+
+        onView(withId(R.id.message_primary_button)).perform(click());
+        Mockito.verify(mPrimaryActionCallback).run();
+    }
 }
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
index 6136c334..027268ab 100644
--- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
+++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
@@ -35,6 +35,14 @@
      * MessageIdentifier enum.
      */
     public static final ReadableIntPropertyKey MESSAGE_IDENTIFIER = new ReadableIntPropertyKey();
+    /**
+     * Controls the appearance of the primary widget, according to which value of the
+     * PrimaryWidgetAppearance enum that this is set to. See the documentation of
+     * PrimaryWidgetAppearance in components/messages/android/message_enums.h for details about each
+     * possible value.
+     */
+    public static final WritableIntPropertyKey PRIMARY_WIDGET_APPEARANCE =
+            new WritableIntPropertyKey();
     public static final WritableObjectPropertyKey<String> PRIMARY_BUTTON_TEXT =
             new WritableObjectPropertyKey<>();
     /**
@@ -128,5 +136,5 @@
             ON_SECONDARY_BUTTON_CLICK, SECONDARY_ICON_CONTENT_DESCRIPTION, DISMISSAL_DURATION,
             TRANSLATION_X, TRANSLATION_Y, ALPHA, ON_TOUCH_RUNNABLE, ON_PRIMARY_ACTION,
             ON_SECONDARY_ACTION, ON_DISMISSED, ON_STARTED_SHOWING, SECONDARY_MENU_BUTTON_DELEGATE,
-            SECONDARY_MENU_MAX_SIZE};
+            SECONDARY_MENU_MAX_SIZE, PRIMARY_WIDGET_APPEARANCE};
 }
diff --git a/components/messages/android/message_enums.h b/components/messages/android/message_enums.h
index 894bb23..aaad71ab 100644
--- a/components/messages/android/message_enums.h
+++ b/components/messages/android/message_enums.h
@@ -125,6 +125,17 @@
   LARGE = 2,   // 300dp -> @dimen/message_secondary_menu_max_size_large
 };
 
+// The primary widget that should be shown in the message.
+//
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.messages
+enum class PrimaryWidgetAppearance {
+  // Default value. Show the primary action button if non-empty text has been
+  // set for the primary action button, otherwise no primary widget is shown.
+  BUTTON_IF_TEXT_IS_SET = 0,
+  // Show a spinning progress indicator that isn't clickable.
+  PROGRESS_SPINNER = 1,
+};
+
 }  // namespace messages
 
 #endif  // COMPONENTS_MESSAGES_ANDROID_MESSAGE_ENUMS_H_
diff --git a/components/messages/android/test/BUILD.gn b/components/messages/android/test/BUILD.gn
index fc24ef1..ab8afe4 100644
--- a/components/messages/android/test/BUILD.gn
+++ b/components/messages/android/test/BUILD.gn
@@ -14,7 +14,6 @@
   sources =
       [ "java/src/org/chromium/components/messages/MessagesTestHelper.java" ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
diff --git a/components/mirroring/service/captured_audio_input_unittest.cc b/components/mirroring/service/captured_audio_input_unittest.cc
index b84e444..e130b97 100644
--- a/components/mirroring/service/captured_audio_input_unittest.cc
+++ b/components/mirroring/service/captured_audio_input_unittest.cc
@@ -18,6 +18,7 @@
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using ::testing::InvokeWithoutArgs;
 
@@ -81,7 +82,7 @@
     stream_client_.reset();
     audio_client->StreamCreated(
         std::move(pending_stream), stream_client_.BindNewPipeAndPassReceiver(),
-        {base::in_place, base::ReadOnlySharedMemoryRegion::Create(1024).region,
+        {absl::in_place, base::ReadOnlySharedMemoryRegion::Create(1024).region,
          mojo::PlatformHandle(foreign_socket.Take())});
   }
 
diff --git a/components/module_installer/android/module_desc_java.gni b/components/module_installer/android/module_desc_java.gni
index 9dbcbbe..2ed79560 100644
--- a/components/module_installer/android/module_desc_java.gni
+++ b/components/module_installer/android/module_desc_java.gni
@@ -71,7 +71,6 @@
 
   android_library(_target_name) {
     deps = [
-      "//base:base_java",
       "//build/android:build_java",
       "//components/module_installer/android:module_installer_java",
     ]
diff --git a/components/navigation_interception/android/BUILD.gn b/components/navigation_interception/android/BUILD.gn
index 4e0267b7..f659eb0 100644
--- a/components/navigation_interception/android/BUILD.gn
+++ b/components/navigation_interception/android/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("navigation_interception_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/components/offline_items_collection/core/BUILD.gn b/components/offline_items_collection/core/BUILD.gn
index 7a28579c..b6305a1 100644
--- a/components/offline_items_collection/core/BUILD.gn
+++ b/components/offline_items_collection/core/BUILD.gn
@@ -150,7 +150,6 @@
     testonly = true
     deps = [
       ":core_java",
-      "//base:base_java",
       "//base:jni_java",
       "//third_party/junit",
     ]
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index 0c6ca42..e4ef39a8 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -423,7 +423,6 @@
     resources_package = "org.chromium.components.omnibox"
     deps = [
       ":java_resources",
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
       "//components/browser_ui/widget/android:java",
diff --git a/components/omnibox/browser/autocomplete_provider_unittest.cc b/components/omnibox/browser/autocomplete_provider_unittest.cc
index a9b719c..2e7dd27 100644
--- a/components/omnibox/browser/autocomplete_provider_unittest.cc
+++ b/components/omnibox/browser/autocomplete_provider_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/location.h"
 #include "base/test/scoped_feature_list.h"
 
-#include "base/base64.h"
+#include "base/base64url.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -674,13 +674,17 @@
     result_.match_at(i)->search_terms_args->searchbox_stats.SerializeToString(
         &serialized_searchbox_stats);
     std::string encoded_searchbox_stats;
-    base::Base64Encode(serialized_searchbox_stats, &encoded_searchbox_stats);
+    base::Base64UrlEncode(serialized_searchbox_stats,
+                          base::Base64UrlEncodePolicy::OMIT_PADDING,
+                          &encoded_searchbox_stats);
     std::string expected_serialized_searchbox_stats;
     aqs_test_data[i].expected_searchbox_stats.SerializeToString(
         &expected_serialized_searchbox_stats);
     std::string expected_encoded_searchbox_stats;
-    base::Base64Encode(expected_serialized_searchbox_stats,
-                       &expected_encoded_searchbox_stats);
+    base::Base64UrlEncode(expected_serialized_searchbox_stats,
+                          base::Base64UrlEncodePolicy::OMIT_PADDING,
+
+                          &expected_encoded_searchbox_stats);
     EXPECT_EQ(expected_encoded_searchbox_stats, encoded_searchbox_stats);
   }
 }
@@ -1332,11 +1336,13 @@
       "chrome.0.69i57j69i58j5l2j0l3j69i59";
   match.search_terms_args->searchbox_stats.set_client_name("chrome");
   url = GetDestinationURL(match, base::Milliseconds(2456));
-  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajBqMA==&", url.path());
+  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajBqMA&", url.path());
   // Make sure searchbox_stats is serialized and encoded correctly.
   {
     std::string serialized_proto;
-    base::Base64Decode("EgZjaHJvbWXSAQgyNDU2ajBqMA==", &serialized_proto);
+    EXPECT_TRUE(base::Base64UrlDecode(
+        "EgZjaHJvbWXSAQgyNDU2ajBqMA",
+        base::Base64UrlDecodePolicy::DISALLOW_PADDING, &serialized_proto));
     metrics::ChromeSearchboxStats expected;
     expected.ParseFromString(serialized_proto);
     EXPECT_EQ("chrome", expected.client_name());
@@ -1345,11 +1351,13 @@
   // Test field trial triggered bit set.
   set_search_provider_field_trial_triggered_in_session(true);
   url = GetDestinationURL(match, base::Milliseconds(2456));
-  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqMA==&", url.path());
+  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqMA&", url.path());
   // Make sure searchbox_stats is serialized and encoded correctly.
   {
     std::string serialized_proto;
-    base::Base64Decode("EgZjaHJvbWXSAQgyNDU2ajFqMA==", &serialized_proto);
+    EXPECT_TRUE(base::Base64UrlDecode(
+        "EgZjaHJvbWXSAQgyNDU2ajFqMA",
+        base::Base64UrlDecodePolicy::DISALLOW_PADDING, &serialized_proto));
     metrics::ChromeSearchboxStats expected;
     expected.ParseFromString(serialized_proto);
     EXPECT_EQ("2456j1j0", expected.experiment_stats());
@@ -1359,11 +1367,13 @@
   set_search_provider_field_trial_triggered_in_session(false);
   set_current_page_classification(metrics::OmniboxEventProto::OTHER);
   url = GetDestinationURL(match, base::Milliseconds(2456));
-  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajBqNA==&", url.path());
+  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajBqNA&", url.path());
   // Make sure searchbox_stats is serialized and encoded correctly.
   {
     std::string serialized_proto;
-    base::Base64Decode("EgZjaHJvbWXSAQgyNDU2ajBqNA==", &serialized_proto);
+    EXPECT_TRUE(base::Base64UrlDecode(
+        "EgZjaHJvbWXSAQgyNDU2ajBqNA",
+        base::Base64UrlDecodePolicy::DISALLOW_PADDING, &serialized_proto));
     metrics::ChromeSearchboxStats expected;
     expected.ParseFromString(serialized_proto);
     EXPECT_EQ("2456j0j4", expected.experiment_stats());
@@ -1373,11 +1383,13 @@
   set_search_provider_field_trial_triggered_in_session(true);
   set_current_page_classification(metrics::OmniboxEventProto::OTHER);
   url = GetDestinationURL(match, base::Milliseconds(2456));
-  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqNA==&", url.path());
+  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqNA&", url.path());
   // Make sure searchbox_stats is serialized and encoded correctly.
   {
     std::string serialized_proto;
-    base::Base64Decode("EgZjaHJvbWXSAQgyNDU2ajFqNA==", &serialized_proto);
+    EXPECT_TRUE(base::Base64UrlDecode(
+        "EgZjaHJvbWXSAQgyNDU2ajFqNA",
+        base::Base64UrlDecodePolicy::DISALLOW_PADDING, &serialized_proto));
     metrics::ChromeSearchboxStats expected;
     expected.ParseFromString(serialized_proto);
     EXPECT_EQ("2456j1j4", expected.experiment_stats());
@@ -1387,13 +1399,14 @@
   add_zero_suggest_provider_experiment_stat(
       base::test::ParseJson(R"json({"2":"0:67","4":10001})json"));
   url = GetDestinationURL(match, base::Milliseconds(2456));
-  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqNOIDCRIEMCw2NyCRTg==&",
+  EXPECT_EQ("//gs_lcrp=EgZjaHJvbWXSAQgyNDU2ajFqNOIDCRIEMCw2NyCRTg&",
             url.path());
   // Make sure searchbox_stats is serialized and encoded correctly.
   {
     std::string serialized_proto;
-    base::Base64Decode("EgZjaHJvbWXSAQgyNDU2ajFqNOIDCRIEMCw2NyCRTg==",
-                       &serialized_proto);
+    EXPECT_TRUE(base::Base64UrlDecode(
+        "EgZjaHJvbWXSAQgyNDU2ajFqNOIDCRIEMCw2NyCRTg",
+        base::Base64UrlDecodePolicy::DISALLOW_PADDING, &serialized_proto));
     metrics::ChromeSearchboxStats expected;
     expected.ParseFromString(serialized_proto);
     EXPECT_EQ(1, expected.experiment_stats_v2_size());
@@ -1453,7 +1466,7 @@
   EXPECT_EQ(
       "//"
       "aqs=chrome.0.69i57j69i58j5l2j0l3j69i59.2456j0j0&gs_lcrp="
-      "EgZjaHJvbWXSAQgyNDU2ajBqMA==&",
+      "EgZjaHJvbWXSAQgyNDU2ajBqMA&",
       url.path());
 }
 
diff --git a/components/optimization_guide/content/browser/page_content_annotations_service.cc b/components/optimization_guide/content/browser/page_content_annotations_service.cc
index 8877693fa..699313c 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_service.cc
+++ b/components/optimization_guide/content/browser/page_content_annotations_service.cc
@@ -37,13 +37,37 @@
 
 namespace {
 
+// Keep this in sync with the PageContentAnnotationsStorageType variant in
+// ../optimization/histograms.xml.
+std::string PageContentAnnotationsTypeToString(
+    PageContentAnnotationsType annotation_type) {
+  switch (annotation_type) {
+    case PageContentAnnotationsType::kUnknown:
+      return "Unknown";
+    case PageContentAnnotationsType::kModelAnnotations:
+      return "ModelAnnotations";
+    case PageContentAnnotationsType::kRelatedSearches:
+      return "RelatedSearches";
+    case PageContentAnnotationsType::kSearchMetadata:
+      return "SearchMetadata";
+  }
+}
+
 void LogPageContentAnnotationsStorageStatus(
-    PageContentAnnotationsStorageStatus status) {
+    PageContentAnnotationsStorageStatus status,
+    PageContentAnnotationsType annotation_type) {
   DCHECK_NE(status, PageContentAnnotationsStorageStatus::kUnknown);
+  DCHECK_NE(annotation_type, PageContentAnnotationsType::kUnknown);
   base::UmaHistogramEnumeration(
       "OptimizationGuide.PageContentAnnotationsService."
       "ContentAnnotationsStorageStatus",
       status);
+
+  base::UmaHistogramEnumeration(
+      "OptimizationGuide.PageContentAnnotationsService."
+      "ContentAnnotationsStorageStatus." +
+          PageContentAnnotationsTypeToString(annotation_type),
+      status);
 }
 
 #if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
@@ -315,7 +339,8 @@
            base::BindOnce(&history::HistoryService::AddSearchMetadataForVisit,
                           history_service_->AsWeakPtr(),
                           search_metadata.normalized_url,
-                          search_metadata.search_terms));
+                          search_metadata.search_terms),
+           PageContentAnnotationsType::kSearchMetadata);
 }
 
 void PageContentAnnotationsService::ExtractRelatedSearches(
@@ -350,7 +375,8 @@
   QueryURL(visit,
            base::BindOnce(
                &history::HistoryService::AddContentModelAnnotationsForVisit,
-               history_service_->AsWeakPtr(), *content_annotations));
+               history_service_->AsWeakPtr(), *content_annotations),
+           PageContentAnnotationsType::kModelAnnotations);
 }
 #endif
 
@@ -393,27 +419,30 @@
 
   QueryURL(visit,
            base::BindOnce(&history::HistoryService::AddRelatedSearchesForVisit,
-                          history_service_->AsWeakPtr(), related_searches));
+                          history_service_->AsWeakPtr(), related_searches),
+           PageContentAnnotationsType::kRelatedSearches);
 }
 
 void PageContentAnnotationsService::QueryURL(
     const HistoryVisit& visit,
-    PersistAnnotationsCallback callback) {
+    PersistAnnotationsCallback callback,
+    PageContentAnnotationsType annotation_type) {
   history_service_->QueryURL(
       visit.url, /*want_visits=*/true,
       base::BindOnce(&PageContentAnnotationsService::OnURLQueried,
-                     weak_ptr_factory_.GetWeakPtr(), visit,
-                     std::move(callback)),
+                     weak_ptr_factory_.GetWeakPtr(), visit, std::move(callback),
+                     annotation_type),
       &history_service_task_tracker_);
 }
 
 void PageContentAnnotationsService::OnURLQueried(
     const HistoryVisit& visit,
     PersistAnnotationsCallback callback,
+    PageContentAnnotationsType annotation_type,
     history::QueryURLResult url_result) {
   if (!url_result.success) {
     LogPageContentAnnotationsStorageStatus(
-        PageContentAnnotationsStorageStatus::kNoVisitsForUrl);
+        PageContentAnnotationsStorageStatus::kNoVisitsForUrl, annotation_type);
     return;
   }
 
@@ -435,13 +464,20 @@
     break;
   }
   LogPageContentAnnotationsStorageStatus(
-      did_store_content_annotations ? kSuccess : kSpecificVisitForUrlNotFound);
+      did_store_content_annotations ? kSuccess : kSpecificVisitForUrlNotFound,
+      annotation_type);
   if (!did_store_content_annotations) {
     DCHECK_NE(min_magnitude_between_visits, base::TimeDelta::Max());
     base::UmaHistogramTimes(
         "OptimizationGuide.PageContentAnnotationsService."
         "ContentAnnotationsStorageMinMagnitudeForVisitNotFound",
         min_magnitude_between_visits);
+
+    base::UmaHistogramTimes(
+        "OptimizationGuide.PageContentAnnotationsService."
+        "ContentAnnotationsStorageMinMagnitudeForVisitNotFound." +
+            PageContentAnnotationsTypeToString(annotation_type),
+        min_magnitude_between_visits);
   }
 }
 
@@ -471,7 +507,10 @@
   QueryURL(history_visit,
            base::BindOnce(
                &history::HistoryService::AddContentModelAnnotationsForVisit,
-               history_service_->AsWeakPtr(), annotations));
+               history_service_->AsWeakPtr(), annotations),
+           // Even though we are persisting remote page entities, we store these
+           // as an override to the model annotations.
+           PageContentAnnotationsType::kModelAnnotations);
 }
 
 void PageContentAnnotationsService::RunBatchAnnotationValidation() {
diff --git a/components/optimization_guide/content/browser/page_content_annotations_service.h b/components/optimization_guide/content/browser/page_content_annotations_service.h
index abba569..a4c911d 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_service.h
+++ b/components/optimization_guide/content/browser/page_content_annotations_service.h
@@ -84,6 +84,18 @@
   std::u16string search_terms;
 };
 
+// The type of page content annotations stored in the history database.
+enum class PageContentAnnotationsType {
+  kUnknown = 0,
+  // Results from executing the models on page content or received from the
+  // remote Optimization Guide service.
+  kModelAnnotations = 1,
+  // Related searches for the Google Search Results page.
+  kRelatedSearches = 2,
+  // Metadata for "search-like" pages.
+  kSearchMetadata = 3,
+};
+
 // A KeyedService that annotates page content.
 class PageContentAnnotationsService : public KeyedService,
                                       public EntityMetadataProvider {
@@ -213,13 +225,18 @@
   using PersistAnnotationsCallback = base::OnceCallback<void(history::VisitID)>;
   // Queries |history_service| for all the visits to the visited URL of |visit|.
   // |callback| will be invoked to write the bound content annotations to
-  // |history_service| once the visits to the given URL have returned.
-  void QueryURL(const HistoryVisit& visit, PersistAnnotationsCallback callback);
+  // |history_service| once the visits to the given URL have returned. The
+  // |annotation_type| of data to be stored in History Service is passed along
+  // for metrics purposes.
+  void QueryURL(const HistoryVisit& visit,
+                PersistAnnotationsCallback callback,
+                PageContentAnnotationsType annotation_type);
   // Callback invoked when |history_service| has returned results for the visits
   // to a URL. In turn invokes |callback| to write the bound content annotations
   // to |history_service|.
   void OnURLQueried(const HistoryVisit& visit,
                     PersistAnnotationsCallback callback,
+                    PageContentAnnotationsType annotation_type,
                     history::QueryURLResult url_result);
 
   // Runs a batch annotation validation, that is calls |BatchAnnotate| with
diff --git a/components/optimization_guide/core/page_entities_model_executor.h b/components/optimization_guide/core/page_entities_model_executor.h
index 5ea55c6..86fd964 100644
--- a/components/optimization_guide/core/page_entities_model_executor.h
+++ b/components/optimization_guide/core/page_entities_model_executor.h
@@ -15,21 +15,6 @@
 
 namespace optimization_guide {
 
-// TODO(crbug/1278828): Remove this entirely.
-class HumanReadablePageEntitiesModelExecutor {
- public:
-  virtual ~HumanReadablePageEntitiesModelExecutor() = default;
-
-  using PageEntitiesModelExecutedCallback = base::OnceCallback<void(
-      const absl::optional<std::vector<tflite::task::core::Category>>&)>;
-
-  // Annotates |text| with page entities likely represented on the page. Invokes
-  // |callback| when done.
-  virtual void ExecuteModelWithInput(
-      const std::string& text,
-      PageEntitiesModelExecutedCallback callback) = 0;
-};
-
 // The PageEntitiesModelExecutor is responsible for executing the PAGE_ENTITIES
 // model.
 class PageEntitiesModelExecutor {
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
index 62e4127..65bd008 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -30,6 +30,7 @@
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/use_counter/use_counter_feature.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
 #include "third_party/blink/public/mojom/use_counter/use_counter_feature.mojom-shared.h"
@@ -118,11 +119,11 @@
                                content::RenderFrameHost* render_frame_host) {
     observer()->OnTimingUpdated(
         render_frame_host, previous_timing_->Clone(),
-        mojom::FrameMetadataPtr(base::in_place),
+        mojom::FrameMetadataPtr(absl::in_place),
         std::vector<blink::UseCounterFeature>(),
         std::vector<mojom::ResourceDataUpdatePtr>(),
-        mojom::FrameRenderDataUpdatePtr(base::in_place), timing.Clone(),
-        mojom::InputTimingPtr(base::in_place), blink::MobileFriendliness());
+        mojom::FrameRenderDataUpdatePtr(absl::in_place), timing.Clone(),
+        mojom::InputTimingPtr(absl::in_place), blink::MobileFriendliness());
   }
 
   void SimulateTimingUpdate(const mojom::PageLoadTiming& timing,
@@ -141,12 +142,12 @@
       content::RenderFrameHost* render_frame_host) {
     previous_timing_ = timing.Clone();
     observer()->OnTimingUpdated(render_frame_host, timing.Clone(),
-                                mojom::FrameMetadataPtr(base::in_place),
+                                mojom::FrameMetadataPtr(absl::in_place),
                                 std::vector<blink::UseCounterFeature>(),
                                 std::vector<mojom::ResourceDataUpdatePtr>(),
-                                mojom::FrameRenderDataUpdatePtr(base::in_place),
-                                mojom::CpuTimingPtr(base::in_place),
-                                mojom::InputTimingPtr(base::in_place),
+                                mojom::FrameRenderDataUpdatePtr(absl::in_place),
+                                mojom::CpuTimingPtr(absl::in_place),
+                                mojom::InputTimingPtr(absl::in_place),
                                 blink::MobileFriendliness());
   }
 
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
index 4b361f1..21607cc6 100644
--- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
+++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
@@ -60,6 +60,7 @@
 #include "net/base/host_port_pair.h"
 #include "services/metrics/public/cpp/metrics_utils.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/blink/public/mojom/frame/frame.mojom.h"
 #include "url/gurl.h"
@@ -202,15 +203,15 @@
     resource->is_complete = true;
     resource->is_primary_frame_resource = true;
     resources.push_back(std::move(resource));
-    auto timing = mojom::PageLoadTimingPtr(base::in_place);
+    auto timing = mojom::PageLoadTimingPtr(absl::in_place);
     InitPageLoadTimingForTest(timing.get());
     observer->OnTimingUpdated(
         navigation_handle()->GetRenderFrameHost(), std::move(timing),
-        mojom::FrameMetadataPtr(base::in_place),
+        mojom::FrameMetadataPtr(absl::in_place),
         std::vector<blink::UseCounterFeature>(), resources,
-        mojom::FrameRenderDataUpdatePtr(base::in_place),
-        mojom::CpuTimingPtr(base::in_place),
-        mojom::InputTimingPtr(base::in_place), blink::MobileFriendliness());
+        mojom::FrameRenderDataUpdatePtr(absl::in_place),
+        mojom::CpuTimingPtr(absl::in_place),
+        mojom::InputTimingPtr(absl::in_place), blink::MobileFriendliness());
   }
 };
 
diff --git a/components/page_load_metrics/browser/observers/page_load_metrics_observer_tester.cc b/components/page_load_metrics/browser/observers/page_load_metrics_observer_tester.cc
index 3800cfe..9570d514 100644
--- a/components/page_load_metrics/browser/observers/page_load_metrics_observer_tester.cc
+++ b/components/page_load_metrics/browser/observers/page_load_metrics_observer_tester.cc
@@ -22,6 +22,7 @@
 #include "content/public/test/test_renderer_host.h"
 #include "net/base/ip_endpoint.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/input/web_input_event.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
 #include "third_party/blink/public/mojom/mobile_metrics/mobile_friendliness.mojom.h"
@@ -144,7 +145,7 @@
 void PageLoadMetricsObserverTester::SimulateCpuTimingUpdate(
     const mojom::CpuTiming& cpu_timing,
     content::RenderFrameHost* rfh) {
-  auto timing = page_load_metrics::mojom::PageLoadTimingPtr(base::in_place);
+  auto timing = page_load_metrics::mojom::PageLoadTimingPtr(absl::in_place);
   page_load_metrics::InitPageLoadTimingForTest(timing.get());
   SimulatePageLoadTimingUpdate(
       *timing, mojom::FrameMetadata(), /* new_features= */ {},
@@ -171,7 +172,7 @@
 void PageLoadMetricsObserverTester::SimulateInputTimingUpdate(
     const mojom::InputTiming& input_timing,
     content::RenderFrameHost* rfh) {
-  auto timing = page_load_metrics::mojom::PageLoadTimingPtr(base::in_place);
+  auto timing = page_load_metrics::mojom::PageLoadTimingPtr(absl::in_place);
   page_load_metrics::InitPageLoadTimingForTest(timing.get());
   SimulatePageLoadTimingUpdate(
       *timing, mojom::FrameMetadata(), /* new_features= */ {},
@@ -252,15 +253,15 @@
 void PageLoadMetricsObserverTester::SimulateResourceDataUseUpdate(
     const std::vector<mojom::ResourceDataUpdatePtr>& resources,
     content::RenderFrameHost* render_frame_host) {
-  auto timing = mojom::PageLoadTimingPtr(base::in_place);
+  auto timing = mojom::PageLoadTimingPtr(absl::in_place);
   InitPageLoadTimingForTest(timing.get());
   metrics_web_contents_observer_->OnTimingUpdated(
       render_frame_host, std::move(timing),
-      mojom::FrameMetadataPtr(base::in_place),
+      mojom::FrameMetadataPtr(absl::in_place),
       std::vector<blink::UseCounterFeature>(), resources,
-      mojom::FrameRenderDataUpdatePtr(base::in_place),
-      mojom::CpuTimingPtr(base::in_place),
-      mojom::InputTimingPtr(base::in_place), blink::MobileFriendliness());
+      mojom::FrameRenderDataUpdatePtr(absl::in_place),
+      mojom::CpuTimingPtr(absl::in_place),
+      mojom::InputTimingPtr(absl::in_place), blink::MobileFriendliness());
 }
 
 void PageLoadMetricsObserverTester::SimulateLoadedResource(
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn
index 42bd387..5f145a3a 100644
--- a/components/payments/content/android/BUILD.gn
+++ b/components/payments/content/android/BUILD.gn
@@ -320,7 +320,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//components/payments/content/android:service_java",
     "//components/payments/mojom:mojom_java",
     "//content/public/android:content_java",
@@ -347,7 +346,6 @@
   deps = [
     ":java",
     ":junit_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//build/android:build_java",
diff --git a/components/policy/android/BUILD.gn b/components/policy/android/BUILD.gn
index 9b7807a..e8add8e7 100644
--- a/components/policy/android/BUILD.gn
+++ b/components/policy/android/BUILD.gn
@@ -96,7 +96,6 @@
   testonly = true
   deps = [
     ":policy_java",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/junit",
diff --git a/components/policy/core/common/management/platform_management_status_provider_mac.cc b/components/policy/core/common/management/platform_management_status_provider_mac.cc
index 9a2e820..14151be 100644
--- a/components/policy/core/common/management/platform_management_status_provider_mac.cc
+++ b/components/policy/core/common/management/platform_management_status_provider_mac.cc
@@ -4,6 +4,7 @@
 
 #include "components/policy/core/common/management/platform_management_status_provider_mac.h"
 
+#include "base/enterprise_util.h"
 #include "components/policy/core/common/policy_pref_names.h"
 
 namespace policy {
@@ -15,7 +16,7 @@
 DomainEnrollmentStatusProvider::~DomainEnrollmentStatusProvider() = default;
 
 EnterpriseManagementAuthority DomainEnrollmentStatusProvider::FetchAuthority() {
-  return domain_join_state_.device_joined || domain_join_state_.user_joined
+  return base::IsEnterpriseDevice()
              ? EnterpriseManagementAuthority::DOMAIN_LOCAL
              : EnterpriseManagementAuthority::NONE;
 }
@@ -28,26 +29,8 @@
 
 EnterpriseManagementAuthority
 EnterpriseMDMManagementStatusProvider::FetchAuthority() {
-  base::MacDeviceManagementStateNew mdm_state_new =
-      base::IsDeviceRegisteredWithManagementNew();
-
-  bool managed = false;
-  switch (mdm_state_new) {
-    case base::MacDeviceManagementStateNew::kLimitedMDMEnrollment:
-    case base::MacDeviceManagementStateNew::kFullMDMEnrollment:
-    case base::MacDeviceManagementStateNew::kDEPMDMEnrollment:
-      managed = true;
-      break;
-    case base::MacDeviceManagementStateNew::kFailureAPIUnavailable:
-      managed = base::MacDeviceManagementStateOld::kMDMEnrollment ==
-                base::IsDeviceRegisteredWithManagementOld();
-      break;
-    default:
-      break;
-  }
-
-  return managed ? EnterpriseManagementAuthority::CLOUD
-                 : EnterpriseManagementAuthority::NONE;
+  return base::IsManagedDevice() ? EnterpriseManagementAuthority::CLOUD
+                                 : EnterpriseManagementAuthority::NONE;
 }
 
 }  // namespace policy
diff --git a/components/policy/core/common/policy_loader_mac.mm b/components/policy/core/common/policy_loader_mac.mm
index b717d39..03583403 100644
--- a/components/policy/core/common/policy_loader_mac.mm
+++ b/components/policy/core/common/policy_loader_mac.mm
@@ -38,25 +38,10 @@
 
 // Encapsulates logic to determine if enterprise policies should be honored.
 bool ShouldHonorPolicies() {
-  // Only honor sensitive policies if the Mac is managed externally.
-  base::DeviceUserDomainJoinState join_state =
-      base::AreDeviceAndUserJoinedToDomain();
-  if (join_state.device_joined)
-    return true;
-
-  // IsDeviceRegisteredWithManagementNew is only available after 10.13.4.
-  // Eventually switch to it when that is the minimum OS required by Chromium.
-  if (@available(macOS 10.13.4, *)) {
-    base::MacDeviceManagementStateNew mdm_state =
-        base::IsDeviceRegisteredWithManagementNew();
-    return mdm_state ==
-               base::MacDeviceManagementStateNew::kLimitedMDMEnrollment ||
-           mdm_state == base::MacDeviceManagementStateNew::kFullMDMEnrollment ||
-           mdm_state == base::MacDeviceManagementStateNew::kDEPMDMEnrollment;
-  }
-  base::MacDeviceManagementStateOld mdm_state =
-      base::IsDeviceRegisteredWithManagementOld();
-  return mdm_state == base::MacDeviceManagementStateOld::kMDMEnrollment;
+  // Only honor sensitive policies if the Mac is managed or connected to an
+  // enterprise.
+  // TODO (crbug.com/1322121): Use PlatformManagementService instead.
+  return base::IsManagedOrEnterpriseDevice();
 }
 
 }  // namespace
@@ -99,10 +84,13 @@
     managed_policy_file_exists = true;
   }
 
+  base::UmaHistogramBoolean("EnterpriseCheck.IsManagedOrEnterpriseDevice",
+                            base::IsManagedOrEnterpriseDevice());
+
   base::UmaHistogramBoolean("EnterpriseCheck.IsManaged2",
                             managed_policy_file_exists);
   base::UmaHistogramBoolean("EnterpriseCheck.IsEnterpriseUser",
-                            base::IsMachineExternallyManaged());
+                            base::IsEnterpriseDevice());
 
   base::UmaHistogramEnumeration("EnterpriseCheck.Mac.IsDeviceMDMEnrolledOld",
                                 base::IsDeviceRegisteredWithManagementOld());
diff --git a/components/policy/core/common/policy_loader_win.cc b/components/policy/core/common/policy_loader_win.cc
index b27940b..82dcfeb4 100644
--- a/components/policy/core/common/policy_loader_win.cc
+++ b/components/policy/core/common/policy_loader_win.cc
@@ -175,13 +175,15 @@
                             base::win::OSInfo::GetInstance()->version_type(),
                             base::win::SUITE_LAST);
 
+  base::UmaHistogramBoolean("EnterpriseCheck.IsManagedOrEnterpriseDevice",
+                            base::IsManagedOrEnterpriseDevice());
   base::UmaHistogramBoolean("EnterpriseCheck.IsDomainJoined", IsDomainJoined());
   base::UmaHistogramBoolean("EnterpriseCheck.InDomain",
                             base::win::IsEnrolledToDomain());
   base::UmaHistogramBoolean("EnterpriseCheck.IsManaged2",
                             base::win::IsDeviceRegisteredWithManagement());
   base::UmaHistogramBoolean("EnterpriseCheck.IsEnterpriseUser",
-                            base::IsMachineExternallyManaged());
+                            base::IsEnterpriseDevice());
   base::UmaHistogramBoolean("EnterpriseCheck.IsJoinedToAzureAD",
                             base::win::IsJoinedToAzureAD());
 
diff --git a/components/prefs/android/BUILD.gn b/components/prefs/android/BUILD.gn
index bc996be..e215748 100644
--- a/components/prefs/android/BUILD.gn
+++ b/components/prefs/android/BUILD.gn
@@ -11,7 +11,6 @@
 android_library("java") {
   sources = [ "java/src/org/chromium/components/prefs/PrefService.java" ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -26,7 +25,6 @@
   sources = [ "java/src/org/chromium/components/prefs/PrefServiceTest.java" ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/reporting/client/report_queue_impl_unittest.cc b/components/reporting/client/report_queue_impl_unittest.cc
index 7444bc7a..084258d 100644
--- a/components/reporting/client/report_queue_impl_unittest.cc
+++ b/components/reporting/client/report_queue_impl_unittest.cc
@@ -322,12 +322,33 @@
 
 TEST_F(ReportQueueImplTest, FlushSpeculativeReportQueue) {
   test::TestEvent<Status> event;
-  auto speculative_report_queue = SpeculativeReportQueueImpl::Create();
-  speculative_report_queue->Enqueue(kTestMessage, priority_, event.cb());
 
+  // Set up speculative report queue
+  auto speculative_report_queue = SpeculativeReportQueueImpl::Create();
+  speculative_report_queue->AttachActualQueue(std::move(report_queue_));
+  task_environment_.RunUntilIdle();
+
+  EXPECT_CALL(*test_storage_module(), Flush(Eq(priority_), _))
+      .WillOnce(
+          WithArg<1>(Invoke([](base::OnceCallback<void(Status)> callback) {
+            std::move(callback).Run(Status::StatusOK());
+          })));
+
+  speculative_report_queue->Flush(priority_, event.cb());
   const auto result = event.result();
   ASSERT_OK(result);
 }
 
+TEST_F(ReportQueueImplTest, FlushUninitializedSpeculativeReportQueue) {
+  test::TestEvent<Status> event;
+
+  auto speculative_report_queue = SpeculativeReportQueueImpl::Create();
+  speculative_report_queue->Flush(priority_, event.cb());
+
+  const auto result = event.result();
+  ASSERT_FALSE(result.ok());
+  EXPECT_EQ(result.error_code(), error::FAILED_PRECONDITION);
+}
+
 }  // namespace
 }  // namespace reporting
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc
index 0d350d4..26b7661 100644
--- a/components/reporting/storage/storage_queue.cc
+++ b/components/reporting/storage/storage_queue.cc
@@ -801,7 +801,6 @@
     DCHECK_LT(
         static_cast<uint32_t>(reason),
         static_cast<uint32_t>(UploaderInterface::UploadReason::MAX_REASON));
-    DETACH_FROM_SEQUENCE(read_sequence_checker_);
   }
 
  private:
@@ -809,7 +808,8 @@
   ~ReadContext() override = default;
 
   void OnStart() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
@@ -824,7 +824,8 @@
   }
 
   void PrepareDataFiles() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
@@ -882,7 +883,8 @@
   }
 
   void BeginUploading() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
@@ -906,7 +908,8 @@
   }
 
   void StartUploading() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     // Read from it until the specified sequencing id is found.
     for (int64_t sequencing_id = current_file_->first;
          sequencing_id < sequence_info_.sequencing_id(); ++sequencing_id) {
@@ -942,7 +945,8 @@
   }
 
   void UploadingCompleted(Status status) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     // If uploader was created, notify it about completion.
     if (uploader_) {
       uploader_->Completed(status);
@@ -960,7 +964,8 @@
   }
 
   void OnCompletion() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     // Unregister with storage_queue.
     if (!files_.empty()) {
       if (storage_queue_) {
@@ -972,7 +977,8 @@
 
   // Prepares the |blob| for uploading.
   void CallCurrentRecord(base::StringPiece blob) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     google::protobuf::io::ArrayInputStream blob_stream(  // Zero-copy stream.
         blob.data(), blob.size());
     EncryptedRecord encrypted_record;
@@ -993,7 +999,8 @@
   // empty (has no |encrypted_wrapped_record| and/or |encryption_info|), it
   // indicates a gap notification.
   void CallRecordUpload(EncryptedRecord encrypted_record) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (encrypted_record.has_sequence_information()) {
       LOG(ERROR) << "Sequence information already present, seq="
                  << sequence_info_.sequencing_id();
@@ -1012,7 +1019,8 @@
   }
 
   void CallGapUpload(uint64_t count) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (count == 0u) {
       // No records skipped.
       NextRecord(/*more_records=*/true);
@@ -1034,7 +1042,8 @@
   // sends for processing, or calls Response with error status. Otherwise, call
   // Response(OK).
   void NextRecord(bool more_records) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!more_records) {
       Response(Status::StatusOK());  // Requested to stop reading.
       return;
@@ -1061,7 +1070,8 @@
   // If anything goes wrong (file is shorter than expected, or record hash does
   // not match), returns error.
   StatusOr<base::StringPiece> EnsureBlob(int64_t sequencing_id) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!storage_queue_) {
       return Status(error::UNAVAILABLE, "StorageQueue shut down");
     }
@@ -1148,7 +1158,8 @@
   }
 
   void CallRecordOrGap(int64_t sequencing_id) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!storage_queue_) {
       Response(Status(error::UNAVAILABLE, "StorageQueue shut down"));
       return;
@@ -1206,7 +1217,8 @@
   void OnUploaderInstantiated(
       base::OnceCallback<void()> continuation,
       StatusOr<std::unique_ptr<UploaderInterface>> uploader_result) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (!uploader_result.ok()) {
       Response(Status(error::FAILED_PRECONDITION,
                       base::StrCat({"Failed to provide the Uploader, status=",
@@ -1233,8 +1245,6 @@
   const bool must_invoke_upload_;
   std::unique_ptr<UploaderInterface> uploader_;
   base::WeakPtr<StorageQueue> storage_queue_;
-
-  SEQUENCE_CHECKER(read_sequence_checker_);
 };
 
 class StorageQueue::WriteContext : public TaskRunnerContext<Status> {
@@ -1248,13 +1258,13 @@
         record_(std::move(record)),
         in_contexts_queue_(storage_queue->write_contexts_queue_.end()) {
     DCHECK(storage_queue.get());
-    DETACH_FROM_SEQUENCE(write_sequence_checker_);
   }
 
  private:
   // Context can only be deleted by calling Response method.
   ~WriteContext() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(write_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
 
     // If still in queue, remove it (something went wrong).
     if (in_contexts_queue_ != storage_queue_->write_contexts_queue_.end()) {
@@ -1284,7 +1294,8 @@
   }
 
   void OnStart() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(write_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
 
     // Make sure the record is valid.
     if (!record_.has_destination()) {
@@ -1423,14 +1434,16 @@
   }
 
   void WriteRecord(std::string buffer) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(write_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     buffer_.swap(buffer);
 
     ResumeWriteRecord();
   }
 
   void ResumeWriteRecord() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(write_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
 
     // If we are not at the head of the queue, delay write and expect to be
     // reactivated later.
@@ -1486,8 +1499,6 @@
   // Write buffer. When filled in (after encryption), |WriteRecord| can be
   // executed. Empty until encryption is done.
   std::string buffer_;
-
-  SEQUENCE_CHECKER(write_sequence_checker_);
 };
 
 void StorageQueue::Write(Record record,
@@ -1544,7 +1555,6 @@
         force_(force),
         storage_queue_(storage_queue) {
     DCHECK(storage_queue.get());
-    DETACH_FROM_SEQUENCE(confirm_sequence_checker_);
   }
 
  private:
@@ -1552,7 +1562,8 @@
   ~ConfirmContext() override = default;
 
   void OnStart() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(confirm_sequence_checker_);
+    DCHECK_CALLED_ON_VALID_SEQUENCE(
+        storage_queue_->storage_queue_sequence_checker_);
     if (force_) {
       storage_queue_->first_unconfirmed_sequencing_id_ =
           sequencing_id_.has_value() ? (sequencing_id_.value() + 1) : 0;
@@ -1570,8 +1581,6 @@
   bool force_;
 
   scoped_refptr<StorageQueue> storage_queue_;
-
-  SEQUENCE_CHECKER(confirm_sequence_checker_);
 };
 
 void StorageQueue::Confirm(absl::optional<int64_t> sequencing_id,
diff --git a/components/reporting/storage/storage_queue_stress_test.cc b/components/reporting/storage/storage_queue_stress_test.cc
index 0d23890..60ab506 100644
--- a/components/reporting/storage/storage_queue_stress_test.cc
+++ b/components/reporting/storage/storage_queue_stress_test.cc
@@ -231,7 +231,7 @@
     test::TestCallbackWaiter write_waiter;
     base::RepeatingCallback<void(Status)> cb = base::BindRepeating(
         [](test::TestCallbackWaiter* waiter, Status status) {
-          EXPECT_OK(status);
+          EXPECT_OK(status) << status;
           waiter->Signal();
         },
         &write_waiter);
diff --git a/components/safe_browsing/core/common/utils.cc b/components/safe_browsing/core/common/utils.cc
index e9f7c29..b43b1db9 100644
--- a/components/safe_browsing/core/common/utils.cc
+++ b/components/safe_browsing/core/common/utils.cc
@@ -51,7 +51,7 @@
 ChromeUserPopulation::ProfileManagementStatus GetProfileManagementStatus(
     const policy::BrowserPolicyConnector* bpc) {
 #if BUILDFLAG(IS_WIN)
-  if (base::IsMachineExternallyManaged())
+  if (base::IsManagedDevice())
     return ChromeUserPopulation::ENTERPRISE_MANAGED;
   else
     return ChromeUserPopulation::NOT_MANAGED;
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc
index 0532d6c..dfdaf68 100644
--- a/components/search_engines/template_url.cc
+++ b/components/search_engines/template_url.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/base64.h"
+#include "base/base64url.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
 #include "base/containers/adapters.h"
@@ -1098,8 +1099,9 @@
                 &serialized_searchbox_stats);
             if (!serialized_searchbox_stats.empty()) {
               std::string encoded_searchbox_stats;
-              base::Base64Encode(serialized_searchbox_stats,
-                                 &encoded_searchbox_stats);
+              base::Base64UrlEncode(serialized_searchbox_stats,
+                                    base::Base64UrlEncodePolicy::OMIT_PADDING,
+                                    &encoded_searchbox_stats);
               HandleReplacement("gs_lcrp", encoded_searchbox_stats, replacement,
                                 &url);
               base::UmaHistogramCounts1000(
diff --git a/components/search_engines/template_url_unittest.cc b/components/search_engines/template_url_unittest.cc
index 071d1761..e8180ef 100644
--- a/components/search_engines/template_url_unittest.cc
+++ b/components/search_engines/template_url_unittest.cc
@@ -687,7 +687,7 @@
       // HTTPS and non-empty gs_lcrp: replace gs_lcrp.
       {u"foo", non_empty_searchbox_stats, "https://foo/",
        "{google:baseURL}?q={searchTerms}&{google:searchboxStats}",
-       "https://foo/?q=foo&gs_lcrp=EgZjaHJvbWWwAgE=&"},
+       "https://foo/?q=foo&gs_lcrp=EgZjaHJvbWWwAgE&"},
       // HTTPS and non-empty gs_lcrp but no google:searchboxStats: no gs_lcrp.
       {u"foo", non_empty_searchbox_stats, "https://foo/",
        "{google:baseURL}?q={searchTerms}", "https://foo/?q=foo"},
@@ -702,7 +702,7 @@
       // gs_lcrp.
       {u"foo", non_empty_searchbox_stats, "https://foo/",
        "https://foo/?{searchTerms}&{google:searchboxStats}",
-       "https://foo/?foo&gs_lcrp=EgZjaHJvbWWwAgE=&"},
+       "https://foo/?foo&gs_lcrp=EgZjaHJvbWWwAgE&"},
       // Non-Google search provider, HTTPS and non-empty gs_lcrp but no
       // google:searchboxStats: no gs_lcrp.
       {u"foo", non_empty_searchbox_stats, "https://foo/",
@@ -725,7 +725,7 @@
   }
   // Expect correct histograms to have been logged.
   histogram_tester.ExpectTotalCount("Omnibox.SearchboxStats.Length", 2);
-  histogram_tester.ExpectBucketCount("Omnibox.SearchboxStats.Length", 16, 2);
+  histogram_tester.ExpectBucketCount("Omnibox.SearchboxStats.Length", 15, 2);
 }
 
 // Tests replacing searchbox stats (gs_lcrp) and assisted query stats (AQS).
@@ -751,13 +751,13 @@
       {u"foo", "chrome.0.0l6", non_empty_searchbox_stats, "https://foo/",
        "{google:baseURL}?q={searchTerms}&{google:searchboxStats}{google:"
        "assistedQueryStats}",
-       "https://foo/?q=foo&gs_lcrp=EgZjaHJvbWWwAgE=&aqs=chrome.0.0l6&"},
+       "https://foo/?q=foo&gs_lcrp=EgZjaHJvbWWwAgE&aqs=chrome.0.0l6&"},
       // Non-Google search provider, HTTPS and non-empty gs_lcrp and AQS:
       // replace both.
       {u"foo", "chrome.0.0l6", non_empty_searchbox_stats, "https://foo/",
        "https://foo/"
        "?{searchTerms}&{google:searchboxStats}{google:assistedQueryStats}",
-       "https://foo/?foo&gs_lcrp=EgZjaHJvbWWwAgE=&aqs=chrome.0.0l6&"},
+       "https://foo/?foo&gs_lcrp=EgZjaHJvbWWwAgE&aqs=chrome.0.0l6&"},
   };
   TemplateURLData data;
   data.input_encodings.push_back("UTF-8");
@@ -780,7 +780,7 @@
   histogram_tester.ExpectBucketCount("Omnibox.AssistedQueryStats.Length", 12,
                                      2);
   histogram_tester.ExpectTotalCount("Omnibox.SearchboxStats.Length", 2);
-  histogram_tester.ExpectBucketCount("Omnibox.SearchboxStats.Length", 16, 2);
+  histogram_tester.ExpectBucketCount("Omnibox.SearchboxStats.Length", 15, 2);
 }
 
 // Tests replacing cursor position.
diff --git a/components/security_state/content/android/BUILD.gn b/components/security_state/content/android/BUILD.gn
index 0679c13..81ccc5a 100644
--- a/components/security_state/content/android/BUILD.gn
+++ b/components/security_state/content/android/BUILD.gn
@@ -25,7 +25,6 @@
     "java/src/org/chromium/components/security_state/SecurityStateModel.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/security_state/core:security_state_enums_java",
diff --git a/components/segmentation_platform/internal/database/storage_service.cc b/components/segmentation_platform/internal/database/storage_service.cc
index 944e6562..e4618f8 100644
--- a/components/segmentation_platform/internal/database/storage_service.cc
+++ b/components/segmentation_platform/internal/database/storage_service.cc
@@ -143,13 +143,6 @@
       .Run(*segment_info_database_initialized_ &&
            *signal_database_initialized_ &&
            *signal_storage_config_initialized_);
-
-  // Initiate database maintenance tasks with a small delay.
-  base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE,
-      base::BindOnce(&StorageService::OnExecuteDatabaseMaintenanceTasks,
-                     weak_ptr_factory_.GetWeakPtr()),
-      kDatabaseMaintenanceDelay);
 }
 
 int StorageService::GetServiceStatus() const {
@@ -164,7 +157,19 @@
   return status;
 }
 
-void StorageService::OnExecuteDatabaseMaintenanceTasks() {
+void StorageService::ExecuteDatabaseMaintenanceTasks(bool is_startup) {
+  if (is_startup) {
+    // Initiate database maintenance tasks with a small delay at startup.
+    base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::BindOnce(&StorageService::ExecuteDatabaseMaintenanceTasks,
+                       weak_ptr_factory_.GetWeakPtr(), false),
+        kDatabaseMaintenanceDelay);
+    return;
+  }
+
+  // This should be invoked at least after a short amount of time has passed
+  // since initialization happened.
   database_maintenance_->ExecuteMaintenanceTasks();
 }
 
diff --git a/components/segmentation_platform/internal/database/storage_service.h b/components/segmentation_platform/internal/database/storage_service.h
index a5c33bb..d5dbd1a1 100644
--- a/components/segmentation_platform/internal/database/storage_service.h
+++ b/components/segmentation_platform/internal/database/storage_service.h
@@ -104,6 +104,9 @@
   // bitmap values.
   int GetServiceStatus() const;
 
+  // Executes all database maintenance tasks.
+  void ExecuteDatabaseMaintenanceTasks(bool is_startup);
+
   DefaultModelManager* default_model_manager() {
     DCHECK(default_model_manager_);
     return default_model_manager_.get();
@@ -128,10 +131,6 @@
   bool IsInitializationFinished() const;
   void MaybeFinishInitialization();
 
-  // Executes all database maintenance tasks. This should be invoked after a
-  // short amount of time has passed since initialization happened.
-  void OnExecuteDatabaseMaintenanceTasks();
-
   // Default models.
   std::unique_ptr<DefaultModelManager> default_model_manager_;
 
diff --git a/components/segmentation_platform/internal/scheduler/execution_service.cc b/components/segmentation_platform/internal/scheduler/execution_service.cc
index bfc0a3b7..7c198ee 100644
--- a/components/segmentation_platform/internal/scheduler/execution_service.cc
+++ b/components/segmentation_platform/internal/scheduler/execution_service.cc
@@ -79,9 +79,6 @@
       std::move(observers), storage_service->segment_info_database(),
       storage_service->signal_storage_config(), model_execution_manager_.get(),
       model_executor_.get(), all_segment_ids, clock, platform_options);
-
-  model_execution_scheduler_->RequestModelExecutionForEligibleSegments(
-      /*expired_only=*/true);
 }
 
 void ExecutionService::OnNewModelInfoReady(
@@ -118,4 +115,9 @@
   model_execution_scheduler_->OnModelExecutionCompleted(segment_id, result);
 }
 
+void ExecutionService::RefreshModelResults() {
+  model_execution_scheduler_->RequestModelExecutionForEligibleSegments(
+      /*expired_only=*/true);
+}
+
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/scheduler/execution_service.h b/components/segmentation_platform/internal/scheduler/execution_service.h
index da403e2..dbe2ebc 100644
--- a/components/segmentation_platform/internal/scheduler/execution_service.h
+++ b/components/segmentation_platform/internal/scheduler/execution_service.h
@@ -87,6 +87,9 @@
       optimization_guide::proto::OptimizationTarget segment_id,
       const std::pair<float, ModelExecutionStatus>& result);
 
+  // Refreshes model results for all eligible models.
+  void RefreshModelResults();
+
  private:
   // Training/inference input data generation.
   std::unique_ptr<processing::FeatureListQueryProcessor>
@@ -95,6 +98,7 @@
   // Traing data collection logic.
   std::unique_ptr<TrainingDataCollector> training_data_collector_;
 
+  // Utility to execute model and return result.
   std::unique_ptr<ModelExecutor> model_executor_;
 
   // Scheduler to launch tasks to report training data to the server.
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
index 7df51fc..62d3115 100644
--- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
+++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -85,8 +85,11 @@
                                                  all_segment_ids_.end());
 
   // Construct signal processors.
-  signal_handler_.Initialize(storage_service_.get(),
-                             init_params->history_service, segment_id_vec);
+  signal_handler_.Initialize(
+      storage_service_.get(), init_params->history_service, segment_id_vec,
+      base::BindRepeating(
+          &SegmentationPlatformServiceImpl::OnModelRefreshNeeded,
+          weak_ptr_factory_.GetWeakPtr()));
 
   for (const auto& config : configs_) {
     segment_selectors_[config->segmentation_key] =
@@ -177,6 +180,8 @@
     selector.second->OnPlatformInitialized(&execution_service_);
   }
 
+  RunDailyTasks(/*is_startup=*/true);
+
   init_time_ = clock_->Now();
   base::UmaHistogramMediumTimes(
       "SegmentationPlatform.Init.CreationToInitializationLatency",
@@ -199,11 +204,26 @@
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
+void SegmentationPlatformServiceImpl::OnModelRefreshNeeded() {
+  execution_service_.RefreshModelResults();
+}
+
 void SegmentationPlatformServiceImpl::OnServiceStatusChanged() {
   proxy_->OnServiceStatusChanged(storage_initialized_,
                                  storage_service_->GetServiceStatus());
 }
 
+void SegmentationPlatformServiceImpl::RunDailyTasks(bool is_startup) {
+  execution_service_.RefreshModelResults();
+  storage_service_->ExecuteDatabaseMaintenanceTasks(is_startup);
+
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(&SegmentationPlatformServiceImpl::RunDailyTasks,
+                     weak_ptr_factory_.GetWeakPtr(), /*is_startup=*/false),
+      base::Days(1));
+}
+
 // static
 void SegmentationPlatformService::RegisterProfilePrefs(
     PrefRegistrySimple* registry) {
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.h b/components/segmentation_platform/internal/segmentation_platform_service_impl.h
index 93fe56d..ce16726 100644
--- a/components/segmentation_platform/internal/segmentation_platform_service_impl.h
+++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.h
@@ -104,9 +104,16 @@
   // Must only be invoked with a valid SegmentInfo.
   void OnSegmentationModelUpdated(proto::SegmentInfo segment_info);
 
+  // Callback sent to child classes to notify when model results need to be
+  // refreshed. For example, when history is cleared.
+  void OnModelRefreshNeeded();
+
   // Called when service status changes.
   void OnServiceStatusChanged();
 
+  // Task that runs every day or at startup to keep the platform data updated.
+  void RunDailyTasks(bool is_startup);
+
   std::unique_ptr<ModelProviderFactory> model_provider_factory_;
 
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/components/segmentation_platform/internal/signals/history_service_observer.cc b/components/segmentation_platform/internal/signals/history_service_observer.cc
index f09327d..e4baf35 100644
--- a/components/segmentation_platform/internal/signals/history_service_observer.cc
+++ b/components/segmentation_platform/internal/signals/history_service_observer.cc
@@ -5,6 +5,7 @@
 #include "components/segmentation_platform/internal/signals/history_service_observer.h"
 
 #include "base/metrics/user_metrics.h"
+#include "base/trace_event/trace_event.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_service_observer.h"
 #include "components/segmentation_platform/internal/database/segment_info_database.h"
@@ -17,10 +18,12 @@
 
 HistoryServiceObserver::HistoryServiceObserver(
     history::HistoryService* history_service,
-    StorageService* storage_service)
+    StorageService* storage_service,
+    base::RepeatingClosure models_refresh_callback)
     : storage_service_(storage_service),
       url_signal_handler_(
           storage_service->ukm_data_manager()->GetOrCreateUrlHandler()),
+      models_refresh_callback_(models_refresh_callback),
       history_delegate_(
           std::make_unique<HistoryDelegateImpl>(history_service,
                                                 url_signal_handler_)) {
@@ -44,6 +47,9 @@
 void HistoryServiceObserver::OnURLsDeleted(
     history::HistoryService* history_service,
     const history::DeletionInfo& deletion_info) {
+  TRACE_EVENT0("segmentation_platform",
+               "HistoryServiceObserver::OnURLsDeleted");
+
   // If the history deletion was not from expiration or if the whole history
   // database was removed, delete the segment results computed based on URL
   // data.
@@ -89,6 +95,17 @@
     storage_service_->segment_info_database()->SaveSegmentResult(
         segment_id, absl::nullopt, base::DoNothing());
   }
+
+  // If a model refresh was recently posted, then cancel the task and restart
+  // the 30 second timer. This is to avoid running models often when user clears
+  // multiple history entries at once.
+  if (posted_model_refresh_task_) {
+    posted_model_refresh_task_->Cancel();
+  }
+  posted_model_refresh_task_ = std::make_unique<base::CancelableOnceClosure>(
+      base::BindOnce(models_refresh_callback_));
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, posted_model_refresh_task_->callback(), base::Minutes(1));
 }
 
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/signals/history_service_observer.h b/components/segmentation_platform/internal/signals/history_service_observer.h
index 3aca0ef49..ada31ae3 100644
--- a/components/segmentation_platform/internal/signals/history_service_observer.h
+++ b/components/segmentation_platform/internal/signals/history_service_observer.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_SIGNALS_HISTORY_SERVICE_OBSERVER_H_
 #define COMPONENTS_SEGMENTATION_PLATFORM_INTERNAL_SIGNALS_HISTORY_SERVICE_OBSERVER_H_
 
+#include "base/cancelable_callback.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
@@ -24,7 +25,8 @@
 class HistoryServiceObserver : public history::HistoryServiceObserver {
  public:
   HistoryServiceObserver(history::HistoryService* history_service,
-                         StorageService* storage_service);
+                         StorageService* storage_service,
+                         base::RepeatingClosure models_refresh_callback);
   // For tests.
   HistoryServiceObserver();
   ~HistoryServiceObserver() override;
@@ -58,6 +60,9 @@
       history_based_segments_;
   bool pending_deletion_based_on_history_based_segments_ = false;
 
+  base::RepeatingClosure models_refresh_callback_;
+  std::unique_ptr<base::CancelableOnceClosure> posted_model_refresh_task_;
+
   std::unique_ptr<HistoryDelegateImpl> history_delegate_;
   base::ScopedObservation<history::HistoryService,
                           history::HistoryServiceObserver>
diff --git a/components/segmentation_platform/internal/signals/signal_handler.cc b/components/segmentation_platform/internal/signals/signal_handler.cc
index c180993..4a99703 100644
--- a/components/segmentation_platform/internal/signals/signal_handler.cc
+++ b/components/segmentation_platform/internal/signals/signal_handler.cc
@@ -20,7 +20,8 @@
     StorageService* storage_service,
     history::HistoryService* history_service,
     const std::vector<optimization_guide::proto::OptimizationTarget>&
-        segment_ids) {
+        segment_ids,
+    base::RepeatingClosure models_refresh_callback) {
   user_action_signal_handler_ = std::make_unique<UserActionSignalHandler>(
       storage_service->signal_database());
   histogram_signal_handler_ = std::make_unique<HistogramSignalHandler>(
@@ -31,7 +32,7 @@
     // If UKM engine is enabled and history service is not available, then we
     // would write metrics without URLs to the database, which is OK.
     history_service_observer_ = std::make_unique<HistoryServiceObserver>(
-        history_service, storage_service);
+        history_service, storage_service, models_refresh_callback);
   }
 
   signal_filter_processor_ = std::make_unique<SignalFilterProcessor>(
diff --git a/components/segmentation_platform/internal/signals/signal_handler.h b/components/segmentation_platform/internal/signals/signal_handler.h
index 6b3d7ad6..77072aa 100644
--- a/components/segmentation_platform/internal/signals/signal_handler.h
+++ b/components/segmentation_platform/internal/signals/signal_handler.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/callback.h"
 #include "components/optimization_guide/proto/models.pb.h"
 
 namespace history {
@@ -36,7 +37,8 @@
       StorageService* storage_service,
       history::HistoryService* history_service,
       const std::vector<optimization_guide::proto::OptimizationTarget>&
-          segment_ids);
+          segment_ids,
+      base::RepeatingClosure model_refresh_callback);
 
   void TearDown();
 
diff --git a/components/site_settings_strings.grdp b/components/site_settings_strings.grdp
index d88234f..30559a5 100644
--- a/components/site_settings_strings.grdp
+++ b/components/site_settings_strings.grdp
@@ -148,6 +148,12 @@
 
   <!-- Site Settings desktop-only -->
   <if expr="not is_android">
+  <message name="IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API" desc="The label used for the third-party sign-in site settings controls.">
+    Third-party sign-in
+  </message>
+  <message name="IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE" desc="The label used for the third-party sign-in site settings controls when used mid-sentence.">
+    third-party sign-in
+  </message>
   <message name="IDS_SITE_SETTINGS_TYPE_FILE_SYSTEM_ACCESS_WRITE" desc="The label used for the File System Access write site settings controls. The write permission determines whether sites are allowed to save to the original file that was selected by the user through the File System Access API.">
     File editing
   </message>
diff --git a/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API.png.sha1 b/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API.png.sha1
new file mode 100644
index 0000000..47984e4
--- /dev/null
+++ b/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API.png.sha1
@@ -0,0 +1 @@
+4e0f7428b0978106d7f4e4be3b9339f5d65d7b2c
\ No newline at end of file
diff --git a/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE.png.sha1 b/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE.png.sha1
new file mode 100644
index 0000000..02e3f22b
--- /dev/null
+++ b/components/site_settings_strings_grdp/IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API_MID_SENTENCE.png.sha1
@@ -0,0 +1 @@
+0a3a30e094fc5bdd013e3982decfbf85fa03c861
\ No newline at end of file
diff --git a/components/sync/android/BUILD.gn b/components/sync/android/BUILD.gn
index 9be36c3..4ebefb2b 100644
--- a/components/sync/android/BUILD.gn
+++ b/components/sync/android/BUILD.gn
@@ -7,7 +7,6 @@
 
 android_library("sync_java") {
   deps = [
-    "//base:base_java",
     "//net/android:net_java",
     "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/components/sync_bookmarks/bookmark_model_observer_impl.cc b/components/sync_bookmarks/bookmark_model_observer_impl.cc
index 67ef2e3..9085aeb2 100644
--- a/components/sync_bookmarks/bookmark_model_observer_impl.cc
+++ b/components/sync_bookmarks/bookmark_model_observer_impl.cc
@@ -75,6 +75,7 @@
   // Mark the entity that it needs to be committed.
   bookmark_tracker_->IncrementSequenceNumber(entity);
   nudge_for_commit_closure_.Run();
+  bookmark_tracker_->CheckAllNodesTracked(model);
 }
 
 void BookmarkModelObserverImpl::BookmarkNodeAdded(
@@ -119,6 +120,10 @@
   // Mark the entity that it needs to be committed.
   bookmark_tracker_->IncrementSequenceNumber(entity);
   nudge_for_commit_closure_.Run();
+
+  // Do not check if all nodes are tracked because it's still possible that some
+  // nodes are untracked, e.g. if current node has been just restored and its
+  // children will be added soon.
 }
 
 void BookmarkModelObserverImpl::OnWillRemoveBookmarks(
@@ -147,6 +152,7 @@
 
 void BookmarkModelObserverImpl::OnWillRemoveAllUserBookmarks(
     bookmarks::BookmarkModel* model) {
+  bookmark_tracker_->CheckAllNodesTracked(model);
   const bookmarks::BookmarkNode* root_node = model->root_node();
   for (const auto& permanent_node : root_node->children()) {
     for (const auto& child : permanent_node->children()) {
@@ -161,6 +167,7 @@
     bookmarks::BookmarkModel* model,
     const std::set<GURL>& removed_urls) {
   // All the work should have already been done in OnWillRemoveAllUserBookmarks.
+  bookmark_tracker_->CheckAllNodesTracked(model);
 }
 
 void BookmarkModelObserverImpl::BookmarkNodeChanged(
diff --git a/components/sync_bookmarks/bookmark_model_type_processor.cc b/components/sync_bookmarks/bookmark_model_type_processor.cc
index b761d38d..ba2fb55 100644
--- a/components/sync_bookmarks/bookmark_model_type_processor.cc
+++ b/components/sync_bookmarks/bookmark_model_type_processor.cc
@@ -256,7 +256,6 @@
       model, std::move(model_metadata));
 
   if (bookmark_tracker_) {
-    bookmark_tracker_->CheckAllNodesTracked(bookmark_model_);
     StartTrackingMetadata();
   } else if (!metadata_str.empty()) {
     DLOG(WARNING)
diff --git a/components/sync_bookmarks/synced_bookmark_tracker.cc b/components/sync_bookmarks/synced_bookmark_tracker.cc
index f3bd203..f358370 100644
--- a/components/sync_bookmarks/synced_bookmark_tracker.cc
+++ b/components/sync_bookmarks/synced_bookmark_tracker.cc
@@ -769,32 +769,22 @@
 
 void SyncedBookmarkTracker::CheckAllNodesTracked(
     const bookmarks::BookmarkModel* bookmark_model) const {
-  // TODO(crbug.com/516866): The method is added to debug some crashes.
-  // Since it's relatively expensive, it should run on debug enabled
-  // builds only after the root cause is found.
-  CHECK(GetEntityForBookmarkNode(bookmark_model->bookmark_bar_node()));
-  CHECK(GetEntityForBookmarkNode(bookmark_model->other_node()));
-  CHECK(GetEntityForBookmarkNode(bookmark_model->mobile_node()));
+#if DCHECK_IS_ON()
+  DCHECK(GetEntityForBookmarkNode(bookmark_model->bookmark_bar_node()));
+  DCHECK(GetEntityForBookmarkNode(bookmark_model->other_node()));
+  DCHECK(GetEntityForBookmarkNode(bookmark_model->mobile_node()));
 
   ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
       bookmark_model->root_node());
   while (iterator.has_next()) {
     const bookmarks::BookmarkNode* node = iterator.Next();
     if (!bookmark_model->client()->CanSyncNode(node)) {
-      // TODO(crbug.com/516866): The below CHECK is added to debug some crashes.
-      // Should be converted to a DCHECK after the root cause if found.
-      CHECK(!GetEntityForBookmarkNode(node));
+      DCHECK(!GetEntityForBookmarkNode(node));
       continue;
     }
-    // Root node is usually tracked, unless the sync data has been provided by
-    // the USS migrator.
-    if (node == bookmark_model->root_node()) {
-      continue;
-    }
-    // TODO(crbug.com/516866): The below CHECK is added to debug some crashes.
-    // Should be converted to a DCHECK after the root cause if found.
-    CHECK(GetEntityForBookmarkNode(node));
+    DCHECK(GetEntityForBookmarkNode(node));
   }
+#endif  // DCHECK_IS_ON()
 }
 
 }  // namespace sync_bookmarks
diff --git a/components/thin_webview/BUILD.gn b/components/thin_webview/BUILD.gn
index 204b6a05..d0aa3fb 100644
--- a/components/thin_webview/BUILD.gn
+++ b/components/thin_webview/BUILD.gn
@@ -22,7 +22,6 @@
   ]
 
   deps = [
-    "//base:base_java",
     "//components/embedder_support/android:web_contents_delegate_java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
@@ -39,7 +38,6 @@
   deps = [
     ":java",
     "internal:internal_java",
-    "//base:base_java",
     "//content/public/android:content_java",
     "//ui/android:ui_java",
   ]
diff --git a/components/translate/content/android/BUILD.gn b/components/translate/content/android/BUILD.gn
index 8f63e1f..76b55a7 100644
--- a/components/translate/content/android/BUILD.gn
+++ b/components/translate/content/android/BUILD.gn
@@ -101,7 +101,6 @@
       [ "java/src/org/chromium/components/translate/TranslateOptionsTest.java" ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//third_party/android_support_test_runner:rules_java",
     "//third_party/android_support_test_runner:runner_java",
diff --git a/components/translate/content/android/java/src/org/chromium/components/translate/TranslateMessage.java b/components/translate/content/android/java/src/org/chromium/components/translate/TranslateMessage.java
index efd1e7a..dbe944cb 100644
--- a/components/translate/content/android/java/src/org/chromium/components/translate/TranslateMessage.java
+++ b/components/translate/content/android/java/src/org/chromium/components/translate/TranslateMessage.java
@@ -6,6 +6,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.text.TextUtils;
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
@@ -19,6 +20,7 @@
 import org.chromium.components.messages.MessageIdentifier;
 import org.chromium.components.messages.MessageScopeType;
 import org.chromium.components.messages.PrimaryActionClickBehavior;
+import org.chromium.components.messages.PrimaryWidgetAppearance;
 import org.chromium.components.messages.SecondaryMenuMaxSize;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
@@ -117,8 +119,15 @@
 
         mMessageProperties.set(MessageBannerProperties.TITLE, title);
         mMessageProperties.set(MessageBannerProperties.DESCRIPTION, description);
-        mMessageProperties.set(MessageBannerProperties.PRIMARY_BUTTON_TEXT,
-                primaryButtonText == null ? "" : primaryButtonText);
+
+        if (TextUtils.isEmpty(primaryButtonText)) {
+            mMessageProperties.set(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                    PrimaryWidgetAppearance.PROGRESS_SPINNER);
+        } else {
+            mMessageProperties.set(MessageBannerProperties.PRIMARY_BUTTON_TEXT, primaryButtonText);
+            mMessageProperties.set(MessageBannerProperties.PRIMARY_WIDGET_APPEARANCE,
+                    PrimaryWidgetAppearance.BUTTON_IF_TEXT_IS_SET);
+        }
 
         if (needsDispatch) {
             mMessageDispatcher.enqueueMessage(mMessageProperties, mWebContents,
diff --git a/components/ukm/android/BUILD.gn b/components/ukm/android/BUILD.gn
index b99cf614..a30b741 100644
--- a/components/ukm/android/BUILD.gn
+++ b/components/ukm/android/BUILD.gn
@@ -8,7 +8,6 @@
   sources = [ "java/src/org/chromium/components/ukm/UkmRecorder.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//content/public/android:content_java",
diff --git a/components/url_formatter/android/BUILD.gn b/components/url_formatter/android/BUILD.gn
index 1e9719e5..06b27dd 100644
--- a/components/url_formatter/android/BUILD.gn
+++ b/components/url_formatter/android/BUILD.gn
@@ -6,7 +6,6 @@
 
 android_library("url_formatter_java") {
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/components/user_notes/browser/BUILD.gn b/components/user_notes/browser/BUILD.gn
index be75b1dd..ff0ade2 100644
--- a/components/user_notes/browser/BUILD.gn
+++ b/components/user_notes/browser/BUILD.gn
@@ -8,12 +8,12 @@
     "frame_user_note_changes.h",
     "user_note_instance.cc",
     "user_note_instance.h",
+    "user_note_manager.cc",
+    "user_note_manager.h",
     "user_note_service.cc",
     "user_note_service.h",
     "user_note_utils.cc",
     "user_note_utils.h",
-    "user_notes_manager.cc",
-    "user_notes_manager.h",
   ]
 
   deps = [
@@ -30,9 +30,9 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "user_note_manager_unittest.cc",
     "user_note_service_unittest.cc",
     "user_note_utils_unittest.cc",
-    "user_notes_manager_unittest.cc",
   ]
 
   deps = [
diff --git a/components/user_notes/browser/user_notes_manager.cc b/components/user_notes/browser/user_note_manager.cc
similarity index 72%
rename from components/user_notes/browser/user_notes_manager.cc
rename to components/user_notes/browser/user_note_manager.cc
index 4a998829..e96dd98a 100644
--- a/components/user_notes/browser/user_notes_manager.cc
+++ b/components/user_notes/browser/user_note_manager.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 "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 
 #include "base/memory/ptr_util.h"
 #include "components/user_notes/browser/user_note_instance.h"
@@ -11,24 +11,24 @@
 namespace user_notes {
 
 // static
-std::unique_ptr<UserNotesManager> UserNotesManager::CreateForTest(
+std::unique_ptr<UserNoteManager> UserNoteManager::CreateForTest(
     content::Page& page,
     base::SafeRef<UserNoteService> service) {
-  return base::WrapUnique(new UserNotesManager(page, service));
+  return base::WrapUnique(new UserNoteManager(page, service));
 }
 
-UserNotesManager::UserNotesManager(content::Page& page,
-                                   base::SafeRef<UserNoteService> service)
-    : PageUserData<UserNotesManager>(page), service_(service) {}
+UserNoteManager::UserNoteManager(content::Page& page,
+                                 base::SafeRef<UserNoteService> service)
+    : PageUserData<UserNoteManager>(page), service_(service) {}
 
-UserNotesManager::~UserNotesManager() {
+UserNoteManager::~UserNoteManager() {
   for (const auto& entry_it : instance_map_) {
     service_->OnNoteInstanceRemovedFromPage(entry_it.second->model().id(),
                                             this);
   }
 }
 
-UserNoteInstance* UserNotesManager::GetNoteInstance(
+UserNoteInstance* UserNoteManager::GetNoteInstance(
     const base::UnguessableToken id) {
   const auto& entry_it = instance_map_.find(id);
   if (entry_it == instance_map_.end()) {
@@ -38,7 +38,7 @@
   return entry_it->second.get();
 }
 
-const std::vector<UserNoteInstance*> UserNotesManager::GetAllNoteInstances() {
+const std::vector<UserNoteInstance*> UserNoteManager::GetAllNoteInstances() {
   std::vector<UserNoteInstance*> notes;
   notes.reserve(instance_map_.size());
   for (const auto& entry_it : instance_map_) {
@@ -48,7 +48,7 @@
   return notes;
 }
 
-void UserNotesManager::RemoveNote(const base::UnguessableToken id) {
+void UserNoteManager::RemoveNote(const base::UnguessableToken id) {
   const auto& entry_it = instance_map_.find(id);
   DCHECK(entry_it != instance_map_.end())
       << "Attempted to remove a note instance from a page where it didn't "
@@ -58,7 +58,7 @@
   instance_map_.erase(entry_it);
 }
 
-void UserNotesManager::AddNoteInstance(std::unique_ptr<UserNoteInstance> note) {
+void UserNoteManager::AddNoteInstance(std::unique_ptr<UserNoteInstance> note) {
   // TODO(crbug.com/1313967): This DCHECK is only applicable if notes are only
   // supported in the top-level frame. If notes are ever supported in subframes,
   // it is possible for the same note ID to be added to the same page more than
@@ -73,6 +73,6 @@
   instance_map_.emplace(note->model().id(), std::move(note));
 }
 
-PAGE_USER_DATA_KEY_IMPL(UserNotesManager);
+PAGE_USER_DATA_KEY_IMPL(UserNoteManager);
 
 }  // namespace user_notes
diff --git a/components/user_notes/browser/user_notes_manager.h b/components/user_notes/browser/user_note_manager.h
similarity index 72%
rename from components/user_notes/browser/user_notes_manager.h
rename to components/user_notes/browser/user_note_manager.h
index 368f70ab..241f4d0 100644
--- a/components/user_notes/browser/user_notes_manager.h
+++ b/components/user_notes/browser/user_note_manager.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_USER_NOTES_BROWSER_USER_NOTES_MANAGER_H_
-#define COMPONENTS_USER_NOTES_BROWSER_USER_NOTES_MANAGER_H_
+#ifndef COMPONENTS_USER_NOTES_BROWSER_USER_NOTE_MANAGER_H_
+#define COMPONENTS_USER_NOTES_BROWSER_USER_NOTE_MANAGER_H_
 
 #include <memory>
 #include <string>
@@ -27,18 +27,18 @@
 // |Page|. Its lifecycle is tied to the |Page| it is associated with, so it
 // implements |PageUserData|. A tab helper is responsible for attaching an
 // instance of this class to each new |Page|.
-class UserNotesManager : public content::PageUserData<UserNotesManager> {
+class UserNoteManager : public content::PageUserData<UserNoteManager> {
  public:
   // Exposes a way to construct this object from unit tests. Do not use in
-  // product code; instead, use UserNotesManager::CreateForPage, inherited from
+  // product code; instead, use UserNoteManager::CreateForPage, inherited from
   // PageUserData.
-  static std::unique_ptr<UserNotesManager> CreateForTest(
+  static std::unique_ptr<UserNoteManager> CreateForTest(
       content::Page& page,
       base::SafeRef<UserNoteService> service);
 
-  ~UserNotesManager() override;
-  UserNotesManager(const UserNotesManager&) = delete;
-  UserNotesManager& operator=(const UserNotesManager&) = delete;
+  ~UserNoteManager() override;
+  UserNoteManager(const UserNoteManager&) = delete;
+  UserNoteManager& operator=(const UserNoteManager&) = delete;
 
   // Returns the note instance for the given ID, or nullptr if this page does
   // not have an instance of that note.
@@ -54,15 +54,15 @@
   void AddNoteInstance(std::unique_ptr<UserNoteInstance> note);
 
  private:
-  FRIEND_TEST_ALL_PREFIXES(UserNotesManagerTest, Destructor);
-  FRIEND_TEST_ALL_PREFIXES(UserNotesManagerTest, GetNoteInstance);
-  FRIEND_TEST_ALL_PREFIXES(UserNotesManagerTest, GetAllNoteInstances);
-  FRIEND_TEST_ALL_PREFIXES(UserNotesManagerTest, RemoveNote);
-  FRIEND_TEST_ALL_PREFIXES(UserNotesManagerTest, AddNoteInstance);
-  friend class content::PageUserData<UserNotesManager>;
+  FRIEND_TEST_ALL_PREFIXES(UserNoteManagerTest, Destructor);
+  FRIEND_TEST_ALL_PREFIXES(UserNoteManagerTest, GetNoteInstance);
+  FRIEND_TEST_ALL_PREFIXES(UserNoteManagerTest, GetAllNoteInstances);
+  FRIEND_TEST_ALL_PREFIXES(UserNoteManagerTest, RemoveNote);
+  FRIEND_TEST_ALL_PREFIXES(UserNoteManagerTest, AddNoteInstance);
+  friend class content::PageUserData<UserNoteManager>;
   friend class UserNoteUtilsTest;
 
-  UserNotesManager(content::Page& page, base::SafeRef<UserNoteService> service);
+  UserNoteManager(content::Page& page, base::SafeRef<UserNoteService> service);
 
   PAGE_USER_DATA_KEY_DECL();
 
@@ -86,4 +86,4 @@
 
 }  // namespace user_notes
 
-#endif  // COMPONENTS_USER_NOTES_BROWSER_USER_NOTES_MANAGER_H_
+#endif  // COMPONENTS_USER_NOTES_BROWSER_USER_NOTE_MANAGER_H_
diff --git a/components/user_notes/browser/user_notes_manager_unittest.cc b/components/user_notes/browser/user_note_manager_unittest.cc
similarity index 91%
rename from components/user_notes/browser/user_notes_manager_unittest.cc
rename to components/user_notes/browser/user_note_manager_unittest.cc
index 4840221..e649021 100644
--- a/components/user_notes/browser/user_notes_manager_unittest.cc
+++ b/components/user_notes/browser/user_note_manager_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 
 #include <memory>
 
@@ -33,9 +33,9 @@
 
 }  // namespace
 
-class UserNotesManagerTest : public testing::Test {
+class UserNoteManagerTest : public testing::Test {
  public:
-  UserNotesManagerTest() {
+  UserNoteManagerTest() {
     // Create 3 note ids.
     note_ids_.push_back(base::UnguessableToken::Create());
     note_ids_.push_back(base::UnguessableToken::Create());
@@ -75,7 +75,7 @@
   int ModelMapSize() { return note_service_->model_map_.size(); }
 
   bool DoesManagerExistForId(const base::UnguessableToken& id,
-                             UserNotesManager* manager) {
+                             UserNoteManager* manager) {
     const auto& model_entry_it = note_service_->model_map_.find(id);
     if (model_entry_it == note_service_->model_map_.end()) {
       return false;
@@ -103,12 +103,12 @@
   std::vector<base::UnguessableToken> note_ids_;
 };
 
-TEST_F(UserNotesManagerTest, Destructor) {
+TEST_F(UserNoteManagerTest, Destructor) {
   // Initial setup.
   auto m1 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   auto m2 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   m2->AddNoteInstance(
       std::make_unique<UserNoteInstance>(GetSafeRefForNote(note_ids_[0])));
   m2->AddNoteInstance(
@@ -139,10 +139,10 @@
   EXPECT_EQ(ModelMapSize(), 0);
 }
 
-TEST_F(UserNotesManagerTest, GetNoteInstance) {
+TEST_F(UserNoteManagerTest, GetNoteInstance) {
   // Initial setup.
   auto m =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   m->AddNoteInstance(
       std::make_unique<UserNoteInstance>(GetSafeRefForNote(note_ids_[0])));
   m->AddNoteInstance(
@@ -163,10 +163,10 @@
   EXPECT_EQ(i->model().id(), note_ids_[2]);
 }
 
-TEST_F(UserNotesManagerTest, GetAllNoteInstances) {
+TEST_F(UserNoteManagerTest, GetAllNoteInstances) {
   // Initial setup.
   auto m =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
 
   // Verify initial state.
   EXPECT_EQ(m->instance_map_.size(), 0u);
@@ -190,12 +190,12 @@
   EXPECT_TRUE(DoResultsContainId(results, note_ids_[2]));
 }
 
-TEST_F(UserNotesManagerTest, RemoveNote) {
+TEST_F(UserNoteManagerTest, RemoveNote) {
   // Initial setup.
   auto m1 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   auto m2 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   m1->AddNoteInstance(
       std::make_unique<UserNoteInstance>(GetSafeRefForNote(note_ids_[0])));
   m1->AddNoteInstance(
@@ -241,12 +241,12 @@
   EXPECT_TRUE(DoesManagerExistForId(note_ids_[0], m2.get()));
 }
 
-TEST_F(UserNotesManagerTest, AddNoteInstance) {
+TEST_F(UserNoteManagerTest, AddNoteInstance) {
   // Initial setup.
   auto m1 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   auto m2 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
 
   // Verify initial state.
   EXPECT_EQ(ModelMapSize(), 3);
diff --git a/components/user_notes/browser/user_note_service.cc b/components/user_notes/browser/user_note_service.cc
index c7e1794b..dca68b5 100644
--- a/components/user_notes/browser/user_note_service.cc
+++ b/components/user_notes/browser/user_note_service.cc
@@ -5,7 +5,7 @@
 #include "components/user_notes/browser/user_note_service.h"
 
 #include "base/notreached.h"
-#include "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/user_notes_features.h"
 #include "content/public/browser/render_frame_host.h"
 
@@ -37,13 +37,13 @@
     return;
   }
 
-  DCHECK(UserNotesManager::GetForPage(rfh->GetPage()));
+  DCHECK(UserNoteManager::GetForPage(rfh->GetPage()));
   NOTIMPLEMENTED();
 }
 
 void UserNoteService::OnNoteInstanceAddedToPage(
     const base::UnguessableToken& id,
-    UserNotesManager* manager) {
+    UserNoteManager* manager) {
   DCHECK(IsUserNotesEnabled());
   const auto& entry_it = model_map_.find(id);
   DCHECK(entry_it != model_map_.end())
@@ -54,7 +54,7 @@
 
 void UserNoteService::OnNoteInstanceRemovedFromPage(
     const base::UnguessableToken& id,
-    UserNotesManager* manager) {
+    UserNoteManager* manager) {
   DCHECK(IsUserNotesEnabled());
 
   const auto& entry_it = model_map_.find(id);
diff --git a/components/user_notes/browser/user_note_service.h b/components/user_notes/browser/user_note_service.h
index 1859eedb..9a8cda8 100644
--- a/components/user_notes/browser/user_note_service.h
+++ b/components/user_notes/browser/user_note_service.h
@@ -26,7 +26,7 @@
 
 namespace user_notes {
 
-class UserNotesManager;
+class UserNoteManager;
 
 // Keyed service coordinating the different parts (Renderer, UI layer, storage
 // layer) of the User Notes feature for the current user profile.
@@ -44,18 +44,18 @@
   // off the logic to display them in the page.
   virtual void OnFrameNavigated(content::RenderFrameHost* rfh);
 
-  // Called by |UserNotesManager| objects when a |UserNoteInstance| is added to
+  // Called by `UserNoteManager` objects when a `UserNoteInstance` is added to
   // the page they're attached to. Updates the model map to add a ref to the
-  // given |UserNotesManager| for the note with the specified ID.
+  // given `UserNoteManager` for the note with the specified ID.
   void OnNoteInstanceAddedToPage(const base::UnguessableToken& id,
-                                 UserNotesManager* manager);
+                                 UserNoteManager* manager);
 
-  // Same as |OnNoteInstanceAddedToPage|, except for when a note is removed from
+  // Same as `OnNoteInstanceAddedToPage`, except for when a note is removed from
   // a page. Updates the model map to remove the ref to the given
-  // |UserNotesManager|. If this is the last page where the note was displayed,
+  // `UserNoteManager`. If this is the last page where the note was displayed,
   // also deletes the model from the model map.
   void OnNoteInstanceRemovedFromPage(const base::UnguessableToken& id,
-                                     UserNotesManager* manager);
+                                     UserNoteManager* manager);
 
   // UserNotesUIDelegate implementation.
   void OnNoteFocused(const base::UnguessableToken& id) override;
@@ -72,16 +72,16 @@
     ModelMapEntry& operator=(const ModelMapEntry&) = delete;
 
     std::unique_ptr<UserNote> model;
-    std::unordered_set<UserNotesManager*> managers;
+    std::unordered_set<UserNoteManager*> managers;
   };
 
   friend class UserNoteServiceTest;
   friend class UserNoteUtilsTest;
-  friend class UserNotesManagerTest;
+  friend class UserNoteManagerTest;
 
   // Source of truth for the in-memory note models. Any note currently being
   // displayed in a tab is stored in this data structure. Each entry also
-  // contains a set of pointers to all |UserNotesManager| objects holding an
+  // contains a set of pointers to all `UserNoteManager` objects holding an
   // instance of that note, which is necessary to clean up the models when
   // they're no longer in use and to remove notes from affected web pages when
   // they're deleted by the user.
diff --git a/components/user_notes/browser/user_note_service_unittest.cc b/components/user_notes/browser/user_note_service_unittest.cc
index d1f90ce5..243ffe54 100644
--- a/components/user_notes/browser/user_note_service_unittest.cc
+++ b/components/user_notes/browser/user_note_service_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/test/scoped_feature_list.h"
-#include "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/model/user_note_model_test_utils.h"
 #include "components/user_notes/user_notes_features.h"
 #include "content/public/browser/page.h"
@@ -84,9 +84,9 @@
 
   // Simulate note instances being created in managers.
   auto m1 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   auto m2 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[0], m1.get());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[0], m2.get());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[1], m1.get());
@@ -99,9 +99,9 @@
 TEST_F(UserNoteServiceTest, RemoveNoteIntancesFromModelMap) {
   // Initial setup.
   auto m1 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   auto m2 =
-      UserNotesManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
+      UserNoteManager::CreateForTest(NullPage(), note_service_->GetSafeRef());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[0], m1.get());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[0], m2.get());
   note_service_->OnNoteInstanceAddedToPage(note_ids_[1], m1.get());
diff --git a/components/user_notes/browser/user_note_utils.cc b/components/user_notes/browser/user_note_utils.cc
index e86d27b..ce77fc9 100644
--- a/components/user_notes/browser/user_note_utils.cc
+++ b/components/user_notes/browser/user_note_utils.cc
@@ -6,7 +6,7 @@
 
 #include "base/unguessable_token.h"
 #include "components/user_notes/browser/frame_user_note_changes.h"
-#include "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/interfaces/user_note_metadata_snapshot.h"
 #include "components/user_notes/model/user_note_metadata.h"
 #include "content/public/browser/render_frame_host.h"
@@ -27,8 +27,8 @@
     // Notes should only be processed for the primary page.
     DCHECK(rfh->GetMainFrame()->IsInPrimaryMainFrame());
 
-    UserNotesManager* notes_manager =
-        UserNotesManager::GetForPage(rfh->GetPage());
+    UserNoteManager* notes_manager =
+        UserNoteManager::GetForPage(rfh->GetPage());
 
     if (!notes_manager) {
       // Frame is part of an uninteresting page (for User Notes purposes), such
diff --git a/components/user_notes/browser/user_note_utils_unittest.cc b/components/user_notes/browser/user_note_utils_unittest.cc
index 8221244..2116a83 100644
--- a/components/user_notes/browser/user_note_utils_unittest.cc
+++ b/components/user_notes/browser/user_note_utils_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/time/time.h"
 #include "base/unguessable_token.h"
 #include "components/user_notes/browser/frame_user_note_changes.h"
-#include "components/user_notes/browser/user_notes_manager.h"
+#include "components/user_notes/browser/user_note_manager.h"
 #include "components/user_notes/interfaces/user_note_metadata_snapshot.h"
 #include "components/user_notes/model/user_note_model_test_utils.h"
 #include "components/user_notes/user_notes_features.h"
@@ -241,12 +241,12 @@
 
   void TearDown() override {
     // Owned web contentses must be destroyed before the test harness. Before
-    // doing that, however, clear the instance map of all `UserNotesManager`
+    // doing that, however, clear the instance map of all `UserNoteManager`
     // objects to avoid clean-up issues where the managers attempt to remove
     // themselves from the `UserNoteService`, which won't work because the test
     // setup does not add the manager refs in the service.
     for (const auto& wc : web_contents_list_) {
-      UserNotesManager::GetForPage(wc->GetPrimaryPage())->instance_map_.clear();
+      UserNoteManager::GetForPage(wc->GetPrimaryPage())->instance_map_.clear();
     }
     web_contents_list_.clear();
     content::RenderViewHostTestHarness::TearDown();
@@ -290,10 +290,10 @@
     content::NavigationSimulator::NavigateAndCommitFromBrowser(
         wc.get(), GURL(frame_config.url));
 
-    // Create and attach a `UserNotesManager` to the primary page.
+    // Create and attach a `UserNoteManager` to the primary page.
     content::Page& page = wc->GetPrimaryPage();
-    UserNotesManager::CreateForPage(page, note_service_->GetSafeRef());
-    UserNotesManager* note_manager = UserNotesManager::GetForPage(page);
+    UserNoteManager::CreateForPage(page, note_service_->GetSafeRef());
+    UserNoteManager* note_manager = UserNoteManager::GetForPage(page);
     DCHECK(note_manager);
 
     // Attach all notes that have a target URL corresponding to this frame's
diff --git a/components/user_prefs/android/BUILD.gn b/components/user_prefs/android/BUILD.gn
index 78db0e5..e99244ca 100644
--- a/components/user_prefs/android/BUILD.gn
+++ b/components/user_prefs/android/BUILD.gn
@@ -11,7 +11,6 @@
 android_library("java") {
   sources = [ "java/src/org/chromium/components/user_prefs/UserPrefs.java" ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/prefs/android:java",
diff --git a/components/version_info/android/BUILD.gn b/components/version_info/android/BUILD.gn
index af1d7c43..9072c520 100644
--- a/components/version_info/android/BUILD.gn
+++ b/components/version_info/android/BUILD.gn
@@ -18,7 +18,6 @@
   ]
   deps = [
     ":generate_version_constants",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index ae52263..77d982f 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -399,18 +399,6 @@
     "yuv_readback_unittest.cc",
   ]
 
-  if (enable_gl_renderer_tests) {
-    sources += [
-      "gl_i420_converter_pixeltest.cc",
-      "gl_i420_converter_unittest.cc",
-      "gl_nv12_converter_pixeltest.cc",
-      "gl_scaler_overscan_pixeltest.cc",
-      "gl_scaler_pixeltest.cc",
-      "gl_scaler_shader_pixeltest.cc",
-      "gl_scaler_unittest.cc",
-    ]
-  }
-
   if (enable_vulkan) {
     sources += [ "gpu/vulkan_in_process_context_provider_unittest.cc" ]
   }
diff --git a/components/viz/common/gl_i420_converter_pixeltest.cc b/components/viz/common/gl_i420_converter_pixeltest.cc
deleted file mode 100644
index 1cf61bb..0000000
--- a/components/viz/common/gl_i420_converter_pixeltest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_i420_converter.h"
-
-#include <GLES2/gl2ext.h>
-
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace viz {
-
-class GLI420ConverterPixelTest : public cc::PixelTest,
-                                 public GLScalerTestUtil,
-                                 public testing::WithParamInterface<bool> {
- public:
-  bool allow_mrt_path() const { return GetParam(); }
-  GLI420Converter* converter() const { return converter_.get(); }
-
-  GLuint CreateTexture(const gfx::Size& size) {
-    return texture_helper_->CreateTexture(size);
-  }
-
-  GLuint UploadTexture(const SkBitmap& bitmap) {
-    return texture_helper_->UploadTexture(bitmap);
-  }
-
-  SkBitmap DownloadTexture(GLuint texture, const gfx::Size& size) {
-    return texture_helper_->DownloadTexture(texture, size);
-  }
-
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-    converter_.reset(new GLI420Converter(context_provider(), allow_mrt_path()));
-    texture_helper_ = std::make_unique<GLScalerTestTextureHelper>(
-        context_provider()->ContextGL());
-  }
-
-  void TearDown() final {
-    texture_helper_.reset();
-    converter_.reset();
-    cc::PixelTest::TearDown();
-  }
-
- private:
-  std::unique_ptr<GLI420Converter> converter_;
-  std::unique_ptr<GLScalerTestTextureHelper> texture_helper_;
-};
-
-// Note: This test is pretty much the same as
-// GLScalerPixelTest.Example_ScaleAndExportForScreenVideoCapture. The goal of
-// this pixel test is to just confirm that everything internal to
-// GLI420Converter has been plumbed-through correctly.
-TEST_P(GLI420ConverterPixelTest, ScaleAndConvert) {
-  // These parameters have been chosen based on: 1) overriding defaults, to
-  // confirm Parameters plumbing; and 2) typical operation on most platforms
-  // (e.g., flipped source textures, the need to swizzle outputs, etc.).
-  GLI420Converter::Parameters params;
-  params.scale_from = gfx::Vector2d(2160, 1440);
-  params.scale_to = gfx::Vector2d(1280, 720);
-  params.source_color_space = DefaultRGBColorSpace();
-  params.output_color_space = DefaultYUVColorSpace();
-  params.enable_precise_color_management =
-      converter()->SupportsPreciseColorManagement();
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = true;
-  params.flip_output = true;
-  params.swizzle[0] = GL_BGRA_EXT;  // Swizzle for readback.
-  ASSERT_TRUE(converter()->Configure(params));
-
-  constexpr gfx::Size kSourceSize = gfx::Size(2160, 1440);
-  const GLuint src_texture = UploadTexture(
-      CreateVerticallyFlippedBitmap(CreateSMPTETestImage(kSourceSize)));
-  constexpr gfx::Rect kOutputRect = gfx::Rect(0, 0, 1280, 720);
-  ASSERT_EQ(kOutputRect, GLI420Converter::ToAlignedRect(kOutputRect));
-  SkBitmap expected = CreateSMPTETestImage(kOutputRect.size());
-  ConvertRGBABitmapToYUV(&expected);
-
-  // While the output size is 1280x720, the packing of 4 pixels into one RGBA
-  // quad means that the texture width must be divided by 4 (for the Y
-  // plane). Then, the other two planes are half the size of the Y plane in both
-  // dimensions.
-  const gfx::Size y_plane_size(kOutputRect.width() / 4, kOutputRect.height());
-  const gfx::Size chroma_plane_size(y_plane_size.width() / 2,
-                                    y_plane_size.height() / 2);
-  const GLuint yuv_textures[3] = {CreateTexture(y_plane_size),
-                                  CreateTexture(chroma_plane_size),
-                                  CreateTexture(chroma_plane_size)};
-
-  ASSERT_TRUE(converter()->Convert(src_texture, kSourceSize, gfx::Vector2d(),
-                                   kOutputRect, yuv_textures));
-
-  // Download the textures, and unpack them into an interleaved YUV bitmap, for
-  // comparison against the |expected| rendition.
-  SkBitmap actual = AllocateRGBABitmap(kOutputRect.size());
-  actual.eraseColor(SkColorSetARGB(0xff, 0x00, 0x80, 0x80));
-  SkBitmap y_plane = DownloadTexture(yuv_textures[0], y_plane_size);
-  SwizzleBitmap(&y_plane);
-  UnpackPlanarBitmap(y_plane, 0, &actual);
-  SkBitmap u_plane = DownloadTexture(yuv_textures[1], chroma_plane_size);
-  SwizzleBitmap(&u_plane);
-  UnpackPlanarBitmap(u_plane, 1, &actual);
-  SkBitmap v_plane = DownloadTexture(yuv_textures[2], chroma_plane_size);
-  SwizzleBitmap(&v_plane);
-  UnpackPlanarBitmap(v_plane, 2, &actual);
-
-  // Provide generous error limits to account for the chroma subsampling in the
-  // |actual| result when compared to the perfect |expected| rendition.
-  constexpr float kAvgAbsoluteErrorLimit = 16.f;
-  constexpr int kMaxAbsoluteErrorLimit = 0x80;
-  EXPECT_TRUE(cc::FuzzyPixelComparator(false, 100.f, 0.f,
-                                       kAvgAbsoluteErrorLimit,
-                                       kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected, actual))
-      << "\nActual: " << cc::GetPNGDataUrl(actual)
-      << "\nExpected: " << cc::GetPNGDataUrl(expected);
-}
-
-// Run the tests twice, once disallowing use of the MRT path, and once allowing
-// its use (auto-detecting whether the current platform supports it).
-INSTANTIATE_TEST_SUITE_P(All, GLI420ConverterPixelTest, testing::Bool());
-
-}  // namespace viz
diff --git a/components/viz/common/gl_i420_converter_unittest.cc b/components/viz/common/gl_i420_converter_unittest.cc
deleted file mode 100644
index 9fd42188..0000000
--- a/components/viz/common/gl_i420_converter_unittest.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_i420_converter.h"
-
-#include <string>
-
-#include "base/strings/stringprintf.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace viz {
-namespace {
-
-// Syntactic convenience: It's clearer to express the tests in terms of
-// left+top+right+bottom coordinates, rather than gfx::Rect's x+y+width+height
-// scheme.
-SkIRect ToAlignedRect(const SkIRect& rect) {
-  const gfx::Rect& result = GLI420Converter::ToAlignedRect(
-      gfx::Rect(rect.fLeft, rect.fTop, rect.fRight - rect.fLeft,
-                rect.fBottom - rect.fTop));
-  return SkIRect{result.x(), result.y(), result.right(), result.bottom()};
-}
-
-// Logging convenience.
-std::string ToString(const SkIRect& rect) {
-  return base::StringPrintf("%d,%d~%d%d", rect.fLeft, rect.fTop, rect.fRight,
-                            rect.fBottom);
-}
-
-TEST(GLI420ConverterTest, AlignsOutputRects) {
-  struct {
-    SkIRect expected;
-    SkIRect input;
-  } kTestCases[] = {
-      {SkIRect{0, 0, 0, 0}, SkIRect{0, 0, 0, 0}},
-
-      {SkIRect{-16, 0, 16, 4}, SkIRect{-9, 0, 16, 4}},
-      {SkIRect{-8, 0, 16, 4}, SkIRect{-8, 0, 16, 4}},
-      {SkIRect{-8, 0, 16, 4}, SkIRect{-7, 0, 16, 4}},
-      {SkIRect{-8, 0, 16, 4}, SkIRect{-1, 0, 16, 4}},
-      {SkIRect{0, 0, 16, 4}, SkIRect{0, 0, 16, 4}},
-      {SkIRect{0, 0, 16, 4}, SkIRect{1, 0, 16, 4}},
-      {SkIRect{0, 0, 16, 4}, SkIRect{7, 0, 16, 4}},
-      {SkIRect{8, 0, 16, 4}, SkIRect{8, 0, 16, 4}},
-      {SkIRect{8, 0, 16, 4}, SkIRect{9, 0, 16, 4}},
-
-      {SkIRect{0, -4, 16, 4}, SkIRect{0, -3, 16, 4}},
-      {SkIRect{0, -2, 16, 4}, SkIRect{0, -2, 16, 4}},
-      {SkIRect{0, -2, 16, 4}, SkIRect{0, -1, 16, 4}},
-      {SkIRect{0, 0, 16, 4}, SkIRect{0, 0, 16, 4}},
-      {SkIRect{0, 0, 16, 4}, SkIRect{0, 1, 16, 4}},
-      {SkIRect{0, 2, 16, 4}, SkIRect{0, 2, 16, 4}},
-      {SkIRect{0, 2, 16, 4}, SkIRect{0, 3, 16, 4}},
-
-      {SkIRect{0, 0, 8, 2}, SkIRect{0, 0, 1, 2}},
-      {SkIRect{0, 0, 8, 2}, SkIRect{0, 0, 7, 2}},
-      {SkIRect{0, 0, 8, 2}, SkIRect{0, 0, 8, 2}},
-      {SkIRect{0, 0, 16, 2}, SkIRect{0, 0, 9, 2}},
-
-      {SkIRect{0, 0, 8, 2}, SkIRect{0, 0, 8, 1}},
-      {SkIRect{0, 0, 8, 2}, SkIRect{0, 0, 8, 2}},
-      {SkIRect{0, 0, 8, 4}, SkIRect{0, 0, 8, 3}},
-      {SkIRect{0, 0, 8, 4}, SkIRect{0, 0, 8, 4}},
-  };
-
-  for (const auto& test_case : kTestCases) {
-    EXPECT_EQ(test_case.expected, ToAlignedRect(test_case.input))
-        << "ToAlignedRect(" << ToString(test_case.input) << ") should be "
-        << ToString(test_case.expected);
-  }
-}
-
-}  // namespace
-}  // namespace viz
diff --git a/components/viz/common/gl_nv12_converter_pixeltest.cc b/components/viz/common/gl_nv12_converter_pixeltest.cc
deleted file mode 100644
index ad3ec480..0000000
--- a/components/viz/common/gl_nv12_converter_pixeltest.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_nv12_converter.h"
-
-#include <GLES2/gl2ext.h>
-
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace viz {
-
-class GLNV12ConverterPixelTest
-    : public cc::PixelTest,
-      public GLScalerTestUtil,
-      public testing::WithParamInterface<
-          std::tuple<bool, bool, gfx::Vector2d, gfx::Vector2d>> {
- public:
-  bool allow_mrt_path() const { return std::get<0>(GetParam()); }
-  bool is_rgba() const { return std::get<1>(GetParam()); }
-  gfx::Vector2d scale_from() const { return std::get<2>(GetParam()); }
-  gfx::Vector2d scale_to() const { return std::get<3>(GetParam()); }
-
-  GLNV12Converter* converter() const { return converter_.get(); }
-
-  GLuint CreateTexture(const gfx::Size& size) {
-    return texture_helper_->CreateTexture(size);
-  }
-
-  GLuint UploadTexture(const SkBitmap& bitmap) {
-    return texture_helper_->UploadTexture(bitmap);
-  }
-
-  SkBitmap DownloadTexture(GLuint texture, const gfx::Size& size) {
-    return texture_helper_->DownloadTexture(texture, size);
-  }
-
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-    converter_ = GLNV12Converter::CreateConverterForTest(context_provider(),
-                                                         allow_mrt_path());
-    texture_helper_ = std::make_unique<GLScalerTestTextureHelper>(
-        context_provider()->ContextGL());
-  }
-
-  void TearDown() final {
-    texture_helper_.reset();
-    converter_.reset();
-    cc::PixelTest::TearDown();
-  }
-
- private:
-  std::unique_ptr<GLNV12Converter> converter_;
-  std::unique_ptr<GLScalerTestTextureHelper> texture_helper_;
-};
-
-// Note: This test is pretty much the same as
-// GLScalerPixelTest.Example_ScaleAndExportForScreenVideoCapture. The goal of
-// this pixel test is to just confirm that everything internal to
-// GLNV12Converter has been plumbed-through correctly.
-TEST_P(GLNV12ConverterPixelTest, ScaleAndConvert) {
-  GLNV12Converter::Parameters params;
-  params.scale_from = scale_from();
-  params.scale_to = scale_to();
-  params.source_color_space = DefaultRGBColorSpace();
-  params.output_color_space = DefaultYUVColorSpace();
-  params.enable_precise_color_management =
-      converter()->SupportsPreciseColorManagement();
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = true;
-  params.flip_output = true;
-  params.swizzle[0] =
-      is_rgba() ? GL_RGBA : GL_BGRA_EXT;  // Swizzle for readback.
-  ASSERT_TRUE(converter()->Configure(params));
-
-  const gfx::Size kSourceSize = gfx::Size(scale_from().x(), scale_from().y());
-  const GLuint src_texture = UploadTexture(
-      CreateVerticallyFlippedBitmap(CreateSMPTETestImage(kSourceSize)));
-  const gfx::Rect kOutputRect = gfx::Rect(0, 0, scale_to().x(), scale_to().y());
-  ASSERT_EQ(kOutputRect, GLNV12Converter::ToAlignedRect(kOutputRect));
-  SkBitmap expected = CreateSMPTETestImage(kOutputRect.size());
-  ConvertRGBABitmapToYUV(&expected);
-
-  // While the output size is `kOutputRect.Size()`, the packing of 4 pixels into
-  // one RGBA quad means that the texture width must be divided by 4 (for the Y
-  // plane). Then, the chroma plane is half the size of the Y plane in both
-  // dimensions, but the width is actually double that since we pack 2 values,
-  // so `y_plane_size.width() * 1/2 * 2` term is simplified to just
-  // `y_plane_size.width()`.
-  const gfx::Size y_plane_size(kOutputRect.width() / 4, kOutputRect.height());
-  const gfx::Size chroma_plane_size(y_plane_size.width(),
-                                    y_plane_size.height() / 2);
-
-  const GLuint yuv_textures[2] = {CreateTexture(y_plane_size),
-                                  CreateTexture(chroma_plane_size)};
-
-  ASSERT_TRUE(converter()->Convert(src_texture, kSourceSize, gfx::Vector2d(),
-                                   kOutputRect, yuv_textures));
-
-  // Download the textures, and unpack them into an interleaved YUV bitmap, for
-  // comparison against the |expected| rendition.
-  SkBitmap actual = AllocateRGBABitmap(kOutputRect.size());
-  actual.eraseColor(SkColorSetARGB(0xff, 0x00, 0x00, 0x00));
-
-  SkBitmap y_plane = DownloadTexture(yuv_textures[0], y_plane_size);
-  SkBitmap uv_plane = DownloadTexture(yuv_textures[1], chroma_plane_size);
-
-  if (!is_rgba()) {
-    // We've asked the converter to produce output in BGRA, & downloaded it to
-    // RGBA SkBitmap, so swizzle it.
-    SwizzleBitmap(&y_plane);
-    SwizzleBitmap(&uv_plane);
-  }
-
-  UnpackPlanarBitmap(y_plane, 0, &actual);
-  UnpackUVBitmap(uv_plane, &actual);
-
-  // Provide generous error limits to account for the chroma subsampling in the
-  // |actual| result when compared to the perfect |expected| rendition.
-  constexpr float kAvgAbsoluteErrorLimit = 16.f;
-  constexpr int kMaxAbsoluteErrorLimit = 0x80;
-  EXPECT_TRUE(cc::FuzzyPixelComparator(false, 100.f, 0.f,
-                                       kAvgAbsoluteErrorLimit,
-                                       kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected, actual))
-      << "\nActual: " << cc::GetPNGDataUrl(actual)
-      << "\nExpected: " << cc::GetPNGDataUrl(expected);
-}
-
-// Run the tests, first parameter controls whether the MRT path is allowed,
-// the second controls whether the converter will use RGBA format vs BGRA (true
-// for RGBA, i.e. no swizzling done by the converter, false for BGRA, i.e. the
-// converter will swizzle the results when writing to texture).
-// These parameters have been chosen based on: 1) overriding defaults, to
-// confirm Parameters plumbing; and 2) typical operation on most platforms
-// (e.g., flipped source textures, the need to swizzle outputs, etc.). In
-// addition, the `scale_to()` is made to return width that is divisible by 4,
-// but not by 8, to test alignment requirements.
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    GLNV12ConverterPixelTest,
-    testing::Combine(testing::Bool(),
-                     testing::Bool(),
-                     testing::Values(gfx::Vector2d(2160, 1440)),
-                     testing::Values(gfx::Vector2d(1280, 720),
-                                     gfx::Vector2d(900, 600))));
-
-}  // namespace viz
diff --git a/components/viz/common/gl_scaler_overscan_pixeltest.cc b/components/viz/common/gl_scaler_overscan_pixeltest.cc
deleted file mode 100644
index 30f4810..0000000
--- a/components/viz/common/gl_scaler_overscan_pixeltest.cc
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_scaler.h"
-
-#include "build/build_config.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "gpu/GLES2/gl2chromium.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkRect.h"
-
-namespace viz {
-
-class GLScalerOverscanPixelTest : public cc::PixelTest,
-                                  public GLScalerTestUtil {
- public:
-  using Axis = GLScaler::Axis;
-  using ScalerStage = GLScaler::ScalerStage;
-  using Shader = GLScaler::Shader;
-
-  bool AreMultipleRenderingTargetsSupported() const {
-    return scaler_->GetMaxDrawBuffersSupported() > 1;
-  }
-
-  // Creates a ScalerStage chain consisting of a single stage having the given
-  // configuration.
-  void UseScaler(Shader shader,
-                 Axis primary_axis,
-                 const gfx::Vector2d& scale_from,
-                 const gfx::Vector2d& scale_to) {
-    scaler_->chain_ = std::make_unique<ScalerStage>(gl_, shader, primary_axis,
-                                                    scale_from, scale_to);
-    scaler_->chain_->set_shader_program(scaler_->GetShaderProgram(
-        shader, GL_UNSIGNED_BYTE, nullptr, GLScaler::Parameters().swizzle));
-  }
-
-  // Converts the given |source_rect| into a possibly-larger one that includes
-  // all of the pixels that would be sampled by the current scaler (i.e.,
-  // including overscan). This uses the math of the internal implementation to
-  // compute the values.
-  gfx::Rect ToInputRect(gfx::Rect source_rect) {
-    CHECK(scaler_ && scaler_->chain_);
-    return scaler_->chain_->ToInputRect(gfx::RectF(source_rect));
-  }
-
-  // Renders images using the current scaler to auto-detect its overscan. This
-  // does NOT use the internal implementation to compute the values, but instead
-  // discovers them experimentally. This is used to confirm that: a) the scaler
-  // behaves as ToInputRect() expects; and b) the math internal to ToInputRect()
-  // is correct.
-  //
-  // The general approach is to upload a source image containing a blue box in
-  // the center, surrounded by a red background. The size of the blue box is
-  // varied: It starts out at a size encompassing more than all of the pixels to
-  // be sampled by the scaler, and is gradually shrunk until the scaler's output
-  // begins to include red "bleed-in." At that point, the overscan amount is
-  // confirmed experimentally.
-  gfx::Vector2d DetectScalerOverscan(const gfx::Vector2d& scale_from,
-                                     const gfx::Vector2d& scale_to) {
-    // Assume a source size three times the "scale from" width and height. This
-    // allows for scaling the middle third of a source image, to test possible
-    // bleed-in on all sides of the output.
-    const gfx::Size src_size(scale_from.x() * 3, scale_from.y() * 3);
-
-    // The requested output rect is the center third of the image, in the
-    // destination coordinate space.
-    const gfx::Rect dst_rect(
-        src_size.width() / 3 * scale_to.x() / scale_from.x(),
-        src_size.height() / 3 * scale_to.y() / scale_from.y(),
-        src_size.width() / 3 * scale_to.x() / scale_from.x(),
-        src_size.height() / 3 * scale_to.y() / scale_from.y());
-    const GLuint dst_texture = texture_helper_->CreateTexture(dst_rect.size());
-
-    // This is our "basis for comparison" image. If scaled output images match
-    // this, then there is no bleed-in.
-    SkBitmap output_without_bleed_in;
-    {
-      const bool did_scale =
-          scaler_->Scale(texture_helper_->UploadTexture(CreateBlueBoxOnRedImage(
-                             src_size, gfx::Rect(src_size))),
-                         src_size, gfx::Vector2d(0, 0), dst_texture, dst_rect);
-      CHECK(did_scale);
-      output_without_bleed_in =
-          texture_helper_->DownloadTexture(dst_texture, dst_rect.size());
-      VLOG(2) << scale_from.ToString() << "→" << scale_to.ToString()
-              << ": Output without bleed-in is "
-              << cc::GetPNGDataUrl(output_without_bleed_in);
-    }
-
-    // Perform a linear search for the minimal overscan values that do not cause
-    // the red bleed-in in the scaled output image. There are actually two
-    // separate searches here, one horizontally and one vertically. Note that an
-    // overscan result of -1 indicates a failed search and/or a broken
-    // implementation.
-    gfx::Vector2d min_overscan(5, 5);
-    for (int is_horizontal = 1; is_horizontal >= 0; --is_horizontal) {
-      while (min_overscan.x() >= 0 && min_overscan.y() >= 0) {
-        // Decrease the overscan by one pixel (one dimension at a time).
-        const gfx::Vector2d overscan(
-            is_horizontal ? (min_overscan.x() - 1) : min_overscan.x(),
-            is_horizontal ? min_overscan.y() : (min_overscan.y() - 1));
-
-        // Create the source texture consisting of a centered blue box
-        // surrounded by red.
-        const gfx::Rect blue_rect(scale_from.x() - overscan.x(),
-                                  scale_from.y() - overscan.y(),
-                                  scale_from.x() + 2 * overscan.x(),
-                                  scale_from.y() + 2 * overscan.y());
-        const SkBitmap source_image =
-            CreateBlueBoxOnRedImage(src_size, blue_rect);
-        const bool did_scale = scaler_->Scale(
-            texture_helper_->UploadTexture(source_image), src_size,
-            gfx::Vector2d(0, 0), dst_texture, dst_rect);
-        CHECK(did_scale);
-        const SkBitmap output =
-            texture_helper_->DownloadTexture(dst_texture, dst_rect.size());
-
-        // Compare |output| with |output_without_bleed_in|. If they are
-        // different, then the blue rect became too small.
-        bool output_has_bleed_in = false;
-        for (int y = 0; y < output.height(); ++y) {
-          for (int x = 0; x < output.width(); ++x) {
-            if (output.getColor(x, y) !=
-                output_without_bleed_in.getColor(x, y)) {
-              output_has_bleed_in = true;
-              break;
-            }
-          }
-        }
-
-        VLOG(2) << scale_from.ToString() << "→" << scale_to.ToString()
-                << ": Testing overscan=" << overscan.ToString() << std::endl
-                << "\tSource image is " << cc::GetPNGDataUrl(source_image)
-                << std::endl
-                << "\tOutput image is " << cc::GetPNGDataUrl(output);
-
-        if (output_has_bleed_in) {
-          break;  // Search complete: Red bleed-in detected.
-        }
-
-        min_overscan = overscan;
-      }
-    }
-
-    return min_overscan;
-  }
-
-  static SkBitmap CreateBlueBoxOnRedImage(const gfx::Size& size,
-                                          const gfx::Rect& blue_rect) {
-    SkBitmap result = AllocateRGBABitmap(size);
-    // Note: None of the color channel values should be close to 0 or 255. This
-    // is because the bicubic scaler will generate values that overshoot and
-    // clip, and this will mess-up detection of the number of overscan pixels.
-    result.eraseColor(SkColorSetRGB(0xc0, 0x40, 0x40));
-    result.erase(SkColorSetRGB(0x40, 0x40, 0xc0),
-                 SkIRect{blue_rect.x(), blue_rect.y(), blue_rect.right(),
-                         blue_rect.bottom()});
-    return result;
-  }
-
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-
-    scaler_ = std::make_unique<GLScaler>(context_provider());
-    gl_ = context_provider()->ContextGL();
-    CHECK(gl_);
-    texture_helper_ = std::make_unique<GLScalerTestTextureHelper>(gl_);
-  }
-
-  void TearDown() final {
-    texture_helper_.reset();
-    gl_ = nullptr;
-    scaler_.reset();
-
-    cc::PixelTest::TearDown();
-  }
-
-  std::unique_ptr<GLScaler> scaler_;
-  gpu::gles2::GLES2Interface* gl_ = nullptr;
-  std::unique_ptr<GLScalerTestTextureHelper> texture_helper_;
-};
-
-namespace {
-constexpr gfx::Rect kTenByTenRect = gfx::Rect(10, 10, 10, 10);
-}  // namespace
-
-TEST_F(GLScalerOverscanPixelTest, Bilinear) {
-  constexpr struct {
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // No scaling.
-      {gfx::Vector2d(32, 20), gfx::Vector2d(32, 20), gfx::Vector2d(0, 0)},
-
-      // Scale by 0.5X.
-      {gfx::Vector2d(32, 20), gfx::Vector2d(16, 20), gfx::Vector2d(0, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(32, 10), gfx::Vector2d(0, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(16, 10), gfx::Vector2d(0, 0)},
-
-      // Scale by 0.75X.
-      {gfx::Vector2d(32, 20), gfx::Vector2d(24, 20), gfx::Vector2d(0, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(32, 15), gfx::Vector2d(0, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(24, 15), gfx::Vector2d(0, 0)},
-
-      // Scale by 1.5X.
-      {gfx::Vector2d(32, 20), gfx::Vector2d(48, 20), gfx::Vector2d(1, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(32, 30), gfx::Vector2d(0, 1)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(48, 30), gfx::Vector2d(1, 1)},
-
-      // Scale by 4X.
-      {gfx::Vector2d(32, 20), gfx::Vector2d(128, 20), gfx::Vector2d(1, 0)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(32, 80), gfx::Vector2d(0, 1)},
-      {gfx::Vector2d(32, 20), gfx::Vector2d(128, 80), gfx::Vector2d(1, 1)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BILINEAR, Axis::HORIZONTAL, tc.scale_from, tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, TwoTapBilinear) {
-  constexpr struct {
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // Scale by 0.25X in one direction only.
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(16, 40),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(64, 10),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.25X in one direction, 0.5X in the other.
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(16, 20),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(32, 10),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.75X (1.5X * 0.5X).
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(48, 40),
-       gfx::Vector2d(1, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(64, 30),
-       gfx::Vector2d(0, 1)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BILINEAR2, tc.primary_axis, tc.scale_from, tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, ThreeTapBilinear) {
-  constexpr struct {
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // Scale by 0.16...X in one direction only.
-      {Axis::HORIZONTAL, gfx::Vector2d(66, 40), gfx::Vector2d(11, 40),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(32, 60), gfx::Vector2d(32, 10),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.16...X in one direction, 0.5X in the other.
-      {Axis::HORIZONTAL, gfx::Vector2d(66, 40), gfx::Vector2d(11, 20),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 60), gfx::Vector2d(32, 10),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.75X (3.0X * 0.5X * 0.5X).
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(48, 40),
-       gfx::Vector2d(1, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(64, 30),
-       gfx::Vector2d(0, 1)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BILINEAR3, tc.primary_axis, tc.scale_from, tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, FourTapBilinear) {
-  constexpr struct {
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // Scale by 0.125X in one direction only.
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(8, 40),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(64, 5),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.125X in one direction, 0.5X in the other.
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(8, 20),
-       gfx::Vector2d(0, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(32, 5),
-       gfx::Vector2d(0, 0)},
-
-      // Scale by 0.75X (6.0X * 0.5X * 0.5X * 0.5X).
-      {Axis::HORIZONTAL, gfx::Vector2d(64, 40), gfx::Vector2d(48, 40),
-       gfx::Vector2d(1, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(64, 40), gfx::Vector2d(64, 30),
-       gfx::Vector2d(0, 1)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BILINEAR4, tc.primary_axis, tc.scale_from, tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, TwoByTwoTapBilinear) {
-  constexpr struct {
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // Scale by 0.25X in both directions.
-      {gfx::Vector2d(64, 40), gfx::Vector2d(16, 10), gfx::Vector2d(0, 0)},
-
-      // Scale by 0.75X (1.5X * 0.5X) in one direction, 0.25X in the other.
-      {gfx::Vector2d(64, 40), gfx::Vector2d(48, 10), gfx::Vector2d(1, 0)},
-      {gfx::Vector2d(64, 40), gfx::Vector2d(16, 30), gfx::Vector2d(0, 1)},
-
-      // Scale by 0.75X (1.5X * 0.5X) in both directions.
-      {gfx::Vector2d(64, 40), gfx::Vector2d(48, 30), gfx::Vector2d(1, 1)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BILINEAR2X2, Axis::HORIZONTAL, tc.scale_from,
-              tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, BicubicUpscale) {
-#if BUILDFLAG(IS_ANDROID)
-  // Unfortunately, on our current Android bots, there are some inaccuracies
-  // introduced by the platform that seem to throw-off the pixel testing of the
-  // bicubic sampler.
-  constexpr bool kSkipDetectionTest = true;
-  LOG(WARNING) << "Skipping overscan detection due to platform issues.";
-#else
-  constexpr bool kSkipDetectionTest = false;
-#endif
-
-  constexpr struct {
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      // Scale by 1.5X, 2X, and 3.3...X horizontally.
-      {Axis::HORIZONTAL, gfx::Vector2d(12, 10), gfx::Vector2d(18, 10),
-       gfx::Vector2d(2, 0)},
-      {Axis::HORIZONTAL, gfx::Vector2d(12, 10), gfx::Vector2d(24, 10),
-       gfx::Vector2d(2, 0)},
-      {Axis::HORIZONTAL, gfx::Vector2d(12, 10), gfx::Vector2d(40, 10),
-       gfx::Vector2d(2, 0)},
-
-      // Scale by 1.5X, 2X, and 3.3...X vertically.
-      {Axis::VERTICAL, gfx::Vector2d(12, 10), gfx::Vector2d(12, 15),
-       gfx::Vector2d(0, 2)},
-      {Axis::VERTICAL, gfx::Vector2d(12, 10), gfx::Vector2d(12, 20),
-       gfx::Vector2d(0, 2)},
-      {Axis::VERTICAL, gfx::Vector2d(12, 9), gfx::Vector2d(12, 30),
-       gfx::Vector2d(0, 2)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BICUBIC_UPSCALE, tc.primary_axis, tc.scale_from,
-              tc.scale_to);
-    if (!kSkipDetectionTest) {
-      EXPECT_EQ(tc.expected_overscan,
-                DetectScalerOverscan(tc.scale_from, tc.scale_to));
-    }
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, BicubicHalving) {
-  constexpr struct {
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-    gfx::Vector2d expected_overscan;
-  } kTestCases[] = {
-      {Axis::HORIZONTAL, gfx::Vector2d(16, 16), gfx::Vector2d(8, 16),
-       gfx::Vector2d(3, 0)},
-      {Axis::VERTICAL, gfx::Vector2d(16, 16), gfx::Vector2d(16, 8),
-       gfx::Vector2d(0, 3)},
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message() << "scale_from=" << tc.scale_from.ToString()
-                                    << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(Shader::BICUBIC_HALF_1D, tc.primary_axis, tc.scale_from,
-              tc.scale_to);
-    EXPECT_EQ(tc.expected_overscan,
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    gfx::Rect expected_input_rect = kTenByTenRect;
-    expected_input_rect.Inset(
-        gfx::Insets::VH(-tc.expected_overscan.y(), -tc.expected_overscan.x()));
-    EXPECT_EQ(expected_input_rect, ToInputRect(kTenByTenRect));
-  }
-}
-
-TEST_F(GLScalerOverscanPixelTest, Planerizers) {
-  if (!AreMultipleRenderingTargetsSupported()) {
-    LOG(WARNING) << "Skipping test due to lack of MRT support on this machine.";
-    return;
-  }
-
-  constexpr struct {
-    Shader shader;
-    Axis primary_axis;
-    gfx::Vector2d scale_from;
-    gfx::Vector2d scale_to;
-  } kTestCases[] = {
-      {Shader::PLANAR_CHANNEL_0, Axis::HORIZONTAL, gfx::Vector2d(16, 16),
-       gfx::Vector2d(4, 16)},
-      // Note: Other PLANAR_CHANNEL_N shaders don't need to be tested since they
-      // use the same code path.
-      {Shader::I422_NV61_MRT, Axis::HORIZONTAL, gfx::Vector2d(16, 16),
-       gfx::Vector2d(4, 16)},
-      {
-          Shader::DEINTERLEAVE_PAIRWISE_MRT, Axis::HORIZONTAL,
-          gfx::Vector2d(16, 16), gfx::Vector2d(8, 16),
-      },
-  };
-
-  for (const auto& tc : kTestCases) {
-    SCOPED_TRACE(testing::Message()
-                 << "shader=" << static_cast<int>(tc.shader)
-                 << ", scale_from=" << tc.scale_from.ToString()
-                 << ", scale_to=" << tc.scale_to.ToString());
-
-    // Test the effect on the pixels.
-    UseScaler(tc.shader, tc.primary_axis, tc.scale_from, tc.scale_to);
-    EXPECT_EQ(gfx::Vector2d(0, 0),
-              DetectScalerOverscan(tc.scale_from, tc.scale_to));
-
-    // Sanity-check that the internal math estimating the overscan is correct.
-    EXPECT_EQ(kTenByTenRect, ToInputRect(kTenByTenRect));
-  }
-}
-
-}  // namespace viz
diff --git a/components/viz/common/gl_scaler_pixeltest.cc b/components/viz/common/gl_scaler_pixeltest.cc
deleted file mode 100644
index 9c1df00f..0000000
--- a/components/viz/common/gl_scaler_pixeltest.cc
+++ /dev/null
@@ -1,628 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_scaler.h"
-
-#include <sstream>
-
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/strings/pattern.h"
-#include "build/build_config.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "components/viz/test/paths.h"
-#include "gpu/GLES2/gl2chromium.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/color_space.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/build_info.h"
-#endif
-
-namespace {
-
-// Loads a PNG test image from the test directory, and converts it to GL_RGBA
-// byte order.
-SkBitmap LoadPNGTestImage(const std::string& basename) {
-  base::FilePath test_dir;
-  if (!base::PathService::Get(viz::Paths::DIR_TEST_DATA, &test_dir)) {
-    LOG(FATAL) << "Unable to get Paths::DIR_TEST_DATA from base::PathService.";
-    return SkBitmap();
-  }
-  const auto source_file = test_dir.AppendASCII(basename);
-  SkBitmap as_n32;
-  if (!cc::ReadPNGFile(source_file, &as_n32)) {
-    return SkBitmap();
-  }
-  SkBitmap as_rgba = viz::GLScalerTestUtil::AllocateRGBABitmap(
-      gfx::Size(as_n32.width(), as_n32.height()));
-  if (!as_n32.readPixels(SkPixmap(as_rgba.info(), as_rgba.getAddr(0, 0),
-                                  as_rgba.rowBytes()))) {
-    return SkBitmap();
-  }
-  return as_rgba;
-}
-
-}  // namespace
-
-namespace viz {
-
-#define EXPECT_STRING_MATCHES(expected, actual)                     \
-  if (!base::MatchPattern(actual, expected)) {                      \
-    ADD_FAILURE() << "\nActual: " << (actual)                       \
-                  << "\nExpected to match pattern: " << (expected); \
-  }
-
-class GLScalerPixelTest : public cc::PixelTest, public GLScalerTestUtil {
- public:
-  GLScaler* scaler() const { return scaler_.get(); }
-
-  std::string GetScalerString() const {
-    std::ostringstream oss;
-    oss << *scaler_;
-    return oss.str();
-  }
-
-  GLuint CreateTexture(const gfx::Size& size) {
-    return texture_helper_->CreateTexture(size);
-  }
-
-  GLuint UploadTexture(const SkBitmap& bitmap) {
-    return texture_helper_->UploadTexture(bitmap);
-  }
-
-  SkBitmap DownloadTexture(GLuint texture, const gfx::Size& size) {
-    return texture_helper_->DownloadTexture(texture, size);
-  }
-
-  // Test convenience to upload |src_bitmap| to the GPU, execute the scaling,
-  // then download the result from the GPU and return it as a SkBitmap.
-  SkBitmap Scale(const SkBitmap& src_bitmap,
-                 const gfx::Vector2d& src_offset,
-                 const gfx::Rect& output_rect) {
-    const GLuint src_texture = UploadTexture(src_bitmap);
-    const GLuint dest_texture = CreateTexture(output_rect.size());
-    if (!scaler()->Scale(src_texture,
-                         gfx::Size(src_bitmap.width(), src_bitmap.height()),
-                         src_offset, dest_texture, output_rect)) {
-      return SkBitmap();
-    }
-    return DownloadTexture(dest_texture, output_rect.size());
-  }
-
-  // Returns the amount of color error expected due to bugs in the current
-  // platform's bilinear texture sampler.
-  int GetBaselineColorDifference() const {
-#if BUILDFLAG(IS_ANDROID)
-    // Android seems to have texture sampling problems that are not at all seen
-    // on any of the desktop platforms. Also, versions before Marshmallow seem
-    // to have a much larger accuracy issues.
-    if (base::android::BuildInfo::GetInstance()->sdk_int() <
-        base::android::SDK_VERSION_MARSHMALLOW) {
-      return 12;
-    }
-    return 2;
-#else
-    return 0;
-#endif
-  }
-
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-
-    scaler_ = std::make_unique<GLScaler>(context_provider());
-    gl_ = context_provider()->ContextGL();
-    CHECK(gl_);
-    texture_helper_ = std::make_unique<GLScalerTestTextureHelper>(gl_);
-  }
-
-  bool IsAndroidMarshmallow() {
-#if BUILDFLAG(IS_ANDROID)
-    return base::android::BuildInfo::GetInstance()->sdk_int() ==
-           base::android::SDK_VERSION_MARSHMALLOW;
-#else
-    return false;
-#endif
-  }
-
-  void TearDown() final {
-    texture_helper_.reset();
-    gl_ = nullptr;
-    scaler_.reset();
-
-    cc::PixelTest::TearDown();
-  }
-
- private:
-  std::unique_ptr<GLScaler> scaler_;
-  gpu::gles2::GLES2Interface* gl_ = nullptr;
-  std::unique_ptr<GLScalerTestTextureHelper> texture_helper_;
-};
-
-// Tests that the default GLScaler::Parameters produces an unscaled copy.
-TEST_F(GLScalerPixelTest, CopiesByDefault) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  ASSERT_TRUE(scaler()->Configure(GLScaler::Parameters()));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp copy} ← Source", GetScalerString());
-  const SkBitmap source = CreateSMPTETestImage(kSMPTEFullSize);
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(kSMPTEFullSize));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSMPTEFullSize, gfx::Rect(kSMPTEFullSize), 0, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests a FAST quality scaling of 2→1 in X and 3→2 in Y.
-TEST_F(GLScalerPixelTest, ScalesAtFastQuality) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(2, 3);
-  params.scale_to = gfx::Vector2d(1, 2);
-  params.quality = GLScaler::Parameters::Quality::FAST;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp [2 3] to [1 2]} ← Source",
-            GetScalerString());
-  const SkBitmap source = CreateSMPTETestImage(kSMPTEFullSize);
-  static_assert(kSMPTEFullSize.width() % 2 == 0, "Fix kSMPTEFullSize.");
-  static_assert(kSMPTEFullSize.height() % 3 == 0, "Fix kSMPTEFullSize.");
-  const SkBitmap actual = Scale(source, gfx::Vector2d(),
-                                gfx::Rect(0, 0, kSMPTEFullSize.width() / 2,
-                                          kSMPTEFullSize.height() * 2 / 3));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSMPTEFullSize, gfx::Rect(kSMPTEFullSize), 2, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests a GOOD quality scaling of 1280x720 → 1024x700.
-TEST_F(GLScalerPixelTest, ScalesALittleAtGoodQuality) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(1280, 720);
-  params.scale_to = gfx::Vector2d(1024, 700);
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR2X2/lowp [1280 720] to [1024 700]} ← Source",
-            GetScalerString());
-  constexpr gfx::Size kSourceSize = gfx::Size(1280, 720);
-  const SkBitmap source = CreateSMPTETestImage(kSourceSize);
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(0, 0, 1024, 700));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSourceSize, gfx::Rect(kSourceSize), 2, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests a large, skewed reduction at GOOD quality: 3840x720 → 128x256.
-TEST_F(GLScalerPixelTest, ScalesALotHorizontallyAtGoodQuality) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(3840, 720);
-  params.scale_to = gfx::Vector2d(128, 256);
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(
-      u8"Output "
-      u8"← {BILINEAR/lowp [256 256] to [128 256]} "
-      u8"← {BILINEAR4/lowp [2048 512] to [256 256]} "
-      u8"← {BILINEAR2X2/lowp [3840 720] to [2048 512]} "
-      u8"← Source",
-      GetScalerString());
-  constexpr gfx::Size kSourceSize = gfx::Size(3840, 720);
-  const SkBitmap source = CreateSMPTETestImage(kSourceSize);
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(0, 0, 128, 256));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSourceSize, gfx::Rect(kSourceSize), 2, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests a large, skewed reduction at GOOD quality: 640x2160 → 256x128.
-TEST_F(GLScalerPixelTest, ScalesALotVerticallyAtGoodQuality) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(640, 2160);
-  params.scale_to = gfx::Vector2d(256, 128);
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(
-      u8"Output "
-      u8"← {BILINEAR/lowp [256 256] to [256 128]} "
-      u8"← {BILINEAR4/lowp [512 2048] to [256 256]} "
-      u8"← {BILINEAR2X2/lowp [640 2160] to [512 2048]} "
-      u8"← Source",
-      GetScalerString());
-  constexpr gfx::Size kSourceSize = gfx::Size(640, 2160);
-  const SkBitmap source = CreateSMPTETestImage(kSourceSize);
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(0, 0, 256, 128));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSourceSize, gfx::Rect(kSourceSize), 2, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests a BEST quality scaling of 1280x720 → 1024x700.
-TEST_F(GLScalerPixelTest, ScalesAtBestQuality) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(1280, 720);
-  params.scale_to = gfx::Vector2d(1024, 700);
-  params.quality = GLScaler::Parameters::Quality::BEST;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(
-      u8"Output "
-      u8"← {BICUBIC_HALF_1D/lowp [2048 700] to [1024 700]} "
-      u8"← {BICUBIC_UPSCALE/lowp [1280 700] to [2048 700]} "
-      u8"← {BICUBIC_HALF_1D/lowp [1280 1400] to [1280 700]} "
-      u8"← {BICUBIC_UPSCALE/lowp [1280 720] to [1280 1400]} "
-      u8"← Source",
-      GetScalerString());
-  constexpr gfx::Size kSourceSize = gfx::Size(1280, 720);
-  const SkBitmap source = CreateSMPTETestImage(kSourceSize);
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(0, 0, 1024, 700));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(
-      actual, kSourceSize, gfx::Rect(kSourceSize), 4, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests that a source offset can be provided to sample the source starting at a
-// different location.
-TEST_F(GLScalerPixelTest, TranslatesWithSourceOffset) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  GLScaler::Parameters params;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp copy} ← Source", GetScalerString());
-  const SkBitmap source = CreateSMPTETestImage(kSMPTEFullSize);
-  static_assert(kSMPTEFullSize.width() % 2 == 0, "Fix kSMPTEFullSize.");
-  static_assert(kSMPTEFullSize.height() % 4 == 0, "Fix kSMPTEFullSize.");
-  const gfx::Vector2d offset(kSMPTEFullSize.width() / 2,
-                             kSMPTEFullSize.height() / 4);
-  const gfx::Rect src_rect(offset.x(), offset.y(),
-                           kSMPTEFullSize.width() - offset.x(),
-                           kSMPTEFullSize.height() - offset.y());
-  const gfx::Rect output_rect(0, 0, kSMPTEFullSize.width() - offset.x(),
-                              kSMPTEFullSize.height() - offset.y());
-  const SkBitmap actual = Scale(source, offset, output_rect);
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(actual, kSMPTEFullSize, src_rect, 0,
-                                      &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests that the source offset works when the source content is vertically
-// flipped.
-TEST_F(GLScalerPixelTest, TranslatesVerticallyFlippedSourceWithSourceOffset) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  GLScaler::Parameters params;
-  params.is_flipped_source = true;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp copy} ← Source", GetScalerString());
-  const SkBitmap flipped_source =
-      CreateVerticallyFlippedBitmap(CreateSMPTETestImage(kSMPTEFullSize));
-  const gfx::Vector2d offset(kSMPTEFullSize.width() / 2,
-                             kSMPTEFullSize.height() / 4);
-  const gfx::Rect src_rect(offset.x(), offset.y(),
-                           kSMPTEFullSize.width() - offset.x(),
-                           kSMPTEFullSize.height() - offset.y());
-  const gfx::Rect output_rect(0, 0, kSMPTEFullSize.width() - offset.x(),
-                              kSMPTEFullSize.height() - offset.y());
-  const SkBitmap flipped_back_actual =
-      CreateVerticallyFlippedBitmap(Scale(flipped_source, offset, output_rect));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(flipped_back_actual, kSMPTEFullSize,
-                                      src_rect, 0, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual (flipped-back): " << cc::GetPNGDataUrl(flipped_back_actual);
-}
-
-// Tests that the correct source selection is made when both translating the
-// source and then scaling. Scale "from" and "to" values are chosen such that a
-// multi-stage scaler will be configured (to test that offsets are correcty
-// calculated and passed between multiple stages).
-TEST_F(GLScalerPixelTest, ScalesWithTranslatedSourceOffset) {
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(640, 2160);
-  params.scale_to = gfx::Vector2d(256, 128);
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(
-      u8"Output "
-      u8"← {BILINEAR/lowp [256 256] to [256 128]} "
-      u8"← {BILINEAR4/lowp [512 2048] to [256 256]} "
-      u8"← {BILINEAR2X2/lowp [640 2160] to [512 2048]} "
-      u8"← Source",
-      GetScalerString());
-  constexpr gfx::Size kSourceSize = gfx::Size(640, 2160);
-  const SkBitmap source = CreateSMPTETestImage(kSourceSize);
-  const gfx::Vector2d offset(kSourceSize.width() / 2, kSourceSize.height() / 4);
-  const gfx::Rect output_rect(0, 0, 128, 64);
-  const SkBitmap actual = Scale(source, offset, output_rect);
-  const gfx::Rect expected_copy_rect(
-      offset.x(), offset.y(),
-      output_rect.width() * params.scale_from.x() / params.scale_to.x(),
-      output_rect.height() * params.scale_from.y() / params.scale_to.y());
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(actual, kSourceSize, expected_copy_rect,
-                                      2, &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nExpected crop region of source: " << expected_copy_rect.ToString()
-      << "\nFull (uncropped) Source: " << cc::GetPNGDataUrl(source)
-      << "\nActual: " << cc::GetPNGDataUrl(actual);
-}
-
-// Tests that the output is vertically flipped, if requested in the parameters.
-TEST_F(GLScalerPixelTest, VerticallyFlipsOutput) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  GLScaler::Parameters params;
-  params.is_flipped_source = false;
-  params.flip_output = true;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp+flip_y copy} ← Source",
-            GetScalerString());
-  const SkBitmap source = CreateSMPTETestImage(kSMPTEFullSize);
-  const SkBitmap flipped_back_actual = CreateVerticallyFlippedBitmap(
-      Scale(source, gfx::Vector2d(), gfx::Rect(kSMPTEFullSize)));
-  int max_color_diff = GetBaselineColorDifference();
-  EXPECT_TRUE(LooksLikeSMPTETestImage(flipped_back_actual, kSMPTEFullSize,
-                                      gfx::Rect(kSMPTEFullSize), 0,
-                                      &max_color_diff))
-      << "max_color_diff measured was " << max_color_diff
-      << "\nActual (flipped-back): " << cc::GetPNGDataUrl(flipped_back_actual);
-}
-
-// Tests that the single-channel export ScalerStage works by executing a red
-// channel export.
-TEST_F(GLScalerPixelTest, ExportsTheRedColorChannel) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  GLScaler::Parameters params;
-  params.is_flipped_source = false;
-  params.export_format = GLScaler::Parameters::ExportFormat::CHANNEL_0;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {PLANAR_CHANNEL_0/lowp [4 1] to [1 1]} ← Source",
-            GetScalerString());
-  const SkBitmap source = CreateSMPTETestImage(kSMPTEFullSize);
-  const SkBitmap expected = CreatePackedPlanarBitmap(source, 0);
-  const gfx::Size output_size(expected.width(), expected.height());
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(output_size));
-  constexpr float kAvgAbsoluteErrorLimit = 1.f;
-  constexpr int kMaxAbsoluteErrorLimit = 2;
-  EXPECT_TRUE(cc::FuzzyPixelComparator(
-                  false, 100.f, 0.f,
-                  GetBaselineColorDifference() + kAvgAbsoluteErrorLimit,
-                  GetBaselineColorDifference() + kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected, actual))
-      << "\nActual: " << cc::GetPNGDataUrl(actual)
-      << "\Expected: " << cc::GetPNGDataUrl(expected);
-}
-
-// A test that also stands as an example for how to use the GLScaler to scale a
-// screen-sized RGB source (2160x1440, 16:10 aspect ratio) to a typical video
-// resolution (720p, 16:9). The end-goal is to produce three textures, which
-// contain the three YUV planes in I420 format.
-//
-// This is a two step process: First, the source is scaled and color space
-// converted, with the final result exported as NV61 format (a full size luma
-// plane + a half-width interleaved UV image). Second, the interleaved UV image
-// is scaled by half in the vertical direction and then separated into one U and
-// one V plane.
-TEST_F(GLScalerPixelTest, Example_ScaleAndExportForScreenVideoCapture) {
-  if (scaler()->GetMaxDrawBuffersSupported() < 2) {
-    LOG(WARNING) << "Skipping test due to lack of MRT support.";
-    return;
-  }
-
-  // Step 1: Produce a scaled NV61-format result.
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(2160, 1440);
-  params.scale_to = gfx::Vector2d(1280, 720);
-  params.source_color_space = DefaultRGBColorSpace();
-  params.output_color_space = DefaultYUVColorSpace();
-  params.enable_precise_color_management = true;
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = true;
-  params.flip_output = true;
-  params.export_format = GLScaler::Parameters::ExportFormat::NV61;
-  params.swizzle[0] = GL_BGRA_EXT;  // Swizzle for readback.
-  params.swizzle[1] = GL_RGBA;      // Don't swizzle output for Step 2.
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_STRING_MATCHES(
-      u8"Output "
-      u8"← {I422_NV61_MRT/mediump [5120 720] to [1280 720], with color x-form "
-      u8"to *BT709*, with swizzle(0)} "
-      u8"← {BILINEAR2/mediump [2160 1440] to [1280 720]} "
-      u8"← {BILINEAR/mediump+flip_y copy, with color x-form *BT709* to "
-      u8"*transfer:1.0000\\*x*} "
-      u8"← Source",
-      GetScalerString());
-
-  constexpr gfx::Size kSourceSize = gfx::Size(2160, 1440);
-  const GLuint src_texture = UploadTexture(
-      CreateVerticallyFlippedBitmap(CreateSMPTETestImage(kSourceSize)));
-  constexpr gfx::Size kOutputSize = gfx::Size(1280, 720);
-  SkBitmap expected = CreateSMPTETestImage(kOutputSize);
-  ConvertRGBABitmapToYUV(&expected);
-
-  // While the output size is 1280x720, the packing of 4 pixels into one RGBA
-  // quad means that the texture width must be divided by 4, and that size
-  // passed in the output_rect argument in the call to ScaleToMultipleOutputs().
-  const gfx::Size y_plane_size(kOutputSize.width() / 4, kOutputSize.height());
-  const GLuint y_plane_texture = CreateTexture(y_plane_size);
-  const GLuint uv_interleaved_texture = CreateTexture(y_plane_size);
-
-  ASSERT_TRUE(scaler()->ScaleToMultipleOutputs(
-      src_texture, kSourceSize, gfx::Vector2d(), y_plane_texture,
-      uv_interleaved_texture, gfx::Rect(y_plane_size)));
-
-  // Step 2: Run the scaler again with the deinterleaver exporter, to produce
-  // the I420 U and V planes from the NV61 UV interleaved image.
-  params = GLScaler::Parameters();  // Reset params.
-  params.scale_from = gfx::Vector2d(1, 2);
-  params.scale_to = gfx::Vector2d(1, 1);
-  params.source_color_space = DefaultYUVColorSpace();
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;  // Output was already flipped in Step 1.
-  params.export_format =
-      GLScaler::Parameters::ExportFormat::DEINTERLEAVE_PAIRWISE;
-  params.swizzle[0] = GL_BGRA_EXT;  // Swizzle for readback.
-  params.swizzle[1] = GL_BGRA_EXT;  // Swizzle for readback.
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(
-      u8"Output "
-      u8"← {DEINTERLEAVE_PAIRWISE_MRT/lowp [2 2] to [1 1], with swizzle(0), "
-      u8"with swizzle(1)} "
-      u8"← Source",
-      GetScalerString());
-
-  const gfx::Size uv_plane_size(y_plane_size.width() / 2,
-                                y_plane_size.height() / 2);
-  const GLuint u_plane_texture = CreateTexture(uv_plane_size);
-  const GLuint v_plane_texture = CreateTexture(uv_plane_size);
-  ASSERT_TRUE(scaler()->ScaleToMultipleOutputs(
-      uv_interleaved_texture, y_plane_size, gfx::Vector2d(), u_plane_texture,
-      v_plane_texture, gfx::Rect(uv_plane_size)));
-
-  // Download the textures, and unpack them into an interleaved YUV bitmap, for
-  // comparison against the |expected| rendition.
-  SkBitmap actual = AllocateRGBABitmap(kOutputSize);
-  actual.eraseColor(SkColorSetARGB(0xff, 0x00, 0x80, 0x80));
-  SkBitmap y_plane = DownloadTexture(y_plane_texture, y_plane_size);
-  SwizzleBitmap(&y_plane);
-  UnpackPlanarBitmap(y_plane, 0, &actual);
-  SkBitmap u_plane = DownloadTexture(u_plane_texture, uv_plane_size);
-  SwizzleBitmap(&u_plane);
-  UnpackPlanarBitmap(u_plane, 1, &actual);
-  SkBitmap v_plane = DownloadTexture(v_plane_texture, uv_plane_size);
-  SwizzleBitmap(&v_plane);
-  UnpackPlanarBitmap(v_plane, 2, &actual);
-
-  // Provide generous error limits to account for the chroma subsampling in the
-  // |actual| result when compared to the perfect |expected| rendition.
-  constexpr float kAvgAbsoluteErrorLimit = 16.f;
-  constexpr int kMaxAbsoluteErrorLimit = 0x80;
-  EXPECT_TRUE(cc::FuzzyPixelComparator(false, 100.f, 0.f,
-                                       kAvgAbsoluteErrorLimit,
-                                       kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected, actual))
-      << "\nActual: " << cc::GetPNGDataUrl(actual)
-      << "\nExpected: " << cc::GetPNGDataUrl(expected);
-}
-
-// Performs a scaling-with-gamma-correction experiment to test GLScaler's
-// "precise color management" feature. A 50% scale is executed on the same
-// source image, once with color management turned on, and once with it turned
-// off. The results, each of which should be different, are then examined.
-TEST_F(GLScalerPixelTest, ScalesWithColorManagement) {
-  if (!scaler()->SupportsPreciseColorManagement()) {
-    LOG(WARNING) << "Skipping test due to lack of 16-bit float support.";
-    return;
-  }
-
-  // An image of a raspberry (source:
-  // https://commons.wikimedia.org/wiki/File:Framboise_Margy_3.jpg) has been
-  // transformed in such a way that scaling it by half in both directions will
-  // reveal whether scaling is occurring on linearized color values. When scaled
-  // correctly, the output image should contain a visible raspberry blended
-  // heavily with solid gray. However, if done naively, the output will be a
-  // solid 50% gray. For details, see: http://www.ericbrasseur.org/gamma.html
-  //
-  // Note that the |source| and |expected| images both use the sRGB color space.
-  const SkBitmap source = LoadPNGTestImage("rasp-grayator.png");
-  ASSERT_FALSE(source.isNull());
-  const SkBitmap expected = LoadPNGTestImage("rasp-grayator-half.png");
-  ASSERT_FALSE(expected.isNull());
-  const gfx::Size output_size =
-      gfx::Size(source.width() / 2, source.height() / 2);
-  ASSERT_EQ(gfx::Size(expected.width(), expected.height()), output_size);
-  const SkBitmap expected_naive = AllocateRGBABitmap(output_size);
-  expected_naive.eraseColor(SkColorSetARGB(0xff, 0x7f, 0x7f, 0x7f));
-
-  // Scale the right way: With color management enabled, the raspberry should be
-  // visible in the downscaled result.
-  GLScaler::Parameters params;
-  params.scale_from = gfx::Vector2d(2, 2);
-  params.scale_to = gfx::Vector2d(1, 1);
-  params.source_color_space = gfx::ColorSpace::CreateSRGB();
-  params.enable_precise_color_management = true;
-  params.quality = GLScaler::Parameters::Quality::GOOD;
-  params.is_flipped_source = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_STRING_MATCHES(
-      u8"Output "
-      u8"← {BILINEAR/mediump [2 2] to [1 1], with color x-form to *BT709*} "
-      u8"← {BILINEAR/mediump copy, with color x-form *BT709* to "
-      u8"*transfer:1.0000\\*x*} "
-      u8"← Source",
-      GetScalerString());
-  const SkBitmap actual =
-      Scale(source, gfx::Vector2d(), gfx::Rect(output_size));
-  constexpr float kAvgAbsoluteErrorLimit = 1.f;
-  constexpr int kMaxAbsoluteErrorLimit = 2;
-  EXPECT_TRUE(cc::FuzzyPixelComparator(
-                  false, 100.f, 0.f,
-                  GetBaselineColorDifference() + kAvgAbsoluteErrorLimit,
-                  GetBaselineColorDifference() + kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected, actual))
-      << "\nActual: " << cc::GetPNGDataUrl(actual)
-      << "\nExpected (half size): " << cc::GetPNGDataUrl(expected)
-      << "\nOriginal: " << cc::GetPNGDataUrl(source);
-
-  // Scale the naive way: Without color management, expect a solid gray result.
-  params.enable_precise_color_management = false;
-  ASSERT_TRUE(scaler()->Configure(params));
-  EXPECT_EQ(u8"Output ← {BILINEAR/lowp [2 2] to [1 1]} ← Source",
-            GetScalerString());
-  const SkBitmap actual_naive =
-      Scale(source, gfx::Vector2d(), gfx::Rect(output_size));
-  EXPECT_TRUE(cc::FuzzyPixelComparator(
-                  false, 100.f, 0.f,
-                  GetBaselineColorDifference() + kAvgAbsoluteErrorLimit,
-                  GetBaselineColorDifference() + kMaxAbsoluteErrorLimit, 0)
-                  .Compare(expected_naive, actual_naive))
-      << "\nActual: " << cc::GetPNGDataUrl(actual_naive)
-      << "\nExpected (half size): " << cc::GetPNGDataUrl(expected_naive)
-      << "\nOriginal: " << cc::GetPNGDataUrl(source);
-}
-
-#undef EXPECT_STRING_MATCHES
-
-}  // namespace viz
diff --git a/components/viz/common/gl_scaler_shader_pixeltest.cc b/components/viz/common/gl_scaler_shader_pixeltest.cc
deleted file mode 100644
index e1e7b8c..0000000
--- a/components/viz/common/gl_scaler_shader_pixeltest.cc
+++ /dev/null
@@ -1,785 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_scaler.h"
-
-#include <sstream>
-#include <tuple>
-#include <vector>
-
-#include "build/build_config.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "gpu/GLES2/gl2chromium.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "ui/gfx/color_transform.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/build_info.h"
-#endif
-
-namespace viz {
-
-namespace {
-
-// Base size of test images to be operated upon. Both dimensions must be
-// divisible by 2, 3, or 4.
-constexpr gfx::Size kBaseSize = gfx::Size(16 * 4 * 3, 9 * 4 * 3);
-
-}  // namespace
-
-class GLScalerShaderPixelTest
-    : public cc::PixelTest,
-      public testing::WithParamInterface<std::tuple<bool, bool>>,
-      public GLScalerTestUtil {
- public:
-  using Axis = GLScaler::Axis;
-  using Shader = GLScaler::Shader;
-  using ShaderProgram = GLScaler::ShaderProgram;
-
-  GLScalerShaderPixelTest()
-      : scoped_trace_(
-            __FILE__,
-            __LINE__,
-            (testing::Message()
-             << "is_converting_rgb_to_yuv=" << is_converting_rgb_to_yuv()
-             << ", is_swizzling_output=" << is_swizzling_output())) {}
-
-  bool is_converting_rgb_to_yuv() const { return std::get<0>(GetParam()); }
-  bool is_swizzling_output() const { return std::get<1>(GetParam()); }
-
-  bool AreMultipleRenderingTargetsSupported() const {
-    return scaler_->GetMaxDrawBuffersSupported() > 1;
-  }
-
-  // Returns a cached ShaderProgram, maybe configured to convert RGB→YUV and/or
-  // swizzle the 1st and 3rd bytes in the output (depending on GetParams()).
-  ShaderProgram* GetShaderProgram(Shader shader) {
-    std::unique_ptr<gfx::ColorTransform> transform;
-    if (is_converting_rgb_to_yuv()) {
-      transform = gfx::ColorTransform::NewColorTransform(
-          DefaultRGBColorSpace(), DefaultYUVColorSpace());
-    }
-    const GLenum swizzle[2] = {
-        static_cast<GLenum>(is_swizzling_output() ? GL_BGRA_EXT : GL_RGBA),
-        static_cast<GLenum>(is_swizzling_output() ? GL_BGRA_EXT : GL_RGBA),
-    };
-    return scaler_->GetShaderProgram(shader, GL_UNSIGNED_BYTE, transform.get(),
-                                     swizzle);
-  }
-
-  GLuint CreateTexture(const gfx::Size& size) {
-    return texture_helper_->CreateTexture(size);
-  }
-
-  GLuint UploadTexture(const SkBitmap& bitmap) {
-    return texture_helper_->UploadTexture(bitmap);
-  }
-
-  SkBitmap DownloadTexture(GLuint texture, const gfx::Size& size) {
-    return texture_helper_->DownloadTexture(texture, size);
-  }
-
-  GLuint RenderToNewTexture(GLuint src_texture, const gfx::Size& size) {
-    return RenderToNewTextures(src_texture, size, false).first;
-  }
-
-  // Using the current shader program, creates new texture(s) of the given
-  // |size| and draws using |src_texture| as input. If |dual_outputs| is true,
-  // two new textures are created and drawn-to simultaneously; otherwise, only
-  // one is created and drawn-to. The caller does not take ownership of the new
-  // texture(s).
-  std::pair<GLuint, GLuint> RenderToNewTextures(GLuint src_texture,
-                                                const gfx::Size& size,
-                                                bool dual_outputs) {
-    std::pair<GLuint, GLuint> dst_textures(
-        CreateTexture(size), dual_outputs ? CreateTexture(size) : 0u);
-    GLuint framebuffer = 0;
-    gl_->GenFramebuffers(1, &framebuffer);
-    gl_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-    gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                              GL_TEXTURE_2D, dst_textures.first, 0);
-    if (dual_outputs) {
-      gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 1,
-                                GL_TEXTURE_2D, dst_textures.second, 0);
-    }
-
-    gl_->BindTexture(GL_TEXTURE_2D, src_texture);
-
-    gl_->Viewport(0, 0, size.width(), size.height());
-    const GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1};
-    if (dual_outputs) {
-      gl_->DrawBuffersEXT(2, buffers);
-    }
-    // Assumption: The |vertex_attributes_buffer_| created in SetUp() is
-    // currently bound to GL_ARRAY_BUFFER.
-    gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-    gl_->DeleteFramebuffers(1, &framebuffer);
-
-    return dst_textures;
-  }
-
-  // Returns a texture that converts the input |texture| back to unswizzled RGB,
-  // if necessary, depending on GetParam(). The caller does not take ownership
-  // of the returned texture, which could be the same texture as the input
-  // argument in some cases.
-  GLuint ConvertBackToUnswizzledRGB(GLuint texture, const gfx::Size& size) {
-    GLuint result = texture;
-    if (is_swizzling_output()) {
-      const GLenum swizzle[2] = {GL_BGRA_EXT, GL_BGRA_EXT};
-      scaler_
-          ->GetShaderProgram(Shader::BILINEAR, GL_UNSIGNED_BYTE, nullptr,
-                             swizzle)
-          ->UseProgram(size, gfx::RectF(gfx::Rect(size)), size,
-                       Axis::HORIZONTAL, false);
-      result = RenderToNewTexture(result, size);
-    }
-    if (is_converting_rgb_to_yuv()) {
-      const auto transform = gfx::ColorTransform::NewColorTransform(
-          DefaultYUVColorSpace(), DefaultRGBColorSpace());
-      const GLenum swizzle[2] = {GL_RGBA, GL_RGBA};
-      scaler_
-          ->GetShaderProgram(Shader::BILINEAR, GL_UNSIGNED_BYTE,
-                             transform.get(), swizzle)
-          ->UseProgram(size, gfx::RectF(gfx::Rect(size)), size,
-                       Axis::HORIZONTAL, false);
-      result = RenderToNewTexture(result, size);
-    }
-    return result;
-  }
-
-  // A test case executed by RunSMPTEScalingTestCases().
-  struct SMPTEScalingTestCase {
-    gfx::Rect src_rect;    // Selects a subrect of the source.
-    int scale_from;        // Scale ratio denominator.
-    int scale_to;          // Scale ratio numerator.
-    int fuzzy_bar_border;  // Ignored pixels between color bars, when comparing.
-  };
-
-  // Draws with the given shader for each of the provided |test_cases| and adds
-  // gtest failure(s) if the output does not look like a part of the SMPTE test
-  // image.
-  void RunSMPTEScalingTestCases(
-      Shader shader,
-      const std::vector<SMPTEScalingTestCase>& test_cases) {
-    const SkBitmap source = CreateSMPTETestImage(kBaseSize);
-    const GLuint src_texture = UploadTexture(source);
-
-    for (const auto& tc : test_cases) {
-      for (int is_horizontal = 0; is_horizontal <= 1; ++is_horizontal) {
-        gfx::Size dst_size = tc.src_rect.size();
-        Axis axis;
-        if (is_horizontal) {
-          CHECK_EQ((dst_size.width() * tc.scale_to) % tc.scale_from, 0);
-          dst_size.set_width(dst_size.width() * tc.scale_to / tc.scale_from);
-          axis = Axis::HORIZONTAL;
-        } else {
-          CHECK_EQ((dst_size.height() * tc.scale_to) % tc.scale_from, 0);
-          dst_size.set_height(dst_size.height() * tc.scale_to / tc.scale_from);
-          axis = Axis::VERTICAL;
-        }
-
-        SCOPED_TRACE(testing::Message()
-                     << "src_rect=" << tc.src_rect.ToString()
-                     << ", scale from→to=" << tc.scale_from << "→"
-                     << tc.scale_to << ", dst_size=" << dst_size.ToString());
-
-        GetShaderProgram(shader)->UseProgram(kBaseSize, gfx::RectF(tc.src_rect),
-                                             dst_size, axis, false);
-        const SkBitmap actual = DownloadTexture(
-            ConvertBackToUnswizzledRGB(
-                RenderToNewTexture(src_texture, dst_size), dst_size),
-            dst_size);
-        int max_color_diff = GetMaxAllowedColorDifference();
-        if (!LooksLikeSMPTETestImage(actual, kBaseSize, tc.src_rect,
-                                     tc.fuzzy_bar_border, &max_color_diff)) {
-          ADD_FAILURE() << "Scaled image does not look like the correct scaled "
-                           "subrect of the SMPTE test image (max diff measured="
-                        << max_color_diff
-                        << "):\nActual: " << cc::GetPNGDataUrl(actual);
-        }
-      }
-    }
-  }
-
-  // Adds test failures if an |actual| image does not match the |expected|
-  // image. When not doing color space conversion, the images must match
-  // exactly; otherwise, some minor differences are allowed.
-  void ExpectAreTheSameImage(const SkBitmap& expected,
-                             const SkBitmap& actual) const {
-    const int max_color_diff = GetMaxAllowedColorDifference();
-    if (!cc::FuzzyPixelComparator(false, 100.0f, 0.0f, max_color_diff,
-                                  max_color_diff, 0)
-             .Compare(expected, actual)) {
-      ADD_FAILURE() << "Images are not similar enough (max_color_diff="
-                    << max_color_diff
-                    << "):\nExpected: " << cc::GetPNGDataUrl(expected)
-                    << "\nActual: " << cc::GetPNGDataUrl(actual);
-    }
-  }
-
-  // Draws with the given shader to downscale a "striped pattern" image by
-  // |downscale_factor| in one dimension only, and adds gtest failure(s) if the
-  // resulting image is not of the |expected_solid_color|. |cycle| specifies the
-  // colors of the stripes, which should average to |expected_solid_color|.
-  //
-  // If the shader program is correct, it should be sampling the texture halfway
-  // between each pair of stripes and then averaging the result. This means that
-  // every N pixels in the source will be averaged to one pixel in the output,
-  // creating a solid color fill as output. If the shader is sampling the
-  // texture at the wrong points, the result will be tinted and/or contain
-  // striping.
-  void RunMultiplePassBilinearTest(Shader shader,
-                                   int downscale_factor,
-                                   const std::vector<SkColor>& cycle) {
-    // Compute the expected solid fill color from the colors in |cycle|.
-    uint32_t sum_red = 0;
-    uint32_t sum_green = 0;
-    uint32_t sum_blue = 0;
-    uint32_t sum_alpha = 0;
-    for (SkColor c : cycle) {
-      sum_red += SkColorGetR(c);
-      sum_green += SkColorGetG(c);
-      sum_blue += SkColorGetB(c);
-      sum_alpha += SkColorGetA(c);
-    }
-    const float count = cycle.size();
-    // Note: Taking the rounded average for each color channel.
-    const SkColor expected_solid_color =
-        SkColorSetARGB(sum_alpha / count + 0.5f, sum_red / count + 0.5f,
-                       sum_green / count + 0.5f, sum_blue / count + 0.5f);
-
-    // Run the test for the vertical direction, and again for the horizontal
-    // direction.
-    const gfx::Rect src_rect =
-        gfx::Rect(0, 0, 10 * downscale_factor, 10 * downscale_factor);
-    for (int is_horizontal = 0; is_horizontal <= 1; ++is_horizontal) {
-      gfx::Size dst_size = src_rect.size();
-      Axis axis;
-      CyclicalPattern pattern;
-      if (is_horizontal) {
-        dst_size.set_width(dst_size.width() / downscale_factor);
-        axis = Axis::HORIZONTAL;
-        pattern = VERTICAL_STRIPES;
-      } else {
-        dst_size.set_height(dst_size.height() / downscale_factor);
-        axis = Axis::VERTICAL;
-        pattern = HORIZONTAL_STRIPES;
-      }
-
-      // Create the expected output image consisting of a solid fill color.
-      SkBitmap expected = AllocateRGBABitmap(dst_size);
-      expected.eraseColor(expected_solid_color);
-
-      // Run the test for each of N possible rotations of the |cycle| of
-      // stripes.
-      for (size_t rotation = 0; rotation < cycle.size(); ++rotation) {
-        SCOPED_TRACE(testing::Message() << "is_horizontal=" << !!is_horizontal
-                                        << ", rotation=" << rotation
-                                        << ", expected_solid_color=" << std::hex
-                                        << expected_solid_color);
-
-        const SkBitmap source =
-            CreateCyclicalTestImage(src_rect.size(), pattern, cycle, rotation);
-        const GLuint src_texture = UploadTexture(source);
-
-        // Execute the program, and convert the shader program's drawn result
-        // back to an unswizzled RGB form, and compare that with the expected
-        // image.
-        GetShaderProgram(shader)->UseProgram(
-            src_rect.size(), gfx::RectF(src_rect), dst_size, axis, false);
-        const SkBitmap actual = DownloadTexture(
-            ConvertBackToUnswizzledRGB(
-                RenderToNewTexture(src_texture, dst_size), dst_size),
-            dst_size);
-        ExpectAreTheSameImage(expected, actual);
-      }
-    }
-  }
-
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-
-    scaler_ = std::make_unique<GLScaler>(context_provider());
-    gl_ = context_provider()->ContextGL();
-    CHECK(gl_);
-
-    // Set up vertex attributes buffer and its data.
-    gl_->GenBuffers(1, &vertex_attributes_buffer_);
-    gl_->BindBuffer(GL_ARRAY_BUFFER, vertex_attributes_buffer_);
-    gl_->BufferData(GL_ARRAY_BUFFER, sizeof(ShaderProgram::kVertexAttributes),
-                    ShaderProgram::kVertexAttributes, GL_STATIC_DRAW);
-
-    texture_helper_ = std::make_unique<GLScalerTestTextureHelper>(gl_);
-  }
-
-  void TearDown() final {
-    texture_helper_.reset();
-
-    if (vertex_attributes_buffer_) {
-      gl_->DeleteBuffers(1, &vertex_attributes_buffer_);
-      vertex_attributes_buffer_ = 0;
-    }
-
-    gl_ = nullptr;
-    scaler_.reset();
-
-    cc::PixelTest::TearDown();
-  }
-
-  // Returns the maximum allowed absolute difference between any two color
-  // values in the expected vs actual image comparisons, given the current test
-  // parameters and known platform-specific inaccuracy.
-  int GetMaxAllowedColorDifference() const {
-#if BUILDFLAG(IS_ANDROID)
-    // Android seems to have texture sampling and/or readback accuracy issues
-    // with these programs that are not at all seen on any of the desktop
-    // platforms. Also, versions before Marshmallow seem to have a much larger
-    // accuracy issues with a few of the programs. Thus, use higher thresholds,
-    // assuming that the programs are correct if they can pass a much lower
-    // threshold on other platforms.
-    if (base::android::BuildInfo::GetInstance()->sdk_int() <
-        base::android::SDK_VERSION_MARSHMALLOW) {
-      return (is_converting_rgb_to_yuv() || is_swizzling_output()) ? 24 : 12;
-    }
-    return (is_converting_rgb_to_yuv() || is_swizzling_output()) ? 4 : 2;
-#else
-    return (is_converting_rgb_to_yuv() || is_swizzling_output()) ? 2 : 0;
-#endif
-  }
-
-  bool IsAndroidMarshmallow() {
-#if BUILDFLAG(IS_ANDROID)
-    return base::android::BuildInfo::GetInstance()->sdk_int() ==
-           base::android::SDK_VERSION_MARSHMALLOW;
-#else
-    return false;
-#endif
-  }
-
-  testing::ScopedTrace scoped_trace_;
-  std::unique_ptr<GLScaler> scaler_;
-  gpu::gles2::GLES2Interface* gl_ = nullptr;
-  GLuint vertex_attributes_buffer_ = 0;
-  std::unique_ptr<GLScalerTestTextureHelper> texture_helper_;
-};
-
-// As the BILINEAR shader is used by some of the test helpers, this test is
-// necessary to ensure the correctness of the tools used by all the other tests.
-TEST_P(GLScalerShaderPixelTest, ValidateTestHelpers) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  // Create/validate a SMPTE color bar test image.
-  const SkBitmap original = CreateSMPTETestImage(kBaseSize);
-  int max_color_diff = GetMaxAllowedColorDifference();
-  ASSERT_TRUE(LooksLikeSMPTETestImage(original, kBaseSize, gfx::Rect(kBaseSize),
-                                      0, &max_color_diff))
-      << "max diff measured=" << max_color_diff;
-
-  // Create and upload a test image that has had RGB→YUV conversion performed
-  // and/or had its color channels swizzled, depending on the testing params.
-  SkBitmap image = CreateSMPTETestImage(kBaseSize);
-  if (is_converting_rgb_to_yuv()) {
-    ConvertRGBABitmapToYUV(&image);
-  }
-  if (is_swizzling_output()) {
-    SwizzleBitmap(&image);
-  }
-  const GLuint uploaded_texture = UploadTexture(image);
-
-  // Use the convert-back helper, which uses the BILINEAR shader to convert the
-  // |uploaded_texture| back to an unswizzled RGB form. Then, download the
-  // result and check whether it matches the original.
-  const gfx::Size size(image.width(), image.height());
-  const GLuint converted_back_texture =
-      ConvertBackToUnswizzledRGB(uploaded_texture, size);
-  const SkBitmap actual = DownloadTexture(converted_back_texture, size);
-  ExpectAreTheSameImage(original, actual);
-}
-
-// Tests the default, one-pass bilinear shader which can upscale or downscale by
-// up to 2X.
-TEST_P(GLScalerShaderPixelTest, Bilinear) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  constexpr gfx::Rect whole = gfx::Rect(kBaseSize);
-  constexpr gfx::Rect quadrant =
-      gfx::Rect(kBaseSize.width() / 2, kBaseSize.height() / 2,
-                kBaseSize.width() / 2, kBaseSize.height() / 2);
-  const std::vector<SMPTEScalingTestCase> kTestCases = {
-      // No scaling.
-      {whole, 1, 1, 0},
-      // Downscale by half.
-      {whole, 2, 1, 1},
-      // Upscale by 1.5.
-      {whole, 2, 3, 1},
-      // No scaling; lower-right quadrant only.
-      {quadrant, 1, 1, 0},
-      // Downscale by half; lower-right quadrant only.
-      {quadrant, 2, 1, 1},
-      // Upscale by 1.5; lower-right quadrant only.
-      {quadrant, 2, 3, 1},
-  };
-
-  RunSMPTEScalingTestCases(Shader::BILINEAR, kTestCases);
-}
-
-// Test the 2-tap bilinear shader, which downscales by 4X in one dimension.
-TEST_P(GLScalerShaderPixelTest, TwoTapBilinear) {
-  RunMultiplePassBilinearTest(Shader::BILINEAR2, 4,
-                              {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0xff, 0x00, 0x00, 0xff)});
-}
-
-// Test the 3-tap bilinear shader, which downscales by 6X in one dimension.
-TEST_P(GLScalerShaderPixelTest, ThreeTapBilinear) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  RunMultiplePassBilinearTest(Shader::BILINEAR3, 6,
-                              {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                               SkColorSetARGB(0xbf, 0x00, 0x80, 0xff),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0xbf, 0xff, 0x80, 0x00),
-                               SkColorSetARGB(0xff, 0x00, 0x00, 0xff)});
-}
-
-// Test the 4-tap bilinear shader, which downscales by 8X in one dimension.
-TEST_P(GLScalerShaderPixelTest, FourTapBilinear) {
-  RunMultiplePassBilinearTest(Shader::BILINEAR4, 8,
-                              {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0xff, 0x00, 0x00, 0xff),
-                               SkColorSetARGB(0xff, 0xff, 0xff, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x80),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x80),
-                               SkColorSetARGB(0xff, 0xff, 0x00, 0xff)});
-}
-
-// Test the 2-by-2-tap bilinear shader, which downscales by 4X in both
-// dimensions at the same time.
-TEST_P(GLScalerShaderPixelTest, TwoByTwoTapBilinear) {
-  RunMultiplePassBilinearTest(Shader::BILINEAR2X2, 4,
-                              {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0x7f, 0x00, 0x80, 0x00),
-                               SkColorSetARGB(0xff, 0x00, 0x00, 0xff)});
-}
-
-// Tests the bicubic upscaler for a variety of scaling factors between 1X and
-// 2X, and over the entire source texture versus just its lower-right quadrant.
-TEST_P(GLScalerShaderPixelTest, BicubicUpscale) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  constexpr gfx::Rect whole = gfx::Rect(kBaseSize);
-  constexpr gfx::Rect quadrant =
-      gfx::Rect(kBaseSize.width() / 2, kBaseSize.height() / 2,
-                kBaseSize.width() / 2, kBaseSize.height() / 2);
-  const std::vector<SMPTEScalingTestCase> kTestCases = {
-      // No scaling.
-      {whole, 1, 1, 0},
-      // Upscale by 4/3.
-      {whole, 3, 4, 3},
-      // Upscale by 3/2.
-      {whole, 2, 3, 3},
-      // Upscale by 2X.
-      {whole, 1, 2, 3},
-      // No scaling; lower-right quadrant only.
-      {quadrant, 1, 1, 0},
-      // Upscale by 4/3.
-      {quadrant, 3, 4, 3},
-      // Upscale by 3/2.
-      {quadrant, 2, 3, 3},
-      // Upscale by 2X.
-      {quadrant, 1, 2, 3},
-  };
-
-  RunSMPTEScalingTestCases(Shader::BICUBIC_UPSCALE, kTestCases);
-}
-
-// Tests the bicubic half-downscaler, both over an entire source texture and
-// over just its lower-right quadrant.
-TEST_P(GLScalerShaderPixelTest, BicubicDownscaleByHalf) {
-  constexpr gfx::Rect whole = gfx::Rect(kBaseSize);
-  constexpr gfx::Rect quadrant =
-      gfx::Rect(kBaseSize.width() / 2, kBaseSize.height() / 2,
-                kBaseSize.width() / 2, kBaseSize.height() / 2);
-  const std::vector<SMPTEScalingTestCase> kTestCases = {
-      // Downscale by half.
-      {whole, 2, 1, 2},
-      // Downscale by half; lower-right quadrant only.
-      {quadrant, 2, 1, 2},
-  };
-
-  RunSMPTEScalingTestCases(Shader::BICUBIC_HALF_1D, kTestCases);
-}
-
-// Tests the shaders that read a normal 4-channel interleaved texture and
-// produce a planar texture consisting of just one color channel, packed into
-// RGBA quads.
-TEST_P(GLScalerShaderPixelTest, Export_Planar) {
-  // Disabled on Marshmallow. See crbug.com/933080
-  if (IsAndroidMarshmallow())
-    return;
-
-  const std::vector<SkColor> kCycle = {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0xff, 0x00, 0x00, 0xff)};
-  SkBitmap source = CreateCyclicalTestImage(kBaseSize, STAGGERED, kCycle, 0);
-  const GLuint src_texture = UploadTexture(source);
-
-  // For each channel, create an expected bitmap and compare it to the result
-  // from drawing with the shader program.
-  if (is_converting_rgb_to_yuv()) {
-    ConvertRGBABitmapToYUV(&source);
-  }
-  for (int channel = 0; channel <= 3; ++channel) {
-    SkBitmap expected = CreatePackedPlanarBitmap(source, channel);
-    if (is_swizzling_output()) {
-      SwizzleBitmap(&expected);
-    }
-
-    const Shader shader = static_cast<Shader>(
-        static_cast<int>(Shader::PLANAR_CHANNEL_0) + channel);
-    const gfx::Size dst_size(kBaseSize.width() / 4, kBaseSize.height());
-    GetShaderProgram(shader)->UseProgram(kBaseSize,
-                                         gfx::RectF(gfx::Rect(kBaseSize)),
-                                         dst_size, Axis::HORIZONTAL, false);
-    const SkBitmap actual =
-        DownloadTexture(RenderToNewTexture(src_texture, dst_size), dst_size);
-    ExpectAreTheSameImage(expected, actual);
-  }
-}
-
-// Tests that the I422/NV61 formatter shader program produces a planar texture
-// and an interleaved half-width texture from a normal 4-channel interleaved
-// texture. See gl_shader.h for more specifics.
-TEST_P(GLScalerShaderPixelTest, Export_I422_NV61) {
-  if (!AreMultipleRenderingTargetsSupported()) {
-    LOG(WARNING) << "Skipping test due to lack of MRT support on this machine.";
-    return;
-  }
-
-  // Use a vertical stripes source image/texture to test that the shader is
-  // sampling the texture at the correct points and performing
-  // downscale-blending in the second texture.
-  const std::vector<SkColor> kCycle = {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0xff, 0x00, 0x00, 0xff)};
-  SkBitmap source =
-      CreateCyclicalTestImage(kBaseSize, VERTICAL_STRIPES, kCycle, 0);
-  const GLuint src_texture = UploadTexture(source);
-
-  // Create the expected output images: The first (A) is simply the first color
-  // channel of the source packed into a planar format. The second (BC) consists
-  // of the second and third color channels downscaled by half and interleaved.
-  // The following can be considered a reference implementation for what the
-  // shader program is supposed to do.
-  if (is_converting_rgb_to_yuv()) {
-    ConvertRGBABitmapToYUV(&source);
-  }
-  SkBitmap expected_a = CreatePackedPlanarBitmap(source, 0);
-  if (is_swizzling_output()) {
-    SwizzleBitmap(&expected_a);
-  }
-  const gfx::Size dst_size(expected_a.width(), expected_a.height());
-  SkBitmap expected_bc = AllocateRGBABitmap(dst_size);
-  for (int y = 0; y < dst_size.height(); ++y) {
-    const uint32_t* const src = source.getAddr32(0, y);
-    uint32_t* const dst_bc = expected_bc.getAddr32(0, y);
-    for (int x = 0; x < dst_size.width(); ++x) {
-      //     (src[0..3])        (dst_bc)
-      // RGBA RGBA rgba rgba --> GBgb     (e.g, two G's blended into one G)
-      const uint32_t g01 = ((((src[x * 4 + 0] >> kGreenShift) & 0xff) +
-                             ((src[x * 4 + 1] >> kGreenShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t b01 = ((((src[x * 4 + 0] >> kBlueShift) & 0xff) +
-                             ((src[x * 4 + 1] >> kBlueShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t g23 = ((((src[x * 4 + 2] >> kGreenShift) & 0xff) +
-                             ((src[x * 4 + 3] >> kGreenShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t b23 = ((((src[x * 4 + 2] >> kBlueShift) & 0xff) +
-                             ((src[x * 4 + 3] >> kBlueShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      dst_bc[x] = ((g01 << kRedShift) | (b01 << kGreenShift) |
-                   (g23 << kBlueShift) | (b23 << kAlphaShift));
-    }
-  }
-  if (is_swizzling_output()) {
-    SwizzleBitmap(&expected_bc);
-  }
-
-  // Execute the program, and compare the shader program's drawn result with the
-  // expected images.
-  GetShaderProgram(Shader::I422_NV61_MRT)
-      ->UseProgram(kBaseSize, gfx::RectF(gfx::Rect(kBaseSize)), dst_size,
-                   Axis::HORIZONTAL, false);
-  const auto textures = RenderToNewTextures(src_texture, dst_size, true);
-  const SkBitmap actual_a = DownloadTexture(textures.first, dst_size);
-  ExpectAreTheSameImage(expected_a, actual_a);
-  const SkBitmap actual_bc = DownloadTexture(textures.second, dst_size);
-  ExpectAreTheSameImage(expected_bc, actual_bc);
-}
-
-// Tests that the PLANAR_CHANNELS_1_2 formatter shader program produces an
-// interleaved half-width texture from a normal 4-channel interleaved texture.
-// See gl_shader.h for more specifics.
-TEST_P(GLScalerShaderPixelTest, Export_PLANAR_CHANNELS_1_2) {
-  // Use a vertical stripes source image/texture to test that the shader is
-  // sampling the texture at the correct points and performing
-  // downscale-blending in the second texture.
-  const std::vector<SkColor> kCycle = {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x80, 0x00),
-                                       SkColorSetARGB(0xff, 0x00, 0x00, 0xff)};
-  SkBitmap source =
-      CreateCyclicalTestImage(kBaseSize, VERTICAL_STRIPES, kCycle, 0);
-  const GLuint src_texture = UploadTexture(source);
-
-  // Create the expected output image: it consists of the second and third
-  // color channels (BC) downscaled by half and interleaved.
-  // The following can be considered a reference implementation for what the
-  // shader program is supposed to do.
-  if (is_converting_rgb_to_yuv()) {
-    ConvertRGBABitmapToYUV(&source);
-  }
-
-  // 4x1 pixels get converted to a packed 1x1 pixel.
-  const gfx::Size dst_size(source.width() / 4, source.height());
-  SkBitmap expected_bc = AllocateRGBABitmap(dst_size);
-  for (int y = 0; y < dst_size.height(); ++y) {
-    const uint32_t* const src = source.getAddr32(0, y);
-    uint32_t* const dst_bc = expected_bc.getAddr32(0, y);
-    for (int x = 0; x < dst_size.width(); ++x) {
-      //     (src[0..3])        (dst_bc)
-      // RGBA RGBA rgba rgba --> GBgb     (e.g, two G's blended into one G)
-      const uint32_t g01 = ((((src[x * 4 + 0] >> kGreenShift) & 0xff) +
-                             ((src[x * 4 + 1] >> kGreenShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t b01 = ((((src[x * 4 + 0] >> kBlueShift) & 0xff) +
-                             ((src[x * 4 + 1] >> kBlueShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t g23 = ((((src[x * 4 + 2] >> kGreenShift) & 0xff) +
-                             ((src[x * 4 + 3] >> kGreenShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      const uint32_t b23 = ((((src[x * 4 + 2] >> kBlueShift) & 0xff) +
-                             ((src[x * 4 + 3] >> kBlueShift) & 0xff)) /
-                                2.f +
-                            0.5f);
-      dst_bc[x] = ((g01 << kRedShift) | (b01 << kGreenShift) |
-                   (g23 << kBlueShift) | (b23 << kAlphaShift));
-    }
-  }
-  if (is_swizzling_output()) {
-    SwizzleBitmap(&expected_bc);
-  }
-
-  // Execute the program, and compare the shader program's drawn result with the
-  // expected images.
-  GetShaderProgram(Shader::PLANAR_CHANNELS_1_2)
-      ->UseProgram(kBaseSize, gfx::RectF(gfx::Rect(kBaseSize)), dst_size,
-                   Axis::HORIZONTAL, false);
-  const auto texture = RenderToNewTexture(src_texture, dst_size);
-  const SkBitmap actual_bc = DownloadTexture(texture, dst_size);
-  ExpectAreTheSameImage(expected_bc, actual_bc);
-}
-
-// Tests the pairwise-deinterleave shader program that produces two planar
-// textures from a single interleaved one.
-TEST_P(GLScalerShaderPixelTest, Export_PairwiseDeinterleave) {
-  if (!AreMultipleRenderingTargetsSupported()) {
-    LOG(WARNING) << "Skipping test due to lack of MRT support on this machine.";
-    return;
-  }
-
-  // This shader does not provide color space conversion. It is just a
-  // demultiplexer/repackager.
-  if (is_converting_rgb_to_yuv()) {
-    return;
-  }
-
-  // Create a source image/texture with a pattern suitable for ensuring the
-  // shader is sampling the texture at the correct points.
-  const std::vector<SkColor> kCycle = {SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-                                       SkColorSetARGB(0xc0, 0x00, 0xc0, 0x00),
-                                       SkColorSetARGB(0x80, 0x00, 0x00, 0x80),
-                                       SkColorSetARGB(0xff, 0xff, 0xff, 0xff)};
-  const SkBitmap source =
-      CreateCyclicalTestImage(kBaseSize, STAGGERED, kCycle, 0);
-  const GLuint src_texture = UploadTexture(source);
-
-  // Create the expected pair of planar images.
-  const gfx::Size dst_size(kBaseSize.width() / 2, kBaseSize.height());
-  SkBitmap expected_a = AllocateRGBABitmap(dst_size);
-  SkBitmap expected_b = AllocateRGBABitmap(dst_size);
-  for (int y = 0; y < dst_size.height(); ++y) {
-    const uint32_t* const src = source.getAddr32(0, y);
-    uint32_t* const dst_a = expected_a.getAddr32(0, y);
-    uint32_t* const dst_b = expected_b.getAddr32(0, y);
-    for (int x = 0; x < dst_size.width(); ++x) {
-      //   (src)       (dst_a) (dst_b)
-      // ABAB abab --> { AAaa + BBbb }
-      dst_a[x] = ((((src[x * 2 + 0] >> kRedShift) & 0xff) << kRedShift) |
-                  (((src[x * 2 + 0] >> kBlueShift) & 0xff) << kGreenShift) |
-                  (((src[x * 2 + 1] >> kRedShift) & 0xff) << kBlueShift) |
-                  (((src[x * 2 + 1] >> kBlueShift) & 0xff) << kAlphaShift));
-      dst_b[x] = ((((src[x * 2 + 0] >> kGreenShift) & 0xff) << kRedShift) |
-                  (((src[x * 2 + 0] >> kAlphaShift) & 0xff) << kGreenShift) |
-                  (((src[x * 2 + 1] >> kGreenShift) & 0xff) << kBlueShift) |
-                  (((src[x * 2 + 1] >> kAlphaShift) & 0xff) << kAlphaShift));
-    }
-  }
-  if (is_swizzling_output()) {
-    SwizzleBitmap(&expected_a);
-    SwizzleBitmap(&expected_b);
-  }
-
-  // Execute the program, and compare the shader program's drawn result with the
-  // expected images.
-  GetShaderProgram(Shader::DEINTERLEAVE_PAIRWISE_MRT)
-      ->UseProgram(kBaseSize, gfx::RectF(gfx::Rect(kBaseSize)), dst_size,
-                   Axis::HORIZONTAL, false);
-  const auto textures = RenderToNewTextures(src_texture, dst_size, true);
-  const SkBitmap actual_a = DownloadTexture(textures.first, dst_size);
-  ExpectAreTheSameImage(expected_a, actual_a);
-  const SkBitmap actual_b = DownloadTexture(textures.second, dst_size);
-  ExpectAreTheSameImage(expected_b, actual_b);
-}
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         GLScalerShaderPixelTest,
-                         testing::Combine(testing::Bool(), testing::Bool()));
-
-}  // namespace viz
diff --git a/components/viz/common/gl_scaler_unittest.cc b/components/viz/common/gl_scaler_unittest.cc
deleted file mode 100644
index 67cab05b..0000000
--- a/components/viz/common/gl_scaler_unittest.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/gl_scaler.h"
-
-#include "cc/test/pixel_test.h"
-#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "gpu/GLES2/gl2chromium.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/common/capabilities.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::ByRef;
-using ::testing::Eq;
-using ::testing::Mock;
-using ::testing::NiceMock;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::ReturnRef;
-using ::testing::SaveArg;
-using ::testing::Sequence;
-
-namespace viz {
-namespace {
-
-class MockContextProvider : public ContextProvider {
- public:
-  MockContextProvider() {
-    ON_CALL(*this, ContextGL())
-        .WillByDefault(
-            Return(reinterpret_cast<gpu::gles2::GLES2Interface*>(0xdeadbeef)));
-    ON_CALL(*this, ContextCapabilities()).WillByDefault(ReturnRef(caps_));
-  }
-
-  MOCK_METHOD1(AddObserver, void(ContextLostObserver* obs));
-  MOCK_METHOD1(RemoveObserver, void(ContextLostObserver* obs));
-  MOCK_CONST_METHOD0(ContextCapabilities, const gpu::Capabilities&());
-  MOCK_METHOD0(ContextGL, gpu::gles2::GLES2Interface*());
-
-  // Stubbed-out, because the tests just stack-allocate this object.
-  void AddRef() const final {}
-  void Release() const final {}
-
- private:
-  gpu::Capabilities caps_;
-
-  // Other ContextProvider methods; but stubbed-out because they are never
-  // called.
-  gpu::ContextResult BindToCurrentThread() final {
-    NOTREACHED();
-    return gpu::ContextResult::kSuccess;
-  }
-  base::Lock* GetLock() final {
-    NOTREACHED();
-    return nullptr;
-  }
-  ContextCacheController* CacheController() final {
-    NOTREACHED();
-    return nullptr;
-  }
-  gpu::ContextSupport* ContextSupport() final {
-    NOTREACHED();
-    return nullptr;
-  }
-  class GrDirectContext* GrContext() final {
-    NOTREACHED();
-    return nullptr;
-  }
-  gpu::SharedImageInterface* SharedImageInterface() final {
-    NOTREACHED();
-    return nullptr;
-  }
-  const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const final {
-    NOTREACHED();
-    return *reinterpret_cast<gpu::GpuFeatureInfo*>(0xdeadbeef);
-  }
-};
-
-class GLScalerTest : public cc::PixelTest {
- protected:
-  void SetUp() final {
-    cc::PixelTest::SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-  }
-
-  void TearDown() final { cc::PixelTest::TearDown(); }
-};
-
-TEST_F(GLScalerTest, AddAndRemovesSelfAsContextLossObserver) {
-  NiceMock<MockContextProvider> provider;
-  ContextLostObserver* registered_observer = nullptr;
-  Sequence s;
-  EXPECT_CALL(provider, AddObserver(NotNull()))
-      .InSequence(s)
-      .WillOnce(SaveArg<0>(&registered_observer));
-  EXPECT_CALL(provider, RemoveObserver(Eq(ByRef(registered_observer))))
-      .InSequence(s);
-  GLScaler scaler(&provider);
-}
-
-TEST_F(GLScalerTest, RemovesObserverWhenContextIsLost) {
-  NiceMock<MockContextProvider> provider;
-  ContextLostObserver* registered_observer = nullptr;
-  Sequence s;
-  EXPECT_CALL(provider, AddObserver(NotNull()))
-      .InSequence(s)
-      .WillOnce(SaveArg<0>(&registered_observer));
-  EXPECT_CALL(provider, RemoveObserver(Eq(ByRef(registered_observer))))
-      .InSequence(s);
-  GLScaler scaler(&provider);
-  static_cast<ContextLostObserver&>(scaler).OnContextLost();
-  // Verify RemoveObserver() was called before |scaler| goes out-of-scope.
-  Mock::VerifyAndClearExpectations(&provider);
-}
-
-TEST_F(GLScalerTest, StopsScalingWhenContextIsLost) {
-  GLScaler scaler(context_provider());
-
-  // Configure the scaler with default parameters (1:1 scale ratio).
-  ASSERT_TRUE(scaler.Configure(GLScaler::Parameters()));
-
-  // Call Scale() and expect it to return true to indicate the operation
-  // succeeded.
-  GLScalerTestTextureHelper helper(context_provider()->ContextGL());
-  constexpr gfx::Size kSomeSize = gfx::Size(32, 32);
-  const GLuint src_texture = helper.CreateTexture(kSomeSize);
-  const GLuint dest_texture = helper.CreateTexture(kSomeSize);
-  EXPECT_TRUE(scaler.Scale(src_texture, kSomeSize, gfx::Vector2d(),
-                           dest_texture, gfx::Rect(kSomeSize)));
-
-  // After the context is lost, another call to Scale() should return false.
-  static_cast<ContextLostObserver&>(scaler).OnContextLost();
-  EXPECT_FALSE(scaler.Scale(src_texture, kSomeSize, gfx::Vector2d(),
-                            dest_texture, gfx::Rect(kSomeSize)));
-}
-
-TEST_F(GLScalerTest, Configure_RequiresValidScalingVectors) {
-  GLScaler scaler(context_provider());
-
-  GLScaler::Parameters params;
-  EXPECT_TRUE(scaler.Configure(params));
-
-  for (int i = 0; i < 4; ++i) {
-    params.scale_from = gfx::Vector2d(i == 0 ? 0 : 1, i == 1 ? 0 : 1);
-    params.scale_to = gfx::Vector2d(i == 2 ? 0 : 1, i == 3 ? 0 : 1);
-    EXPECT_FALSE(scaler.Configure(params));
-  }
-}
-
-TEST_F(GLScalerTest, Configure_ResolvesUnspecifiedColorSpaces) {
-  GLScaler scaler(context_provider());
-
-  // Neither source nor output space specified: Both should resolve to sRGB.
-  GLScaler::Parameters params;
-  EXPECT_TRUE(scaler.Configure(params));
-  const auto srgb = gfx::ColorSpace::CreateSRGB();
-  EXPECT_EQ(srgb, scaler.params().source_color_space);
-  EXPECT_EQ(srgb, scaler.params().output_color_space);
-  EXPECT_TRUE(GLScaler::ParametersAreEquivalent(params, scaler.params()));
-
-  // Source space set to XYZD50 with no output space specified: Both should
-  // resolve to XYZD50.
-  const auto xyzd50 = gfx::ColorSpace::CreateXYZD50();
-  params.source_color_space = xyzd50;
-  EXPECT_TRUE(scaler.Configure(params));
-  EXPECT_EQ(xyzd50, scaler.params().source_color_space);
-  EXPECT_EQ(xyzd50, scaler.params().output_color_space);
-  EXPECT_TRUE(GLScaler::ParametersAreEquivalent(params, scaler.params()));
-
-  // Source space set to XYZD50 with output space set to P3D65: Nothing should
-  // change.
-  const auto p3d65 = gfx::ColorSpace::CreateDisplayP3D65();
-  params.output_color_space = p3d65;
-  EXPECT_TRUE(scaler.Configure(params));
-  EXPECT_EQ(xyzd50, scaler.params().source_color_space);
-  EXPECT_EQ(p3d65, scaler.params().output_color_space);
-  EXPECT_TRUE(GLScaler::ParametersAreEquivalent(params, scaler.params()));
-}
-
-TEST_F(GLScalerTest, Configure_RequiresValidSwizzles) {
-  GLScaler scaler(context_provider());
-  GLScaler::Parameters params;
-
-  // Test that all valid combinations work.
-  for (int i = 0; i < 4; ++i) {
-    params.swizzle[0] = (i % 2 == 0) ? GL_RGBA : GL_BGRA_EXT;
-    params.swizzle[1] = (i / 2 == 0) ? GL_RGBA : GL_BGRA_EXT;
-    EXPECT_TRUE(scaler.Configure(params)) << "i=" << i;
-  }
-
-  // Test that invalid combinations don't work.
-  for (int i = 1; i < 4; ++i) {
-    params.swizzle[0] = (i % 2 == 0) ? GL_RGBA : GL_RGB;
-    params.swizzle[1] = (i / 2 == 0) ? GL_RGBA : GL_RGB;
-    EXPECT_FALSE(scaler.Configure(params)) << "i=" << i;
-  }
-}
-
-TEST_F(GLScalerTest, DetectsEquivalentScaleRatios) {
-  GLScaler::Parameters params;
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(params, gfx::Vector2d(1, 1),
-                                                    gfx::Vector2d(1, 1)));
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(15, 15), gfx::Vector2d(15, 15)));
-
-  params.scale_from = gfx::Vector2d(2, 1);
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(params, gfx::Vector2d(2, 1),
-                                                    gfx::Vector2d(1, 1)));
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(30, 15), gfx::Vector2d(15, 15)));
-
-  params.scale_from = gfx::Vector2d(1, 2);
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(params, gfx::Vector2d(1, 2),
-                                                    gfx::Vector2d(1, 1)));
-  EXPECT_TRUE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(15, 30), gfx::Vector2d(15, 15)));
-
-  params.scale_from = gfx::Vector2d(2, 1);
-  EXPECT_FALSE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(1, 2), gfx::Vector2d(1, 1)));
-  EXPECT_FALSE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(15, 30), gfx::Vector2d(15, 15)));
-
-  params.scale_from = gfx::Vector2d(1, 2);
-  EXPECT_FALSE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(2, 1), gfx::Vector2d(1, 1)));
-  EXPECT_FALSE(GLScaler::ParametersHasSameScaleRatio(
-      params, gfx::Vector2d(30, 15), gfx::Vector2d(15, 15)));
-}
-
-}  // namespace
-}  // namespace viz
diff --git a/components/viz/common/switches.cc b/components/viz/common/switches.cc
index e6d3acb..c5cf3aa 100644
--- a/components/viz/common/switches.cc
+++ b/components/viz/common/switches.cc
@@ -29,10 +29,6 @@
 // Also implies --disable-gpu-vsync (see //ui/gl/gl_switches.h).
 const char kDisableFrameRateLimit[] = "disable-frame-rate-limit";
 
-// Slows down animations during a DocumentTransition for debugging.
-const char kDocumentTransitionSlowdownFactor[] =
-    "document-transition-slowdown-factor";
-
 // Sets the number of max pending frames in the GL buffer queue to 1.
 const char kDoubleBufferCompositing[] = "double-buffer-compositing";
 
@@ -87,18 +83,4 @@
   return activation_deadline_in_frames;
 }
 
-int GetDocumentTransitionSlowDownFactor() {
-  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-  if (!command_line ||
-      !command_line->HasSwitch(kDocumentTransitionSlowdownFactor))
-    return 1;
-
-  auto factor_str =
-      command_line->GetSwitchValueASCII(kDocumentTransitionSlowdownFactor);
-  int factor = 0;
-  LOG_IF(ERROR, !base::StringToInt(factor_str, &factor))
-      << "Error parsing document transition slow down factor " << factor_str;
-  return std::max(1, factor);
-}
-
 }  // namespace switches
diff --git a/components/viz/common/switches.h b/components/viz/common/switches.h
index b76565e9..a602615d 100644
--- a/components/viz/common/switches.h
+++ b/components/viz/common/switches.h
@@ -17,7 +17,6 @@
 VIZ_COMMON_EXPORT extern const char kDeJellyScreenWidth[];
 VIZ_COMMON_EXPORT extern const char kDeadlineToSynchronizeSurfaces[];
 VIZ_COMMON_EXPORT extern const char kDisableFrameRateLimit[];
-VIZ_COMMON_EXPORT extern const char kDocumentTransitionSlowdownFactor[];
 VIZ_COMMON_EXPORT extern const char kDoubleBufferCompositing[];
 VIZ_COMMON_EXPORT extern const char kEnableDeJelly[];
 VIZ_COMMON_EXPORT extern const char kEnableHardwareOverlays[];
@@ -33,7 +32,6 @@
 VIZ_COMMON_EXPORT extern const char kShowDCLayerDebugBorders[];
 
 VIZ_COMMON_EXPORT absl::optional<uint32_t> GetDeadlineToSynchronizeSurfaces();
-VIZ_COMMON_EXPORT int GetDocumentTransitionSlowDownFactor();
 
 }  // namespace switches
 
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 68f5395..fe988e3 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -591,14 +591,6 @@
     "transitions/transferable_resource_tracker_unittest.cc",
   ]
 
-  if (enable_gl_renderer_tests) {
-    sources += [
-      "display/gl_renderer_copier_pixeltest.cc",
-      "display/gl_renderer_copier_unittest.cc",
-      "display/gl_renderer_unittest.cc",
-    ]
-  }
-
   if (!use_aura && !is_mac) {
     sources -= [ "display_embedder/buffer_queue_unittest.cc" ]
   }
@@ -690,7 +682,6 @@
   sources = [
     "display/bsp_tree_perftest.cc",
     "display/display_perftest.cc",
-    "display/gl_renderer_copier_perftest.cc",
     "display/renderer_perftest.cc",
     "display/surface_aggregator_perftest.cc",
     "display/viz_perftest.cc",
diff --git a/components/viz/service/display/gl_renderer_copier_perftest.cc b/components/viz/service/display/gl_renderer_copier_perftest.cc
deleted file mode 100644
index 853f61e..0000000
--- a/components/viz/service/display/gl_renderer_copier_perftest.cc
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/raw_ptr.h"
-#include "components/viz/service/display/gl_renderer_copier.h"
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/timer/lap_timer.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/common/frame_sinks/copy_output_result.h"
-#include "components/viz/common/frame_sinks/copy_output_util.h"
-#include "components/viz/service/display/gl_renderer.h"
-#include "components/viz/test/paths.h"
-#include "components/viz/test/test_in_process_context_provider.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_result_reporter.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace viz {
-
-namespace {
-
-// The size of the source texture or framebuffer.
-constexpr gfx::Size kSourceSize = gfx::Size(240, 120);
-
-// In order to test coordinate calculations and Y-flipping, the tests will issue
-// copy requests for a small region just to the right and below the center of
-// the entire source texture/framebuffer.
-constexpr gfx::Rect kRequestArea = gfx::Rect(kSourceSize.width() / 2,
-                                             kSourceSize.height() / 2,
-                                             kSourceSize.width() / 4,
-                                             kSourceSize.height() / 4);
-
-constexpr char kMetricPrefixGLRendererCopier[] = "GLRendererCopier.";
-constexpr char kMetricReadbackThroughputRunsPerS[] = "readback_throughput";
-
-perf_test::PerfResultReporter SetUpGLRendererCopierReporter(
-    const std::string& story) {
-  perf_test::PerfResultReporter reporter(kMetricPrefixGLRendererCopier, story);
-  reporter.RegisterImportantMetric(kMetricReadbackThroughputRunsPerS, "runs/s");
-  return reporter;
-}
-
-base::FilePath GetTestFilePath(const base::FilePath::CharType* basename) {
-  base::FilePath test_dir;
-  base::PathService::Get(Paths::DIR_TEST_DATA, &test_dir);
-  return test_dir.Append(base::FilePath(basename));
-}
-
-}  // namespace
-
-class GLRendererCopierPerfTest : public testing::Test {
- public:
-  GLRendererCopierPerfTest() {
-    context_provider_ = base::MakeRefCounted<TestInProcessContextProvider>(
-        TestContextType::kGLES2, /*support_locking=*/false);
-    gpu::ContextResult result = context_provider_->BindToCurrentThread();
-    DCHECK_EQ(result, gpu::ContextResult::kSuccess);
-    gl_ = context_provider_->ContextGL();
-    texture_deleter_ =
-        std::make_unique<TextureDeleter>(base::ThreadTaskRunnerHandle::Get());
-    copier_ = std::make_unique<GLRendererCopier>(context_provider_.get(),
-                                                 texture_deleter_.get());
-  }
-
-  GLRendererCopierPerfTest(const GLRendererCopierPerfTest&) = delete;
-  GLRendererCopierPerfTest& operator=(const GLRendererCopierPerfTest&) = delete;
-
-  void TearDown() override {
-    DeleteSourceFramebuffer();
-    DeleteSourceTexture();
-    copier_.reset();
-    texture_deleter_.reset();
-  }
-
-  gfx::Rect DrawToWindowSpace(const gfx::Rect& draw_rect, bool flipped_source) {
-    gfx::Rect window_rect = draw_rect;
-    if (flipped_source)
-      window_rect.set_y(kSourceSize.height() - window_rect.bottom());
-    return window_rect;
-  }
-
-  // Creates a packed RGBA (bytes_per_pixel=4) bitmap in OpenGL byte/row order
-  // from the given SkBitmap.
-  std::unique_ptr<uint8_t[]> CreateGLPixelsFromSkBitmap(SkBitmap bitmap,
-                                                        bool flipped_source) {
-    // |bitmap| could be of any color type (and is usually BGRA). Convert it to
-    // a RGBA bitmap in the GL byte order.
-    SkBitmap rgba_bitmap;
-    rgba_bitmap.allocPixels(SkImageInfo::Make(bitmap.width(), bitmap.height(),
-                                              kRGBA_8888_SkColorType,
-                                              kPremul_SkAlphaType));
-    SkPixmap pixmap;
-    const bool success =
-        bitmap.peekPixels(&pixmap) && rgba_bitmap.writePixels(pixmap, 0, 0);
-    CHECK(success);
-
-    // Copy the RGBA bitmap into a raw byte array, reversing the row order and
-    // maybe stripping-out the alpha channel.
-    const int bytes_per_pixel = 4;
-    std::unique_ptr<uint8_t[]> pixels(
-        new uint8_t[rgba_bitmap.width() * rgba_bitmap.height() *
-                    bytes_per_pixel]);
-    for (int y = 0; y < rgba_bitmap.height(); ++y) {
-      const uint8_t* src = static_cast<uint8_t*>(rgba_bitmap.getAddr(0, y));
-      const int flipped_y = flipped_source ? rgba_bitmap.height() - y - 1 : y;
-      uint8_t* dest =
-          pixels.get() + flipped_y * rgba_bitmap.width() * bytes_per_pixel;
-      for (int x = 0; x < rgba_bitmap.width(); ++x) {
-        *(dest++) = *(src++);
-        *(dest++) = *(src++);
-        *(dest++) = *(src++);
-        if (bytes_per_pixel == 4)
-          *(dest++) = *(src++);
-        else
-          ++src;
-      }
-    }
-
-    return pixels;
-  }
-
-  GLuint CreateSourceTexture(bool flipped_source) {
-    CHECK_EQ(0u, source_texture_);
-    SkBitmap source_bitmap;
-    cc::ReadPNGFile(GetTestFilePath(FILE_PATH_LITERAL("16_color_rects.png")),
-                    &source_bitmap);
-    source_bitmap.setImmutable();
-    gl_->GenTextures(1, &source_texture_);
-    gl_->BindTexture(GL_TEXTURE_2D, source_texture_);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    gl_->TexImage2D(
-        GL_TEXTURE_2D, 0, static_cast<GLenum>(GL_RGBA), kSourceSize.width(),
-        kSourceSize.height(), 0, static_cast<GLenum>(GL_RGBA), GL_UNSIGNED_BYTE,
-        CreateGLPixelsFromSkBitmap(source_bitmap, flipped_source).get());
-    gl_->BindTexture(GL_TEXTURE_2D, 0);
-    return source_texture_;
-  }
-
-  void DeleteSourceTexture() {
-    if (source_texture_ != 0) {
-      gl_->DeleteTextures(1, &source_texture_);
-      source_texture_ = 0;
-    }
-  }
-
-  void CreateAndBindSourceFramebuffer(GLuint texture) {
-    ASSERT_EQ(0u, source_framebuffer_);
-    gl_->GenFramebuffers(1, &source_framebuffer_);
-    gl_->BindFramebuffer(GL_FRAMEBUFFER, source_framebuffer_);
-    gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                              GL_TEXTURE_2D, texture, 0);
-  }
-
-  void DeleteSourceFramebuffer() {
-    if (source_framebuffer_ != 0) {
-      gl_->DeleteFramebuffers(1, &source_framebuffer_);
-      source_framebuffer_ = 0;
-    }
-  }
-
-  void CopyFromTextureOrFramebuffer(
-      bool have_source_texture,
-      CopyOutputResult::Format result_format,
-      CopyOutputResult::Destination result_destination,
-      bool scale_by_half,
-      bool flipped_source,
-      const std::string& story) {
-    std::unique_ptr<CopyOutputResult> result;
-
-    gfx::Rect result_selection(kRequestArea);
-    if (scale_by_half)
-      result_selection = gfx::ScaleToEnclosingRect(result_selection, 0.5f);
-
-    copy_output::RenderPassGeometry geometry;
-    // geometry.result_bounds not used by GLRendererCopier
-    geometry.sampling_bounds =
-        DrawToWindowSpace(gfx::Rect(kSourceSize), flipped_source);
-    geometry.result_selection = result_selection;
-    geometry.readback_offset =
-        DrawToWindowSpace(geometry.result_selection, flipped_source)
-            .OffsetFromOrigin();
-
-    timer_.Reset();
-    do {
-      base::RunLoop loop;
-      auto request = std::make_unique<CopyOutputRequest>(
-          result_format, result_destination,
-          base::BindOnce(
-              [](std::unique_ptr<CopyOutputResult>* result,
-                 base::OnceClosure quit_closure,
-                 std::unique_ptr<CopyOutputResult> result_from_copier) {
-                *result = std::move(result_from_copier);
-                std::move(quit_closure).Run();
-              },
-              &result, loop.QuitClosure()));
-      if (scale_by_half)
-        request->SetUniformScaleRatio(2, 1);
-      const GLuint source_texture = CreateSourceTexture(flipped_source);
-      CreateAndBindSourceFramebuffer(source_texture);
-
-      copier_->CopyFromTextureOrFramebuffer(
-          std::move(request), geometry, static_cast<GLenum>(GL_RGBA),
-          have_source_texture ? source_texture : 0, kSourceSize, flipped_source,
-          gfx::ColorSpace::CreateSRGB());
-      loop.Run();
-
-      // Check that a result was produced and is of the expected rect/size.
-      ASSERT_TRUE(result);
-      ASSERT_FALSE(result->IsEmpty());
-      if (scale_by_half)
-        ASSERT_EQ(gfx::ScaleToEnclosingRect(kRequestArea, 0.5f),
-                  result->rect());
-      else
-        ASSERT_EQ(kRequestArea, result->rect());
-
-      if (result_format == CopyOutputResult::Format::RGBA &&
-          result_destination == CopyOutputResult::Destination::kSystemMemory) {
-        auto scoped_bitmap = result->ScopedAccessSkBitmap();
-        const SkBitmap& result_bitmap = scoped_bitmap.bitmap();
-        ASSERT_TRUE(result_bitmap.readyToDraw());
-      } else if (result_format == CopyOutputResult::Format::I420_PLANES) {
-        const int result_width = result->rect().width();
-        const int result_height = result->rect().height();
-        const int y_width = result_width;
-        const int y_stride = y_width;
-        std::unique_ptr<uint8_t[]> y_data(
-            new uint8_t[y_stride * result_height]);
-        const int chroma_width = (result_width + 1) / 2;
-        const int u_stride = chroma_width;
-        const int v_stride = chroma_width;
-        const int chroma_height = (result_height + 1) / 2;
-        std::unique_ptr<uint8_t[]> u_data(
-            new uint8_t[u_stride * chroma_height]);
-        std::unique_ptr<uint8_t[]> v_data(
-            new uint8_t[v_stride * chroma_height]);
-
-        const bool success =
-            result->ReadI420Planes(y_data.get(), y_stride, u_data.get(),
-                                   u_stride, v_data.get(), v_stride);
-        ASSERT_TRUE(success);
-      }
-
-      DeleteSourceFramebuffer();
-      DeleteSourceTexture();
-      timer_.NextLap();
-    } while (!timer_.HasTimeLimitExpired());
-
-    auto reporter = SetUpGLRendererCopierReporter(story);
-    reporter.AddResult(kMetricReadbackThroughputRunsPerS,
-                       timer_.LapsPerSecond());
-  }
-
- private:
-  raw_ptr<gpu::gles2::GLES2Interface> gl_ = nullptr;
-  scoped_refptr<TestInProcessContextProvider> context_provider_;
-  std::unique_ptr<TextureDeleter> texture_deleter_;
-  std::unique_ptr<GLRendererCopier> copier_;
-  GLuint source_texture_ = 0;
-  GLuint source_framebuffer_ = 0;
-  base::LapTimer timer_;
-};
-
-// Fast-Path: If no transformation is necessary and no new textures need to be
-// generated, read-back directly from the currently-bound framebuffer.
-TEST_F(GLRendererCopierPerfTest, NoTransformNoNewTextures) {
-  CopyFromTextureOrFramebuffer(
-      /*have_source_texture=*/false, CopyOutputResult::Format::RGBA,
-      CopyOutputResult::Destination::kSystemMemory,
-      /*scale_by_half=*/false, /*flipped_source=*/false,
-      "no_transformation_and_no_new_textures");
-}
-
-// Source texture is the one attached to the framebuffer, better performance
-// than having to make a copy of the framebuffer.
-TEST_F(GLRendererCopierPerfTest, HaveTextureResultRGBABitmap) {
-  CopyFromTextureOrFramebuffer(
-      /*have_source_texture=*/true, CopyOutputResult::Format::RGBA,
-      CopyOutputResult::Destination::kSystemMemory,
-      /*scale_by_half=*/true, /*flipped_source=*/false,
-      "framebuffer_has_texture_and_result_is_RGBA_BITMAP");
-}
-TEST_F(GLRendererCopierPerfTest, HaveTextureResultRGBATexture) {
-  CopyFromTextureOrFramebuffer(
-      /*have_source_texture=*/true, CopyOutputResult::Format::RGBA,
-      CopyOutputResult::Destination::kNativeTextures,
-      /*scale_by_half=*/true, /*flipped_source=*/false,
-      "framebuffer_has_texture_and_result_is_RGBA_TEXTURE");
-}
-TEST_F(GLRendererCopierPerfTest, HaveTextureResultI420Planes) {
-  CopyFromTextureOrFramebuffer(
-      /*have_source_texture=*/true, CopyOutputResult::Format::I420_PLANES,
-      CopyOutputResult::Destination::kSystemMemory,
-      /*scale_by_half=*/true, /*flipped_source=*/false,
-      "framebuffer_has_texture_and_result_is_I420_PLANES");
-}
-
-// Have to make a copy of the framebuffer for the source texture.
-TEST_F(GLRendererCopierPerfTest, NoTextureResultI420Planes) {
-  CopyFromTextureOrFramebuffer(
-      /*have_source_texture=*/false, CopyOutputResult::Format::I420_PLANES,
-      CopyOutputResult::Destination::kSystemMemory,
-      /*scale_by_half=*/true, /*flipped_source=*/false,
-      "framebuffer_doesn't_have_texture_and_result_is_I420_PLANES");
-}
-
-// Source content is vertically flipped.
-TEST_F(GLRendererCopierPerfTest, SourceContentVerticallyFlipped) {
-  CopyFromTextureOrFramebuffer(/*have_source_texture=*/true,
-                               CopyOutputResult::Format::I420_PLANES,
-                               CopyOutputResult::Destination::kSystemMemory,
-                               /*scale_by_half=*/true, /*flipped_source=*/true,
-                               "source_content_is_vertically_flipped");
-}
-
-// Result is not scaled by half.
-TEST_F(GLRendererCopierPerfTest, ResultNotScaled) {
-  CopyFromTextureOrFramebuffer(/*have_source_texture=*/true,
-                               CopyOutputResult::Format::I420_PLANES,
-                               CopyOutputResult::Destination::kSystemMemory,
-                               /*scale_by_half=*/false, /*flipped_source=*/true,
-                               "result_is_not_scaled_by_half");
-}
-
-}  // namespace viz
diff --git a/components/viz/service/display/gl_renderer_copier_pixeltest.cc b/components/viz/service/display/gl_renderer_copier_pixeltest.cc
deleted file mode 100644
index 0f72f75..0000000
--- a/components/viz/service/display/gl_renderer_copier_pixeltest.cc
+++ /dev/null
@@ -1,958 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display/gl_renderer_copier.h"
-
-#include <stdint.h>
-
-#include <cstring>
-#include <memory>
-#include <tuple>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "base/test/test_switches.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/pixel_test_utils.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/common/frame_sinks/copy_output_result.h"
-#include "components/viz/common/frame_sinks/copy_output_util.h"
-#include "components/viz/service/display/gl_renderer.h"
-#include "components/viz/test/gl_scaler_test_util.h"
-#include "components/viz/test/paths.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libyuv/include/libyuv/convert_argb.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
-#include "third_party/skia/include/core/SkPixmap.h"
-#include "ui/gfx/color_space.h"
-#include "ui/gfx/color_transform.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include "base/android/build_info.h"
-#endif
-
-namespace viz {
-
-namespace {
-
-base::FilePath GetTestFilePath(const base::FilePath::CharType* basename) {
-  base::FilePath test_dir;
-  base::PathService::Get(Paths::DIR_TEST_DATA, &test_dir);
-  return test_dir.Append(base::FilePath(basename));
-}
-
-// Creates a packed RGBA (bytes_per_pixel=4) or RGB (bytes_per_pixel=3) bitmap
-// in OpenGL byte/row order from the given SkBitmap.
-std::unique_ptr<uint8_t[]> CreateGLPixelsFromSkBitmap(SkBitmap bitmap,
-                                                      GLuint source_format,
-                                                      bool flip_source) {
-  // |bitmap| could be of any color type (and is usually BGRA). Convert it to
-  // a RGBA bitmap in the GL byte order.
-  SkBitmap rgba_bitmap;
-  rgba_bitmap.allocPixels(SkImageInfo::Make(bitmap.width(), bitmap.height(),
-                                            kRGBA_8888_SkColorType,
-                                            kPremul_SkAlphaType));
-  SkPixmap pixmap;
-  const bool success =
-      bitmap.peekPixels(&pixmap) && rgba_bitmap.writePixels(pixmap, 0, 0);
-  CHECK(success);
-
-  // Copy the RGBA bitmap into a raw byte array, reversing the row order and
-  // maybe stripping-out the alpha channel.
-  const int bytes_per_pixel = source_format == GL_RGBA ? 4 : 3;
-  std::unique_ptr<uint8_t[]> pixels(
-      new uint8_t[rgba_bitmap.width() * rgba_bitmap.height() *
-                  bytes_per_pixel]);
-  for (int y = 0; y < rgba_bitmap.height(); ++y) {
-    const uint8_t* src = static_cast<uint8_t*>(rgba_bitmap.getAddr(0, y));
-    const int flipped_y = flip_source ? rgba_bitmap.height() - y - 1 : y;
-    uint8_t* dest =
-        pixels.get() + flipped_y * rgba_bitmap.width() * bytes_per_pixel;
-    for (int x = 0; x < rgba_bitmap.width(); ++x) {
-      *(dest++) = *(src++);
-      *(dest++) = *(src++);
-      *(dest++) = *(src++);
-      if (bytes_per_pixel == 4)
-        *(dest++) = *(src++);
-      else
-        ++src;
-    }
-  }
-
-  return pixels;
-}
-
-// Returns a SkBitmap, given a packed RGBA bitmap in OpenGL byte/row order.
-SkBitmap CreateSkBitmapFromGLPixels(const uint8_t* pixels,
-                                    const gfx::Size& size) {
-  SkBitmap bitmap;
-  bitmap.allocPixels(
-      SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
-                        kPremul_SkAlphaType),
-      size.width() * 4);
-  for (int y = 0; y < size.height(); ++y) {
-    const int flipped_y = size.height() - y - 1;
-    const uint8_t* const src_row = pixels + flipped_y * size.width() * 4;
-    void* const dest_row = bitmap.getAddr(0, y);
-    std::memcpy(dest_row, src_row, size.width() * 4);
-  }
-  return bitmap;
-}
-
-// Reads back the texture in the given |mailbox| to a SkBitmap in Skia-native
-// format.
-SkBitmap ReadbackToSkBitmap(gpu::gles2::GLES2Interface* gl,
-                            const gpu::Mailbox& mailbox,
-                            const gpu::SyncToken& sync_token,
-                            const gfx::Size& texture_size) {
-  // Bind the texture to a framebuffer from which to read the pixels.
-  if (sync_token.HasData())
-    gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
-  GLuint texture = gl->CreateAndConsumeTextureCHROMIUM(mailbox.name);
-  GLuint framebuffer = 0;
-  gl->GenFramebuffers(1, &framebuffer);
-  gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-  gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                           texture, 0);
-
-  // Read the pixels and convert to SkBitmap form for test comparisons.
-  std::unique_ptr<uint8_t[]> pixels(new uint8_t[texture_size.GetArea() * 4]);
-  gl->ReadPixels(0, 0, texture_size.width(), texture_size.height(), GL_RGBA,
-                 GL_UNSIGNED_BYTE, pixels.get());
-  gl->DeleteFramebuffers(1, &framebuffer);
-  gl->DeleteTextures(1, &texture);
-  return CreateSkBitmapFromGLPixels(pixels.get(), texture_size);
-}
-
-// Validates whether all rows are identical (i.e. for each row r != 0, compares
-// it with row 0.
-void ValidateRows(uint8_t* pixel_data, size_t row_stride, size_t height) {
-  for (size_t row = 1; row < height; ++row) {
-    for (size_t col = 0; col < row_stride; ++col) {
-      EXPECT_NEAR(pixel_data[col], pixel_data[col + row * row_stride], 1)
-          << " mismatch in row " << row << ", column " << col;
-    }
-  }
-}
-
-// Returns maximum allowed difference between the expected and actual pixel
-// values.
-int GetTolerance() {
-  return 1;
-}
-
-}  // namespace
-
-//
-// All tests in this class follow roughly the same pattern::
-// - Construct a CopyOutputRequest, with arguments depending on the test
-//   parameters and the specific format that is being tested.
-// - Upload source texture to GL.
-// - Invoke GLRendererCopier::CopyFromTextureOrFramebuffer(), with arguments
-//   depending on the test parameters, passing the created CopyOutputRequest.
-// - Load the result into memory and compare with baseline.
-//
-// Parameters:
-// 0. GL format to use when uploading source texture.
-// 1. True if the copier will also receive the texture in a call to
-//    `CopyFromTextureOrFramebuffer()`, false otherwise.
-// 2. Destiation for the CopyOutputRequest (native textures or system memory).
-// 3. True if the result should be scaled by half in each dimension, false
-//    otherwise.
-// 4. True if the source texture will be flipped (bottom-up), false otherwise.
-class GLRendererCopierPixelTest
-    : public cc::PixelTest,
-      public testing::WithParamInterface<
-          std::tuple<GLenum, bool, CopyOutputResult::Destination, bool, bool>> {
- public:
-  // In order to test coordinate calculations and Y-flipping, the tests will
-  // issue copy requests for a small region just to the right and below the
-  // center of the entire source texture/framebuffer.
-  gfx::Rect GetRequestArea() const {
-    DCHECK(!source_size_.IsZero());
-
-    gfx::Rect result(source_size_.width() / 2, source_size_.height() / 2,
-                     source_size_.width() / 4, source_size_.height() / 4);
-
-    if (scale_by_half_) {
-      return gfx::ScaleToEnclosingRect(result, 0.5f);
-    }
-
-    return result;
-  }
-
-  void SetUp() override {
-    SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-
-    texture_deleter_ =
-        std::make_unique<TextureDeleter>(base::ThreadTaskRunnerHandle::Get());
-
-    source_gl_format_ = std::get<0>(GetParam());
-    have_source_texture_ = std::get<1>(GetParam());
-    result_destination_ = std::get<2>(GetParam());
-    scale_by_half_ = std::get<3>(GetParam());
-    flipped_source_ = std::get<4>(GetParam());
-
-    gl_ = context_provider()->ContextGL();
-    copier_ = std::make_unique<GLRendererCopier>(context_provider(),
-                                                 texture_deleter_.get());
-
-    ASSERT_TRUE(cc::ReadPNGFile(
-        GetTestFilePath(FILE_PATH_LITERAL("16_color_rects.png")),
-        &source_bitmap_));
-    source_bitmap_.setImmutable();
-
-    source_size_ = gfx::Size(source_bitmap_.width(), source_bitmap_.height());
-
-    source_bitmap_rgba_ =
-        GLScalerTestUtil::CopyAndConvertToRGBA(source_bitmap_);
-    source_bitmap_rgba_.setImmutable();
-
-    source_bitmap_yuv_ = source_bitmap_rgba_;
-    GLScalerTestUtil::ConvertRGBABitmapToYUV(&source_bitmap_yuv_);
-    source_bitmap_yuv_.setImmutable();
-  }
-
-  void TearDown() override {
-    DeleteSourceFramebuffer();
-    DeleteSourceTexture();
-    copier_.reset();
-    texture_deleter_.reset();
-  }
-
-  gpu::gles2::GLES2Interface* gl() { return gl_; }
-
-  GLRendererCopier* copier() { return copier_.get(); }
-
-  gfx::Rect DrawToWindowSpace(const gfx::Size& source_size,
-                              const gfx::Rect& draw_rect) {
-    gfx::Rect window_rect = draw_rect;
-    if (flipped_source_)
-      window_rect.set_y(source_size.height() - window_rect.bottom());
-    return window_rect;
-  }
-
-  GLuint CreateSourceTexture(SkBitmap source_bitmap) {
-    CHECK_EQ(0u, source_texture_);
-    gl_->GenTextures(1, &source_texture_);
-    gl_->BindTexture(GL_TEXTURE_2D, source_texture_);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    gl_->TexImage2D(GL_TEXTURE_2D, 0, source_gl_format_, source_bitmap.width(),
-                    source_bitmap.height(), 0, source_gl_format_,
-                    GL_UNSIGNED_BYTE,
-                    CreateGLPixelsFromSkBitmap(source_bitmap, source_gl_format_,
-                                               flipped_source_)
-                        .get());
-    gl_->BindTexture(GL_TEXTURE_2D, 0);
-    return source_texture_;
-  }
-
-  void DeleteSourceTexture() {
-    if (source_texture_ != 0) {
-      gl_->DeleteTextures(1, &source_texture_);
-      source_texture_ = 0;
-    }
-  }
-
-  void CreateAndBindSourceFramebuffer(GLuint texture) {
-    ASSERT_EQ(0u, source_framebuffer_);
-    gl_->GenFramebuffers(1, &source_framebuffer_);
-    gl_->BindFramebuffer(GL_FRAMEBUFFER, source_framebuffer_);
-    gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                              GL_TEXTURE_2D, texture, 0);
-  }
-
-  void DeleteSourceFramebuffer() {
-    if (source_framebuffer_ != 0) {
-      gl_->DeleteFramebuffers(1, &source_framebuffer_);
-      source_framebuffer_ = 0;
-    }
-  }
-
- protected:
-  // The size of the source texture or framebuffer.
-  gfx::Size source_size_;
-
-  GLenum source_gl_format_;
-  bool have_source_texture_;
-  CopyOutputResult::Destination result_destination_;
-  bool scale_by_half_;
-  bool flipped_source_;
-  SkBitmap source_bitmap_;
-  SkBitmap source_bitmap_rgba_;
-  SkBitmap source_bitmap_yuv_;
-
- private:
-  gpu::gles2::GLES2Interface* gl_ = nullptr;
-  std::unique_ptr<TextureDeleter> texture_deleter_;
-  std::unique_ptr<GLRendererCopier> copier_;
-  GLuint source_texture_ = 0;
-  GLuint source_framebuffer_ = 0;
-};
-
-// On Android KitKat bots (but not newer ones), the left column of pixels in the
-// result is off-by-one in the red channel. Use the off-by-one camparator as a
-// workaround.
-#if BUILDFLAG(IS_ANDROID)
-#define PIXEL_COMPARATOR() cc::FuzzyPixelOffByOneComparator(false)
-#else
-#define PIXEL_COMPARATOR() cc::ExactPixelComparator(false)
-#endif
-
-TEST_P(GLRendererCopierPixelTest, ExecutesCopyRequestRGBA) {
-  // Create and execute a CopyOutputRequest via the GLRendererCopier.
-  std::unique_ptr<CopyOutputResult> result;
-  {
-    base::RunLoop loop;
-    auto request = std::make_unique<CopyOutputRequest>(
-        CopyOutputRequest::ResultFormat::RGBA, result_destination_,
-        base::BindOnce(
-            [](std::unique_ptr<CopyOutputResult>* result,
-               base::OnceClosure quit_closure,
-               std::unique_ptr<CopyOutputResult> result_from_copier) {
-              *result = std::move(result_from_copier);
-              std::move(quit_closure).Run();
-            },
-            &result, loop.QuitClosure()));
-    if (scale_by_half_) {
-      request->SetUniformScaleRatio(2, 1);
-    }
-
-    request->set_result_selection(GetRequestArea());
-
-    const GLuint source_texture = CreateSourceTexture(source_bitmap_);
-    CreateAndBindSourceFramebuffer(source_texture);
-
-    copy_output::RenderPassGeometry geometry;
-    // geometry.result_bounds not used by GLRendererCopier
-    geometry.sampling_bounds =
-        DrawToWindowSpace(source_size_, gfx::Rect(source_size_));
-    geometry.result_selection = request->result_selection();
-    geometry.readback_offset =
-        DrawToWindowSpace(source_size_, geometry.result_selection)
-            .OffsetFromOrigin();
-
-    copier()->CopyFromTextureOrFramebuffer(
-        std::move(request), geometry, source_gl_format_,
-        have_source_texture_ ? source_texture : 0, source_size_,
-        flipped_source_, gfx::ColorSpace::CreateSRGB());
-    loop.Run();
-  }
-
-  // Check that a result was produced and is of the expected rect/size.
-  ASSERT_TRUE(result);
-  ASSERT_FALSE(result->IsEmpty());
-  ASSERT_EQ(GetRequestArea(), result->rect());
-
-  // Examine the image in the |result|, and compare it to the baseline PNG file.
-  absl::optional<CopyOutputResult::ScopedSkBitmap> scoped_bitmap;
-  SkBitmap actual;
-  if (result_destination_ == CopyOutputResult::Destination::kSystemMemory) {
-    scoped_bitmap = result->ScopedAccessSkBitmap();
-    actual = scoped_bitmap->bitmap();
-  } else {
-    actual = ReadbackToSkBitmap(
-        gl(), result->GetTextureResult()->planes[0].mailbox,
-        result->GetTextureResult()->planes[0].sync_token, result->size());
-  }
-  const auto png_file_path = GetTestFilePath(
-      scale_by_half_ ? FILE_PATH_LITERAL("half_of_one_of_16_color_rects.png")
-                     : FILE_PATH_LITERAL("one_of_16_color_rects.png"));
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRebaselinePixelTests))
-    EXPECT_TRUE(cc::WritePNGFile(actual, png_file_path, false));
-  if (!cc::MatchesPNGFile(actual, png_file_path, PIXEL_COMPARATOR())) {
-    LOG(ERROR) << "Entire source: " << cc::GetPNGDataUrl(source_bitmap_);
-    ADD_FAILURE();
-  }
-}
-
-TEST_P(GLRendererCopierPixelTest, ExecutesCopyRequestNV12) {
-  if (result_destination_ ==
-      CopyOutputRequest::ResultDestination::kNativeTextures) {
-    // TODO(https://crbug.com/1216287): Enable once textures are supported.
-    GTEST_SKIP()
-        << "Enable once the GLRenderer supports producing producing results to "
-           "a texture for NV12 format.";
-  }
-
-  const gfx::Rect request_area = GetRequestArea();
-
-  // Check if request's width and height are even (required for NV12 format).
-  // The test case expects the result size to match the request size exactly,
-  // which is not possible with NV12 when the request size dimensions aren't
-  // even.
-  ASSERT_TRUE(request_area.width() % 2 == 0 && request_area.height() % 2 == 0)
-      << " request size is not even, request_area.size()="
-      << request_area.size().ToString();
-
-  // Additionally, the test uses helpers that assume pixel data can be packed (4
-  // 8-bit values in 1 32-bit pixel).
-  ASSERT_TRUE(request_area.width() % 4 == 0)
-      << " request width is not divisible by 4, request_area.width()="
-      << request_area.width();
-
-  // Create and execute a CopyOutputRequest via the GLRendererCopier.
-  std::unique_ptr<CopyOutputResult> result;
-  {
-    base::RunLoop loop;
-    auto request = std::make_unique<CopyOutputRequest>(
-        CopyOutputRequest::ResultFormat::NV12_PLANES, result_destination_,
-        base::BindOnce(
-            [](std::unique_ptr<CopyOutputResult>* result,
-               base::OnceClosure quit_closure,
-               std::unique_ptr<CopyOutputResult> result_from_copier) {
-              *result = std::move(result_from_copier);
-              std::move(quit_closure).Run();
-            },
-            &result, loop.QuitClosure()));
-    if (scale_by_half_) {
-      request->SetUniformScaleRatio(2, 1);
-    }
-
-    request->set_result_selection(request_area);
-
-    // Upload source texture to GL - the texture will be converted to RGBA if
-    // necessary.
-    const GLuint source_texture = CreateSourceTexture(source_bitmap_);
-    CreateAndBindSourceFramebuffer(source_texture);
-
-    copy_output::RenderPassGeometry geometry;
-    // geometry.result_bounds not used by GLRendererCopier
-    geometry.sampling_bounds =
-        DrawToWindowSpace(source_size_, gfx::Rect(source_size_));
-    geometry.result_selection = request->result_selection();
-    geometry.readback_offset =
-        DrawToWindowSpace(source_size_, geometry.result_selection)
-            .OffsetFromOrigin();
-
-    copier()->CopyFromTextureOrFramebuffer(
-        std::move(request), geometry, source_gl_format_,
-        have_source_texture_ ? source_texture : 0, source_size_,
-        flipped_source_, gfx::ColorSpace::CreateSRGB());
-    loop.Run();
-  }
-
-  // Check that a result was produced and is of the expected rect/size.
-  ASSERT_TRUE(result);
-  ASSERT_FALSE(result->IsEmpty());
-  ASSERT_EQ(request_area, result->rect());
-
-  // Examine the image in the |result|, and compare it to the baseline PNG file.
-  // Approach is the same as the one in GLNV12ConverterPixelTest.
-
-  // Allocate new bitmap, it will then be populated with Y & UV data.
-  SkBitmap actual = GLScalerTestUtil::AllocateRGBABitmap(result->size());
-  actual.eraseColor(SkColorSetARGB(0xff, 0x00, 0x00, 0x00));
-
-  SkBitmap luma_plane;
-  SkBitmap chroma_planes;
-
-  if (result_destination_ == CopyOutputResult::Destination::kSystemMemory) {
-    // Create a bitmap with packed Y values:
-    luma_plane = GLScalerTestUtil::AllocateRGBABitmap(
-        gfx::Size(result->size().width() / 4, result->size().height()));
-
-    chroma_planes = GLScalerTestUtil::AllocateRGBABitmap(
-        gfx::Size(luma_plane.width(), luma_plane.height() / 2));
-
-    result->ReadNV12Planes(
-        reinterpret_cast<uint8_t*>(luma_plane.getAddr(0, 0)),
-        result->size().width(),
-        reinterpret_cast<uint8_t*>(chroma_planes.getAddr(0, 0)),
-        result->size().width());
-  } else {
-    LOG(ERROR) << "Texture results for NV12 are not supported yet!";
-    ADD_FAILURE();
-  }
-
-  GLScalerTestUtil::UnpackPlanarBitmap(luma_plane, 0, &actual);
-  GLScalerTestUtil::UnpackUVBitmap(chroma_planes, &actual);
-
-  const auto png_file_path = GetTestFilePath(
-      scale_by_half_ ? FILE_PATH_LITERAL("half_of_one_of_16_color_rects.png")
-                     : FILE_PATH_LITERAL("one_of_16_color_rects.png"));
-
-  SkBitmap expected;
-  if (!cc::ReadPNGFile(png_file_path, &expected)) {
-    LOG(ERROR) << "Cannot read reference image: " << png_file_path.value();
-    ADD_FAILURE();
-    return;
-  }
-
-  expected = GLScalerTestUtil::CopyAndConvertToRGBA(expected);
-  GLScalerTestUtil::ConvertRGBABitmapToYUV(&expected);
-
-  constexpr float kAvgAbsoluteErrorLimit = 16.f;
-  constexpr int kMaxAbsoluteErrorLimit = 0x80;
-  if (!cc::MatchesBitmap(
-          actual, expected,
-          cc::FuzzyPixelComparator(false, 100.f, 0.f, kAvgAbsoluteErrorLimit,
-                                   kMaxAbsoluteErrorLimit, 0))) {
-    ADD_FAILURE();
-    return;
-  }
-}
-
-#undef PIXEL_COMPARATOR
-
-// These tests work similarly to `GLRendererCopierPixelTest`, but test various
-// request dimensions in more depth.
-//
-// Parameters:
-// 0. Destiation for the CopyOutputRequest (native textures or system memory).
-// 1. True if the result should be scaled by half in each dimension, false
-//    otherwise.
-// 2. True if the request should specify odd coordinates for the result
-//    selection rectangle, false otherwise.
-// 3. True if the request should specify odd dimensions for the result selection
-//    rectangle, false otherwise.
-class GLRendererCopierDimensionsPixelTest
-    : public cc::PixelTest,
-      public testing::WithParamInterface<
-          std::tuple<CopyOutputResult::Destination, bool, bool>> {
- public:
-  void SetUp() override {
-    SetUpGLWithoutRenderer(gfx::SurfaceOrigin::kBottomLeft);
-
-    texture_deleter_ =
-        std::make_unique<TextureDeleter>(base::ThreadTaskRunnerHandle::Get());
-
-    result_destination_ = std::get<0>(GetParam());
-    scale_by_half_ = std::get<1>(GetParam());
-    use_odd_offset_ = std::get<2>(GetParam());
-
-    gl_ = context_provider()->ContextGL();
-    copier_ = std::make_unique<GLRendererCopier>(context_provider(),
-                                                 texture_deleter_.get());
-
-    // For this test, use a generated bitmap, with 4 groups of 4 pixels each.
-    const std::vector<SkColor> kCycle = {
-        // Red:
-        SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-        SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-        SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-        SkColorSetARGB(0xff, 0xff, 0x00, 0x00),
-        // Green:
-        SkColorSetARGB(0xff, 0x00, 0xff, 0x00),
-        SkColorSetARGB(0xff, 0x00, 0xff, 0x00),
-        SkColorSetARGB(0xff, 0x00, 0xff, 0x00),
-        SkColorSetARGB(0xff, 0x00, 0xff, 0x00),
-        // Blue:
-        SkColorSetARGB(0xff, 0x00, 0x00, 0xff),
-        SkColorSetARGB(0xff, 0x00, 0x00, 0xff),
-        SkColorSetARGB(0xff, 0x00, 0x00, 0xff),
-        SkColorSetARGB(0xff, 0x00, 0x00, 0xff),
-        // White:
-        SkColorSetARGB(0xff, 0xff, 0xff, 0xff),
-        SkColorSetARGB(0xff, 0xff, 0xff, 0xff),
-        SkColorSetARGB(0xff, 0xff, 0xff, 0xff),
-        SkColorSetARGB(0xff, 0xff, 0xff, 0xff),
-    };
-    source_bitmap_ = GLScalerTestUtil::CreateCyclicalTestImage(
-        gfx::Size(800, 600), GLScalerTestUtil::VERTICAL_STRIPES, kCycle, 0);
-    // source_bitmap_.setImmutable();
-    source_bitmap_size_ =
-        gfx::Size(source_bitmap_.width(), source_bitmap_.height());
-  }
-
-  void TearDown() override {
-    DeleteSourceFramebuffer();
-    DeleteSourceTexture();
-    copier_.reset();
-    texture_deleter_.reset();
-  }
-
-  gpu::gles2::GLES2Interface* gl() { return gl_; }
-
-  GLRendererCopier* copier() { return copier_.get(); }
-
-  gfx::Rect DrawToWindowSpace(const gfx::Size& source_size,
-                              const gfx::Rect& draw_rect) {
-    gfx::Rect window_rect = draw_rect;
-    if (flipped_source_)
-      window_rect.set_y(source_size.height() - window_rect.bottom());
-    return window_rect;
-  }
-
-  GLuint CreateSourceTexture(SkBitmap source_bitmap) {
-    CHECK_EQ(0u, source_texture_);
-    gl_->GenTextures(1, &source_texture_);
-    gl_->BindTexture(GL_TEXTURE_2D, source_texture_);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    gl_->TexImage2D(GL_TEXTURE_2D, 0, source_gl_format_, source_bitmap.width(),
-                    source_bitmap.height(), 0, source_gl_format_,
-                    GL_UNSIGNED_BYTE,
-                    CreateGLPixelsFromSkBitmap(source_bitmap, source_gl_format_,
-                                               flipped_source_)
-                        .get());
-    gl_->BindTexture(GL_TEXTURE_2D, 0);
-    return source_texture_;
-  }
-
-  void DeleteSourceTexture() {
-    if (source_texture_ != 0) {
-      gl_->DeleteTextures(1, &source_texture_);
-      source_texture_ = 0;
-    }
-  }
-
-  void CreateAndBindSourceFramebuffer(GLuint texture) {
-    ASSERT_EQ(0u, source_framebuffer_);
-    gl_->GenFramebuffers(1, &source_framebuffer_);
-    gl_->BindFramebuffer(GL_FRAMEBUFFER, source_framebuffer_);
-    gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                              GL_TEXTURE_2D, texture, 0);
-  }
-
-  void DeleteSourceFramebuffer() {
-    if (source_framebuffer_ != 0) {
-      gl_->DeleteFramebuffers(1, &source_framebuffer_);
-      source_framebuffer_ = 0;
-    }
-  }
-
- protected:
-  GLenum source_gl_format_ = GL_RGBA;
-  bool have_source_texture_ = false;
-  CopyOutputResult::Destination result_destination_;
-  bool scale_by_half_;
-  bool flipped_source_ = false;
-  bool use_odd_offset_;
-  SkBitmap source_bitmap_;
-  gfx::Size source_bitmap_size_;
-
- private:
-  gpu::gles2::GLES2Interface* gl_ = nullptr;
-  std::unique_ptr<TextureDeleter> texture_deleter_;
-  std::unique_ptr<GLRendererCopier> copier_;
-  GLuint source_texture_ = 0;
-  GLuint source_framebuffer_ = 0;
-};
-
-TEST_P(GLRendererCopierDimensionsPixelTest, ExecutesCopyRequestNV12) {
-  if (result_destination_ ==
-      CopyOutputRequest::ResultDestination::kNativeTextures) {
-    // TODO(https://crbug.com/1216287): Enable once textures are supported.
-    GTEST_SKIP() << "Enable once the NV12 format supports producing results to "
-                    "a texture.";
-  }
-
-  // Result should contain 1px green strip at the beginning if the offset is
-  // supposed to be odd.
-  const gfx::Rect request_area = [this]() {
-    // Capture 2x2 or 4x4 blue strip fragment, depending on scaling.
-    gfx::Rect result =
-        scale_by_half_ ? gfx::Rect(4, 0, 2, 2) : gfx::Rect(8, 0, 4, 4);
-
-    // If we are supposed to ask for a rect with odd offset,
-    // make sure that we capture 1 green pixel.
-    if (use_odd_offset_) {
-      result.set_x(result.x() - 1);
-    }
-
-    return result;
-  }();
-
-  // Create and execute a CopyOutputRequest via the GLRendererCopier.
-  std::unique_ptr<CopyOutputResult> result;
-  {
-    base::RunLoop loop;
-    auto request = std::make_unique<CopyOutputRequest>(
-        CopyOutputRequest::ResultFormat::NV12_PLANES, result_destination_,
-        base::BindOnce(
-            [](std::unique_ptr<CopyOutputResult>* result,
-               base::OnceClosure quit_closure,
-               std::unique_ptr<CopyOutputResult> result_from_copier) {
-              *result = std::move(result_from_copier);
-              std::move(quit_closure).Run();
-            },
-            &result, loop.QuitClosure()));
-
-    if (scale_by_half_) {
-      request->SetUniformScaleRatio(2, 1);
-    }
-
-    request->set_result_selection(gfx::Rect(request_area));
-
-    // Upload source texture to GL:
-    const GLuint source_texture = CreateSourceTexture(source_bitmap_);
-    CreateAndBindSourceFramebuffer(source_texture);
-
-    copy_output::RenderPassGeometry geometry;
-    // geometry.result_bounds not used by GLRendererCopier
-    geometry.sampling_bounds =
-        DrawToWindowSpace(source_bitmap_size_, gfx::Rect(source_bitmap_size_));
-    geometry.result_selection = request->result_selection();
-    geometry.readback_offset =
-        DrawToWindowSpace(source_bitmap_size_, geometry.result_selection)
-            .OffsetFromOrigin();
-
-    copier()->CopyFromTextureOrFramebuffer(
-        std::move(request), geometry, source_gl_format_,
-        have_source_texture_ ? source_texture : 0, source_bitmap_size_,
-        flipped_source_, gfx::ColorSpace::CreateSRGB());
-    loop.Run();
-  }
-
-  // Check that a result was produced and is of the expected rect/size.
-  ASSERT_TRUE(result);
-  ASSERT_FALSE(result->IsEmpty());
-  ASSERT_EQ(request_area, result->rect());
-
-  const auto luma_nbytes = copy_output::GetLumaPlaneSize(*result);
-  const auto luma_stride = copy_output::GetLumaPlaneStride(*result);
-
-  const auto chroma_nbytes = copy_output::GetChromaPlaneSize(*result);
-  const auto chroma_stride = copy_output::GetChromaPlaneStride(*result);
-
-  std::unique_ptr<uint8_t[]> luma_plane =
-      std::make_unique<uint8_t[]>(luma_nbytes);
-  std::unique_ptr<uint8_t[]> chroma_planes =
-      std::make_unique<uint8_t[]>(chroma_nbytes);
-
-  // Examine the image in the |result|, and compare it to the baseline.
-  if (result_destination_ == CopyOutputResult::Destination::kSystemMemory) {
-    result->ReadNV12Planes(luma_plane.get(), luma_stride, chroma_planes.get(),
-                           chroma_stride);
-  } else {
-    LOG(ERROR) << "Texture results for NV12 are not supported yet!";
-    ADD_FAILURE();
-  }
-
-  SkBitmap source_bitmap_yuv = source_bitmap_;
-  GLScalerTestUtil::ConvertRGBABitmapToYUV(&source_bitmap_yuv);
-
-  // We've asked for a region that starts with one green pixel that is followed
-  // by all blue pixels, grab the source colors after they have been converted
-  // to YUV to have something to validate against:
-  SkColor green_yuv = source_bitmap_yuv.getColor(4, 0);
-  SkColor blue_yuv = source_bitmap_yuv.getColor(8, 0);
-
-  // Validate first row of luma (first color channel):
-  for (int col = 0; col < luma_stride; ++col) {
-    if (col == 0 && use_odd_offset_) {
-      EXPECT_NEAR(luma_plane[col], SkColorGetR(green_yuv), GetTolerance());
-      continue;
-    }
-
-    EXPECT_NEAR(luma_plane[col], SkColorGetR(blue_yuv), GetTolerance());
-  }
-
-  // All other luma rows must match the first row:
-  ValidateRows(luma_plane.get(), luma_stride, result->rect().height());
-
-  // Validate first row of chroma (second and third color channel):
-  for (int col = 0; col < chroma_stride; col += 2) {
-    if (col == 0 && use_odd_offset_) {
-      EXPECT_NEAR(chroma_planes[col], SkColorGetG(green_yuv), GetTolerance());
-      EXPECT_NEAR(chroma_planes[col + 1], SkColorGetB(green_yuv),
-                  GetTolerance());
-      continue;
-    }
-
-    EXPECT_NEAR(chroma_planes[col], SkColorGetG(blue_yuv), GetTolerance());
-    EXPECT_NEAR(chroma_planes[col + 1], SkColorGetB(blue_yuv), GetTolerance());
-  }
-
-  // All other chroma rows must match the first row:
-  ValidateRows(chroma_planes.get(), chroma_stride,
-               (result->rect().height() + 1) / 2);
-}
-
-TEST_P(GLRendererCopierDimensionsPixelTest, ExecutesCopyRequestI420) {
-  if (result_destination_ ==
-      CopyOutputRequest::ResultDestination::kNativeTextures) {
-    // TODO(https://crbug.com/1216287): Enable once textures are supported.
-    GTEST_SKIP() << "Enable once the I420 format supports producing results to "
-                    "a texture.";
-  }
-
-  // Result should contain 1px green strip at the beginning if the offset is
-  // supposed to be odd.
-  const gfx::Rect request_area = [this]() {
-    // Capture 2x2 or 4x4 blue strip fragment, depending on scaling.
-    gfx::Rect result =
-        scale_by_half_ ? gfx::Rect(4, 0, 2, 2) : gfx::Rect(8, 0, 4, 4);
-
-    // If we are supposed to ask for a rect with odd offset,
-    // make sure that we capture 1 green pixel.
-    if (use_odd_offset_) {
-      result.set_x(result.x() - 1);
-    }
-
-    return result;
-  }();
-
-  // Create and execute a CopyOutputRequest via the GLRendererCopier.
-  std::unique_ptr<CopyOutputResult> result;
-  {
-    base::RunLoop loop;
-    auto request = std::make_unique<CopyOutputRequest>(
-        CopyOutputRequest::ResultFormat::I420_PLANES, result_destination_,
-        base::BindOnce(
-            [](std::unique_ptr<CopyOutputResult>* result,
-               base::OnceClosure quit_closure,
-               std::unique_ptr<CopyOutputResult> result_from_copier) {
-              *result = std::move(result_from_copier);
-              std::move(quit_closure).Run();
-            },
-            &result, loop.QuitClosure()));
-
-    if (scale_by_half_) {
-      request->SetUniformScaleRatio(2, 1);
-    }
-
-    request->set_result_selection(gfx::Rect(request_area));
-
-    // Upload source texture to GL:
-    const GLuint source_texture = CreateSourceTexture(source_bitmap_);
-    CreateAndBindSourceFramebuffer(source_texture);
-
-    copy_output::RenderPassGeometry geometry;
-    // geometry.result_bounds not used by GLRendererCopier
-    geometry.sampling_bounds =
-        DrawToWindowSpace(source_bitmap_size_, gfx::Rect(source_bitmap_size_));
-    geometry.result_selection = request->result_selection();
-    geometry.readback_offset =
-        DrawToWindowSpace(source_bitmap_size_, geometry.result_selection)
-            .OffsetFromOrigin();
-
-    copier()->CopyFromTextureOrFramebuffer(
-        std::move(request), geometry, source_gl_format_,
-        have_source_texture_ ? source_texture : 0, source_bitmap_size_,
-        flipped_source_, gfx::ColorSpace::CreateSRGB());
-    loop.Run();
-  }
-
-  // Check that a result was produced and is of the expected rect/size.
-  ASSERT_TRUE(result);
-  ASSERT_FALSE(result->IsEmpty());
-  ASSERT_EQ(request_area, result->rect());
-
-  // Examine the image in the |result|, and compare it to the baseline PNG file.
-
-  const auto luma_nbytes = copy_output::GetLumaPlaneSize(*result);
-  const auto luma_stride = copy_output::GetLumaPlaneStride(*result);
-
-  const auto chroma_nbytes = copy_output::GetChromaPlaneSize(*result);
-  const auto chroma_stride = copy_output::GetChromaPlaneStride(*result);
-
-  std::unique_ptr<uint8_t[]> luma_plane =
-      std::make_unique<uint8_t[]>(luma_nbytes);
-  std::unique_ptr<uint8_t[]> chroma_plane_1 =
-      std::make_unique<uint8_t[]>(chroma_nbytes);
-  std::unique_ptr<uint8_t[]> chroma_plane_2 =
-      std::make_unique<uint8_t[]>(chroma_nbytes);
-
-  if (result_destination_ == CopyOutputResult::Destination::kSystemMemory) {
-    result->ReadI420Planes(luma_plane.get(), luma_stride, chroma_plane_1.get(),
-                           chroma_stride, chroma_plane_2.get(), chroma_stride);
-  } else {
-    LOG(ERROR) << "Texture results for I420 are not supported yet!";
-    ADD_FAILURE();
-  }
-
-  SkBitmap source_bitmap_yuv = source_bitmap_;
-  GLScalerTestUtil::ConvertRGBABitmapToYUV(&source_bitmap_yuv);
-
-  // We've asked for a region that starts with one green pixel that is followed
-  // by all blue pixels, validate:
-  SkColor green_yuv = source_bitmap_yuv.getColor(7, 0);
-  SkColor blue_yuv = source_bitmap_yuv.getColor(8, 0);
-
-  // Validate first row of luma (first channel):
-  for (int col = 0; col < luma_stride; ++col) {
-    if (col == 0 && use_odd_offset_) {
-      EXPECT_NEAR(luma_plane[col], SkColorGetR(green_yuv), GetTolerance());
-      continue;
-    }
-
-    EXPECT_NEAR(luma_plane[col], SkColorGetR(blue_yuv), GetTolerance());
-  }
-
-  // All other luma rows must match the first row:
-  ValidateRows(luma_plane.get(), luma_stride, result->rect().height());
-
-  // Validate first row of chroma_1 (second channel):
-  for (int col = 0; col < chroma_stride; ++col) {
-    if (col == 0 && use_odd_offset_) {
-      EXPECT_NEAR(chroma_plane_1[col], SkColorGetG(green_yuv), GetTolerance());
-      continue;
-    }
-
-    EXPECT_NEAR(chroma_plane_1[col], SkColorGetG(blue_yuv), GetTolerance());
-  }
-
-  // All other chroma_1 rows must match the first row:
-  ValidateRows(chroma_plane_1.get(), chroma_stride,
-               (result->rect().height() + 1) / 2);
-
-  // Validate first row of chroma_2 (third channel):
-  for (int col = 0; col < chroma_stride; ++col) {
-    if (col == 0 && use_odd_offset_) {
-      EXPECT_NEAR(chroma_plane_2[col], SkColorGetB(green_yuv), GetTolerance());
-      continue;
-    }
-
-    EXPECT_NEAR(chroma_plane_2[col], SkColorGetB(blue_yuv), GetTolerance());
-  }
-
-  // All other chroma_2 rows must match the first row:
-  ValidateRows(chroma_plane_2.get(), chroma_stride,
-               (result->rect().height() + 1) / 2);
-}
-
-// Instantiate parameter sets for all possible combinations of scenarios
-// GLRendererCopier will encounter, which will cause it to follow different
-// workflows.
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    GLRendererCopierPixelTest,
-    testing::Combine(
-        // Source framebuffer GL format.
-        testing::Values(static_cast<GLenum>(GL_RGBA),
-                        static_cast<GLenum>(GL_RGB)),
-        // Source: Have texture too?
-        testing::Values(false, true),
-        // Result destination.
-        testing::Values(CopyOutputResult::Destination::kSystemMemory,
-                        CopyOutputResult::Destination::kNativeTextures),
-        // Result scaling: Scale by half?
-        testing::Values(false, true),
-        // Source content is vertically flipped?
-        testing::Values(false, true)));
-
-// Instantiate parameter sets for all possible combinations of scenarios
-// GLRendererCopier will encounter, which will cause it to follow different
-// workflows.
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    GLRendererCopierDimensionsPixelTest,
-    testing::Combine(
-        // Result destination.
-        testing::Values(CopyOutputResult::Destination::kSystemMemory,
-                        CopyOutputResult::Destination::kNativeTextures),
-        // Result scaling: Scale by half?
-        testing::Values(false, true),
-        // Use odd offset?
-        testing::Values(false, true)));
-
-}  // namespace viz
diff --git a/components/viz/service/display/gl_renderer_copier_unittest.cc b/components/viz/service/display/gl_renderer_copier_unittest.cc
deleted file mode 100644
index 8ff8bca..0000000
--- a/components/viz/service/display/gl_renderer_copier_unittest.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display/gl_renderer_copier.h"
-
-#include <stdint.h>
-
-#include <iterator>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/run_loop.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/common/frame_sinks/copy_output_util.h"
-#include "components/viz/test/test_context_provider.h"
-#include "components/viz/test/test_gles2_interface.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-namespace viz {
-
-namespace {
-
-class CopierTestGLES2Interface : public TestGLES2Interface {
- public:
-  // Sets how GL will respond to queries regarding the implementation's internal
-  // read-back format.
-  void SetOptimalReadbackFormat(GLenum format, GLenum type) {
-    format_ = format;
-    type_ = type;
-  }
-
-  // GLES2Interface override.
-  void GetIntegerv(GLenum pname, GLint* params) override {
-    switch (pname) {
-      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
-        ASSERT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
-                  CheckFramebufferStatus(GL_FRAMEBUFFER));
-        params[0] = format_;
-        break;
-      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
-        ASSERT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
-                  CheckFramebufferStatus(GL_FRAMEBUFFER));
-        params[0] = type_;
-        break;
-      default:
-        TestGLES2Interface::GetIntegerv(pname, params);
-        break;
-    }
-  }
-
- private:
-  GLenum format_ = 0;
-  GLenum type_ = 0;
-};
-
-}  // namespace
-
-class GLRendererCopierTest : public testing::Test {
- public:
-  using ReusableThings = GLRendererCopier::ReusableThings;
-
-  void SetUp() override {
-    context_provider_ = TestContextProvider::Create(
-        std::make_unique<CopierTestGLES2Interface>());
-    context_provider_->BindToCurrentThread();
-    copier_ =
-        std::make_unique<GLRendererCopier>(context_provider_.get(), nullptr);
-  }
-
-  void TearDown() override { copier_.reset(); }
-
-  GLRendererCopier* copier() const { return copier_.get(); }
-
-  CopierTestGLES2Interface* test_gl() const {
-    return static_cast<CopierTestGLES2Interface*>(
-        copier_->context_provider_->ContextGL());
-  }
-
-  // These simply forward method calls to GLRendererCopier.
-  std::unique_ptr<ReusableThings> TakeReusableThingsOrCreate(
-      const base::UnguessableToken& requester) {
-    return copier_->TakeReusableThingsOrCreate(requester);
-  }
-  void StashReusableThingsOrDelete(const base::UnguessableToken& requester,
-                                   std::unique_ptr<ReusableThings> things) {
-    return copier_->StashReusableThingsOrDelete(requester, std::move(things));
-  }
-  ReusableThings* PeekReusableThings(const base::UnguessableToken& requester) {
-    const auto it = copier_->cache_.find(requester);
-    if (it == copier_->cache_.end())
-      return nullptr;
-    return it->second.get();
-  }
-  size_t GetCopierCacheSize() { return copier_->cache_.size(); }
-  void FreeUnusedCachedResources() { copier_->FreeUnusedCachedResources(); }
-  GLenum GetOptimalReadbackFormat() const {
-    return copier_->GetOptimalReadbackFormat();
-  }
-
-  static constexpr int kKeepalivePeriod = GLRendererCopier::kKeepalivePeriod;
-
- private:
-  scoped_refptr<ContextProvider> context_provider_;
-  std::unique_ptr<GLRendererCopier> copier_;
-};
-
-// Tests that named objects, such as textures or framebuffers, are only cached
-// when the CopyOutputRequest has specified a "source" of requests.
-TEST_F(GLRendererCopierTest, ReusesThingsFromSameSource) {
-  // With no source set in a copy request, expect to never re-use any textures
-  // or framebuffers.
-  const base::UnguessableToken no_source;
-  EXPECT_EQ(0u, GetCopierCacheSize());
-  auto things = TakeReusableThingsOrCreate(no_source);
-  EXPECT_TRUE(things);
-  StashReusableThingsOrDelete(no_source, std::move(things));
-  EXPECT_EQ(nullptr, PeekReusableThings(no_source));
-  EXPECT_EQ(0u, GetCopierCacheSize());
-
-  // With a source set in the request, objects should now be cached and re-used.
-  const auto source = base::UnguessableToken::Create();
-  things = TakeReusableThingsOrCreate(source);
-  ReusableThings* things_raw_ptr = things.get();
-  EXPECT_TRUE(things_raw_ptr);
-  StashReusableThingsOrDelete(source, std::move(things));
-  EXPECT_EQ(things_raw_ptr, PeekReusableThings(source));
-  EXPECT_EQ(1u, GetCopierCacheSize());
-
-  // A second, separate source gets its own cache entry.
-  const auto source2 = base::UnguessableToken::Create();
-  things = TakeReusableThingsOrCreate(source2);
-  things_raw_ptr = things.get();
-  EXPECT_TRUE(things_raw_ptr);
-  EXPECT_EQ(1u, GetCopierCacheSize());
-  StashReusableThingsOrDelete(source2, std::move(things));
-  EXPECT_EQ(things_raw_ptr, PeekReusableThings(source2));
-  EXPECT_EQ(2u, GetCopierCacheSize());
-}
-
-// Tests that cached resources are freed if unused for a while.
-TEST_F(GLRendererCopierTest, FreesUnusedResources) {
-  // Take and then stash a ReusableThings instance for a valid source.
-  const base::UnguessableToken source = base::UnguessableToken::Create();
-  EXPECT_EQ(0u, GetCopierCacheSize());
-  StashReusableThingsOrDelete(source, TakeReusableThingsOrCreate(source));
-  EXPECT_TRUE(PeekReusableThings(source));
-  EXPECT_EQ(1u, GetCopierCacheSize());
-
-  // Call FreesUnusedCachedResources() the maximum number of times before the
-  // cache entry would be considered for freeing.
-  for (int i = 0; i < kKeepalivePeriod - 1; ++i) {
-    FreeUnusedCachedResources();
-    EXPECT_TRUE(PeekReusableThings(source));
-    EXPECT_EQ(1u, GetCopierCacheSize());
-    if (HasFailure())
-      break;
-  }
-
-  // Calling FreeUnusedCachedResources() just one more time should cause the
-  // cache entry to be freed.
-  FreeUnusedCachedResources();
-  EXPECT_FALSE(PeekReusableThings(source));
-  EXPECT_EQ(0u, GetCopierCacheSize());
-}
-
-TEST_F(GLRendererCopierTest, DetectsBGRAForReadbackFormat) {
-  test_gl()->SetOptimalReadbackFormat(GL_BGRA_EXT, GL_UNSIGNED_BYTE);
-  EXPECT_EQ(static_cast<GLenum>(GL_BGRA_EXT), GetOptimalReadbackFormat());
-}
-
-TEST_F(GLRendererCopierTest, DetectsRGBAForReadbackFormat) {
-  test_gl()->SetOptimalReadbackFormat(GL_RGBA, GL_UNSIGNED_BYTE);
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), GetOptimalReadbackFormat());
-}
-
-TEST_F(GLRendererCopierTest, FallsBackOnRGBAForReadbackFormat_BadFormat) {
-  test_gl()->SetOptimalReadbackFormat(GL_RGB, GL_UNSIGNED_BYTE);
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), GetOptimalReadbackFormat());
-}
-
-TEST_F(GLRendererCopierTest, FallsBackOnRGBAForReadbackFormat_BadType) {
-  test_gl()->SetOptimalReadbackFormat(GL_BGRA_EXT, GL_UNSIGNED_SHORT);
-  EXPECT_EQ(static_cast<GLenum>(GL_RGBA), GetOptimalReadbackFormat());
-}
-
-// Tests that copying from a source with a color space that can't be converted
-// to a SkColorSpace will fallback to a transform to sRGB.
-TEST_F(GLRendererCopierTest, FallsBackToSRGBForInvalidSkColorSpaces) {
-  std::unique_ptr<CopyOutputResult> result;
-  base::RunLoop loop;
-  auto request = std::make_unique<CopyOutputRequest>(
-      CopyOutputRequest::ResultFormat::RGBA,
-      CopyOutputRequest::ResultDestination::kSystemMemory,
-      base::BindOnce(
-          [](std::unique_ptr<CopyOutputResult>* result_out,
-             base::OnceClosure quit_closure,
-             std::unique_ptr<CopyOutputResult> result_from_copier) {
-            *result_out = std::move(result_from_copier);
-            std::move(quit_closure).Run();
-          },
-          &result, loop.QuitClosure()));
-  gfx::Rect bounds(50, 50);
-  copy_output::RenderPassGeometry geometry;
-  geometry.result_bounds = bounds;
-  geometry.result_selection = bounds;
-  geometry.sampling_bounds = bounds;
-  gfx::ColorSpace hdr_color_space = gfx::ColorSpace::CreatePiecewiseHDR(
-      gfx::ColorSpace::PrimaryID::BT2020, 0.5, 1.5);
-
-  copier()->CopyFromTextureOrFramebuffer(std::move(request), geometry, GL_RGBA,
-      0, gfx::Size(50, 50), false, hdr_color_space);
-  loop.Run();
-
-  auto scoped_bitmap = result->ScopedAccessSkBitmap();
-  SkBitmap result_bitmap = scoped_bitmap.bitmap();
-  ASSERT_NE(nullptr, result_bitmap.colorSpace());
-  EXPECT_TRUE(result_bitmap.colorSpace()->isSRGB());
-}
-
-}  // namespace viz
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc
deleted file mode 100644
index 7981afd..0000000
--- a/components/viz/service/display/gl_renderer_unittest.cc
+++ /dev/null
@@ -1,5195 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/service/display/gl_renderer.h"
-
-#include <stdint.h>
-
-#include <memory>
-#include <set>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/containers/cxx20_erase.h"
-#include "base/location.h"
-#include "base/strings/stringprintf.h"
-#include "base/task/single_thread_task_runner.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "cc/base/math_util.h"
-#include "cc/test/fake_impl_task_runner_provider.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/resource_provider_test_utils.h"
-#include "components/viz/client/client_resource_provider.h"
-#include "components/viz/common/display/renderer_settings.h"
-#include "components/viz/common/features.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/common/frame_sinks/copy_output_result.h"
-#include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/resources/platform_color.h"
-#include "components/viz/common/resources/transferable_resource.h"
-#include "components/viz/service/display/display_resource_provider_gl.h"
-#include "components/viz/test/fake_output_surface.h"
-#include "components/viz/test/test_gles2_interface.h"
-#include "components/viz/test/viz_test_suite.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/config/gpu_finch_features.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "ui/base/ui_base_features.h"
-#include "ui/gfx/color_transform.h"
-#include "ui/gfx/geometry/transform.h"
-#include "ui/latency/latency_info.h"
-
-#if BUILDFLAG(IS_WIN)
-#include "components/viz/service/display/overlay_processor_win.h"
-#elif BUILDFLAG(IS_APPLE)
-#include "components/viz/service/display/overlay_processor_mac.h"
-#elif BUILDFLAG(IS_ANDROID) || defined(USE_OZONE)
-#include "components/viz/service/display/overlay_processor_strategy.h"
-#include "components/viz/service/display/overlay_processor_using_strategy.h"
-#include "components/viz/service/display/overlay_strategy_single_on_top.h"
-#include "components/viz/service/display/overlay_strategy_underlay.h"
-#else  // Default
-#include "components/viz/service/display/overlay_processor_stub.h"
-#endif
-
-using testing::_;
-using testing::AnyNumber;
-using testing::Args;
-using testing::AtLeast;
-using testing::Contains;
-using testing::ElementsAre;
-using testing::Expectation;
-using testing::InSequence;
-using testing::Invoke;
-using testing::Mock;
-using testing::Not;
-using testing::Pointee;
-using testing::Return;
-using testing::StrictMock;
-
-namespace viz {
-
-MATCHER_P(MatchesSyncToken, sync_token, "") {
-  gpu::SyncToken other;
-  memcpy(&other, arg, sizeof(other));
-  return other == sync_token;
-}
-
-class GLRendererTest : public testing::Test {
- protected:
-  ~GLRendererTest() override {
-    // Some tests create CopyOutputRequests which will PostTask ensure
-    // they are all cleaned up and completed before destroying the test.
-    VizTestSuite::RunUntilIdle();
-  }
-  AggregatedRenderPass* root_render_pass() {
-    return render_passes_in_draw_order_.back().get();
-  }
-  void DrawFrame(GLRenderer* renderer,
-                 const gfx::Size& viewport_size,
-                 const gfx::DisplayColorSpaces& display_color_spaces =
-                     gfx::DisplayColorSpaces()) {
-    SurfaceDamageRectList surface_damage_rect_list;
-    renderer->DrawFrame(&render_passes_in_draw_order_, 1.f, viewport_size,
-                        display_color_spaces,
-                        std::move(surface_damage_rect_list));
-  }
-
-  static const Program* current_program(GLRenderer* renderer) {
-    return renderer->current_program_;
-  }
-
-  static TexCoordPrecision get_cached_tex_coord_precision(
-      GLRenderer* renderer) {
-    return renderer->draw_cache_.program_key.tex_coord_precision();
-  }
-
-  DebugRendererSettings debug_settings_;
-  AggregatedRenderPassList render_passes_in_draw_order_;
-};
-
-#define EXPECT_PROGRAM_VALID(program_binding)      \
-  do {                                             \
-    ASSERT_TRUE(program_binding);                  \
-    EXPECT_TRUE((program_binding)->program());     \
-    EXPECT_TRUE((program_binding)->initialized()); \
-  } while (false)
-
-static inline SkBlendMode BlendModeToSkXfermode(BlendMode blend_mode) {
-  switch (blend_mode) {
-    case BLEND_MODE_NONE:
-    case BLEND_MODE_NORMAL:
-      return SkBlendMode::kSrcOver;
-    case BLEND_MODE_DESTINATION_IN:
-      return SkBlendMode::kDstIn;
-    case BLEND_MODE_SCREEN:
-      return SkBlendMode::kScreen;
-    case BLEND_MODE_OVERLAY:
-      return SkBlendMode::kOverlay;
-    case BLEND_MODE_DARKEN:
-      return SkBlendMode::kDarken;
-    case BLEND_MODE_LIGHTEN:
-      return SkBlendMode::kLighten;
-    case BLEND_MODE_COLOR_DODGE:
-      return SkBlendMode::kColorDodge;
-    case BLEND_MODE_COLOR_BURN:
-      return SkBlendMode::kColorBurn;
-    case BLEND_MODE_HARD_LIGHT:
-      return SkBlendMode::kHardLight;
-    case BLEND_MODE_SOFT_LIGHT:
-      return SkBlendMode::kSoftLight;
-    case BLEND_MODE_DIFFERENCE:
-      return SkBlendMode::kDifference;
-    case BLEND_MODE_EXCLUSION:
-      return SkBlendMode::kExclusion;
-    case BLEND_MODE_MULTIPLY:
-      return SkBlendMode::kMultiply;
-    case BLEND_MODE_HUE:
-      return SkBlendMode::kHue;
-    case BLEND_MODE_SATURATION:
-      return SkBlendMode::kSaturation;
-    case BLEND_MODE_COLOR:
-      return SkBlendMode::kColor;
-    case BLEND_MODE_LUMINOSITY:
-      return SkBlendMode::kLuminosity;
-  }
-  return SkBlendMode::kSrcOver;
-}
-
-// Explicitly named to be a friend in GLRenderer for shader access.
-class GLRendererShaderPixelTest : public cc::PixelTest {
- public:
-  void SetUp() override {
-    SetUpGLRenderer(gfx::SurfaceOrigin::kBottomLeft);
-    ASSERT_FALSE(renderer()->IsContextLost());
-  }
-
-  void TearDown() override {
-    cc::PixelTest::TearDown();
-    ASSERT_FALSE(renderer());
-  }
-
-  GLRenderer* renderer() { return static_cast<GLRenderer*>(renderer_.get()); }
-
-  void TestShaderWithDrawingFrame(
-      const ProgramKey& program_key,
-      const DirectRenderer::DrawingFrame& drawing_frame,
-      bool validate_output_color_matrix) {
-    renderer()->SetCurrentFrameForTesting(drawing_frame);
-    const gfx::ColorSpace kSrcColorSpaces[] = {
-        gfx::ColorSpace::CreateSRGB(),
-        gfx::ColorSpace(gfx::ColorSpace::PrimaryID::ADOBE_RGB,
-                        gfx::ColorSpace::TransferID::GAMMA28),
-        gfx::ColorSpace::CreateREC709(),
-        gfx::ColorSpace::CreateExtendedSRGB(),
-        // This will be adjusted to the display's SDR white level, because no
-        // level was specified.
-        gfx::ColorSpace::CreateSCRGBLinear(),
-        // This won't be, because it has a set SDR white level.
-        gfx::ColorSpace::CreateSCRGBLinear(123.0f),
-        // This will be adjusted to the display's SDR white level, because no
-        // level was specified.
-        gfx::ColorSpace::CreateHDR10(),
-        // This won't be, because it has a set SDR white level.
-        gfx::ColorSpace::CreateHDR10(123.0f),
-    };
-    const gfx::ColorSpace kDstColorSpaces[] = {
-        gfx::ColorSpace::CreateSRGB(),
-        gfx::ColorSpace(gfx::ColorSpace::PrimaryID::ADOBE_RGB,
-                        gfx::ColorSpace::TransferID::GAMMA18),
-        gfx::ColorSpace::CreateExtendedSRGB(),
-        gfx::ColorSpace::CreateSCRGBLinear(),
-    };
-    // Note: Use ASSERT_XXX() and not EXPECT_XXX() below since the size of the
-    // loop will lead to useless timeout failures on the bots otherwise.
-    for (const auto& src_color_space : kSrcColorSpaces) {
-      for (const auto& dst_color_space : kDstColorSpaces) {
-        renderer()->SetUseProgram(program_key, src_color_space, dst_color_space,
-                                  /*adjust_src_white_level=*/true);
-        ASSERT_TRUE(renderer()->current_program_->initialized());
-
-        if (src_color_space != dst_color_space) {
-          auto adjusted_color_space = src_color_space;
-          if (src_color_space.IsHDR()) {
-            adjusted_color_space = src_color_space.GetWithSDRWhiteLevel(
-                drawing_frame.display_color_spaces.GetSDRMaxLuminanceNits());
-          }
-          SCOPED_TRACE(
-              base::StringPrintf("adjusted_color_space=%s, dst_color_space=%s",
-                                 adjusted_color_space.ToString().c_str(),
-                                 dst_color_space.ToString().c_str()));
-
-          gfx::ColorTransform::Options options;
-          options.tone_map_pq_and_hlg_to_sdr = !dst_color_space.IsHDR();
-          options.sdr_max_luminance_nits =
-              drawing_frame.display_color_spaces.GetSDRMaxLuminanceNits();
-          auto color_transform = gfx::ColorTransform::NewColorTransform(
-              adjusted_color_space, dst_color_space, options);
-
-          ASSERT_EQ(color_transform->GetShaderSource(),
-                    renderer()
-                        ->current_program_->color_transform_for_testing()
-                        ->GetShaderSource());
-        }
-
-        if (validate_output_color_matrix) {
-          if (program_key.type() == ProgramType::PROGRAM_TYPE_SOLID_COLOR) {
-            ASSERT_EQ(
-                -1,
-                renderer()->current_program_->output_color_matrix_location());
-          } else {
-            ASSERT_NE(
-                -1,
-                renderer()->current_program_->output_color_matrix_location());
-          }
-        }
-      }
-    }
-  }
-
-  void TestShader(const ProgramKey& program_key) {
-    TestShaderWithDrawingFrame(program_key, GLRenderer::DrawingFrame(), false);
-  }
-
-  void TestShadersWithOutputColorMatrix(const ProgramKey& program_key) {
-    GLRenderer::DrawingFrame frame;
-
-    AggregatedRenderPassList render_passes_in_draw_order;
-    gfx::Size viewport_size(100, 100);
-    AggregatedRenderPassId root_pass_id{1};
-    auto* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    root_pass->damage_rect = gfx::Rect(0, 0, 25, 25);
-
-    frame.root_render_pass = root_pass;
-    frame.current_render_pass = root_pass;
-    frame.render_passes_in_draw_order = &render_passes_in_draw_order;
-
-    // Set a non-identity color matrix on the output surface.
-    SkM44 color_matrix;
-    color_matrix.setRC(0, 0, 0.7f);
-    color_matrix.setRC(1, 1, 0.4f);
-    color_matrix.setRC(2, 2, 0.5f);
-    renderer()->output_surface_->set_color_matrix(color_matrix);
-
-    TestShaderWithDrawingFrame(program_key, frame, true);
-  }
-
-  void TestShadersWithSDRWhiteLevel(const ProgramKey& program_key,
-                                    float sdr_white_level) {
-    GLRenderer::DrawingFrame frame;
-    frame.display_color_spaces.SetSDRMaxLuminanceNits(sdr_white_level);
-    TestShaderWithDrawingFrame(program_key, frame, false);
-  }
-
-  void TestBasicShaders() {
-    TestShader(ProgramKey::DebugBorder());
-    TestShader(ProgramKey::SolidColor(NO_AA, false, false));
-    TestShader(ProgramKey::SolidColor(USE_AA, false, false));
-    TestShader(ProgramKey::SolidColor(NO_AA, true, false));
-
-    TestShadersWithOutputColorMatrix(ProgramKey::DebugBorder());
-    TestShadersWithOutputColorMatrix(
-        ProgramKey::SolidColor(NO_AA, false, false));
-    TestShadersWithOutputColorMatrix(
-        ProgramKey::SolidColor(USE_AA, false, false));
-    TestShadersWithOutputColorMatrix(
-        ProgramKey::SolidColor(NO_AA, true, false));
-
-    TestShadersWithSDRWhiteLevel(ProgramKey::DebugBorder(), 200.f);
-    TestShadersWithSDRWhiteLevel(ProgramKey::SolidColor(NO_AA, false, false),
-                                 200.f);
-    TestShadersWithSDRWhiteLevel(ProgramKey::SolidColor(USE_AA, false, false),
-                                 200.f);
-    TestShadersWithSDRWhiteLevel(ProgramKey::SolidColor(NO_AA, true, false),
-                                 200.f);
-  }
-
-  void TestColorShaders() {
-    const size_t kNumTransferFns = 7;
-    skcms_TransferFunction transfer_fns[kNumTransferFns] = {
-        // The identity.
-        {1.f, 1.f, 0.f, 1.f, 0.f, 0.f, 0.f},
-        // The identity, with an if statement.
-        {1.f, 1.f, 0.f, 1.f, 0.5f, 0.f, 0.f},
-        // Just the power function.
-        {1.1f, 1.f, 0.f, 1.f, 0.f, 0.f, 0.f},
-        // Everything but the power function, nonlinear only.
-        {1.f, 0.9f, 0.1f, 0.9f, 0.f, 0.1f, 0.1f},
-        // Everything, nonlinear only.
-        {1.1f, 0.9f, 0.1f, 0.9f, 0.f, 0.1f, 0.1f},
-        // Everything but the power function.
-        {1.f, 0.9f, 0.1f, 0.9f, 0.5f, 0.1f, 0.1f},
-        // Everything.
-        {1.1f, 0.9f, 0.1f, 0.9f, 0.5f, 0.1f, 0.1f},
-    };
-
-    for (size_t i = 0; i < kNumTransferFns; ++i) {
-      skcms_Matrix3x3 primaries;
-      gfx::ColorSpace::CreateSRGB().GetPrimaryMatrix(&primaries);
-      gfx::ColorSpace src =
-          gfx::ColorSpace::CreateCustom(primaries, transfer_fns[i]);
-
-      renderer()->SetCurrentFrameForTesting(GLRenderer::DrawingFrame());
-      renderer()->SetUseProgram(ProgramKey::SolidColor(NO_AA, false, false),
-                                src, gfx::ColorSpace::CreateXYZD50());
-      EXPECT_TRUE(renderer()->current_program_->initialized());
-    }
-  }
-
-  void TestShadersWithPrecision(TexCoordPrecision precision) {
-    // This program uses external textures and sampler, so it won't compile
-    // everywhere.
-    if (context_provider()->ContextCapabilities().egl_image_external) {
-      TestShader(ProgramKey::VideoStream(precision, false));
-    }
-  }
-
-  void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision,
-                                        BlendMode blend_mode) {
-    TestShader(ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode,
-                                      NO_AA, NO_MASK, false, false, false,
-                                      false));
-    TestShader(ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode,
-                                      USE_AA, NO_MASK, false, false, false,
-                                      false));
-  }
-
-  void TestShadersWithPrecisionAndSampler(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      PremultipliedAlphaMode premultipliedAlpha,
-      bool has_background_color,
-      bool has_tex_clamp_rect) {
-    TestShader(ProgramKey::Texture(precision, sampler, premultipliedAlpha,
-                                   has_background_color, has_tex_clamp_rect,
-                                   false, false));
-  }
-
-  void TestShadersWithPrecisionAndSamplerTiledAA(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      PremultipliedAlphaMode premultipliedAlpha) {
-    TestShader(ProgramKey::Tile(precision, sampler, USE_AA, premultipliedAlpha,
-                                false, false, false, false));
-  }
-
-  void TestShadersWithPrecisionAndSamplerTiled(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      PremultipliedAlphaMode premultipliedAlpha,
-      bool is_opaque,
-      bool has_tex_clamp_rect) {
-    TestShader(ProgramKey::Tile(precision, sampler, NO_AA, premultipliedAlpha,
-                                is_opaque, has_tex_clamp_rect, false, false));
-  }
-
-  void TestYUVShadersWithPrecisionAndSampler(TexCoordPrecision precision,
-                                             SamplerType sampler) {
-    // Iterate over alpha plane and nv12 parameters.
-    UVTextureMode uv_modes[2] = {UV_TEXTURE_MODE_UV, UV_TEXTURE_MODE_U_V};
-    YUVAlphaTextureMode a_modes[2] = {YUV_NO_ALPHA_TEXTURE,
-                                      YUV_HAS_ALPHA_TEXTURE};
-    for (auto uv_mode : uv_modes) {
-      SCOPED_TRACE(uv_mode);
-      for (auto a_mode : a_modes) {
-        SCOPED_TRACE(a_mode);
-        TestShader(ProgramKey::YUVVideo(precision, sampler, a_mode, uv_mode,
-                                        false, false));
-      }
-    }
-  }
-
-  void TestShadersWithMasks(TexCoordPrecision precision,
-                            SamplerType sampler,
-                            BlendMode blend_mode,
-                            bool mask_for_background) {
-    TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA,
-                                      HAS_MASK, mask_for_background, false,
-                                      false, false));
-    TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA,
-                                      HAS_MASK, mask_for_background, true,
-                                      false, false));
-    TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA,
-                                      HAS_MASK, mask_for_background, false,
-                                      false, false));
-    TestShader(ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA,
-                                      HAS_MASK, mask_for_background, true,
-                                      false, false));
-  }
-};
-
-namespace {
-
-#if !BUILDFLAG(IS_ANDROID)
-static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
-                                                   TEX_COORD_PRECISION_HIGH};
-
-static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
-    BLEND_MODE_NONE,       BLEND_MODE_NORMAL,      BLEND_MODE_DESTINATION_IN,
-    BLEND_MODE_SCREEN,     BLEND_MODE_OVERLAY,     BLEND_MODE_DARKEN,
-    BLEND_MODE_LIGHTEN,    BLEND_MODE_COLOR_DODGE, BLEND_MODE_COLOR_BURN,
-    BLEND_MODE_HARD_LIGHT, BLEND_MODE_SOFT_LIGHT,  BLEND_MODE_DIFFERENCE,
-    BLEND_MODE_EXCLUSION,  BLEND_MODE_MULTIPLY,    BLEND_MODE_HUE,
-    BLEND_MODE_SATURATION, BLEND_MODE_COLOR,       BLEND_MODE_LUMINOSITY,
-};
-
-static const SamplerType kSamplerList[] = {
-    SAMPLER_TYPE_2D, SAMPLER_TYPE_2D_RECT, SAMPLER_TYPE_EXTERNAL_OES,
-};
-
-static const PremultipliedAlphaMode kPremultipliedAlphaModeList[] = {
-    PREMULTIPLIED_ALPHA, NON_PREMULTIPLIED_ALPHA};
-
-TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
-  TestBasicShaders();
-}
-
-TEST_F(GLRendererShaderPixelTest, TestColorShadersCompile) {
-  TestColorShaders();
-}
-
-class PrecisionShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<TexCoordPrecision> {};
-
-TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
-  TestShadersWithPrecision(GetParam());
-}
-
-INSTANTIATE_TEST_SUITE_P(PrecisionShadersCompile,
-                         PrecisionShaderPixelTest,
-                         ::testing::ValuesIn(kPrecisionList));
-
-class PrecisionBlendShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision, BlendMode>> {};
-
-TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
-  TestShadersWithPrecisionAndBlend(std::get<0>(GetParam()),
-                                   std::get<1>(GetParam()));
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    PrecisionBlendShadersCompile,
-    PrecisionBlendShaderPixelTest,
-    ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                       ::testing::ValuesIn(kBlendModeList)));
-
-class PrecisionSamplerShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision,
-                     SamplerType,
-                     PremultipliedAlphaMode,
-                     bool,       // has_background_color
-                     bool>> {};  // has_tex_clamp_rect
-
-TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
-  SamplerType sampler = std::get<1>(GetParam());
-  if (sampler != SAMPLER_TYPE_2D_RECT ||
-      context_provider()->ContextCapabilities().texture_rectangle) {
-    TestShadersWithPrecisionAndSampler(
-        std::get<0>(GetParam()),  // TexCoordPrecision
-        sampler,
-        std::get<2>(GetParam()),   // PremultipliedAlphaMode
-        std::get<3>(GetParam()),   // has_background_color
-        std::get<4>(GetParam()));  // has_tex_clamp_rect
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    PrecisionSamplerShadersCompile,
-    PrecisionSamplerShaderPixelTest,
-    ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                       ::testing::ValuesIn(kSamplerList),
-                       ::testing::ValuesIn(kPremultipliedAlphaModeList),
-                       ::testing::Bool(),    // has_background_color
-                       ::testing::Bool()));  // has_tex_clamp_rect
-
-class PrecisionSamplerShaderPixelTestTiled
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision,
-                     SamplerType,
-                     PremultipliedAlphaMode,
-                     bool,   // is_opaque
-                     bool>>  // has_tex_clamp_rect
-{};
-
-TEST_P(PrecisionSamplerShaderPixelTestTiled, ShadersCompile) {
-  SamplerType sampler = std::get<1>(GetParam());
-  if (sampler != SAMPLER_TYPE_2D_RECT ||
-      context_provider()->ContextCapabilities().texture_rectangle) {
-    TestShadersWithPrecisionAndSamplerTiled(
-        std::get<0>(GetParam()),  // TexCoordPrecision
-        sampler,
-        std::get<2>(GetParam()),   // PremultipliedAlphaMode
-        std::get<3>(GetParam()),   // is_opaque
-        std::get<4>(GetParam()));  // has_tex_clamp_rect
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    PrecisionSamplerShadersCompile,
-    PrecisionSamplerShaderPixelTestTiled,
-    ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                       ::testing::ValuesIn(kSamplerList),
-                       ::testing::ValuesIn(kPremultipliedAlphaModeList),
-                       ::testing::Bool(),    // is_opaque
-                       ::testing::Bool()));  // has_tex_clamp_rect
-
-class PrecisionSamplerShaderPixelTestTiledAA
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision, SamplerType, PremultipliedAlphaMode>> {
-};
-
-TEST_P(PrecisionSamplerShaderPixelTestTiledAA, ShadersCompile) {
-  SamplerType sampler = std::get<1>(GetParam());
-  if (sampler != SAMPLER_TYPE_2D_RECT ||
-      context_provider()->ContextCapabilities().texture_rectangle) {
-    TestShadersWithPrecisionAndSamplerTiledAA(
-        std::get<0>(GetParam()),  // TexCoordPrecision
-        sampler,
-        std::get<2>(GetParam()));  // PremultipliedAlphaMode
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(
-    PrecisionSamplerShadersCompile,
-    PrecisionSamplerShaderPixelTestTiledAA,
-    ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                       ::testing::ValuesIn(kSamplerList),
-                       ::testing::ValuesIn(kPremultipliedAlphaModeList)));
-
-class PrecisionSamplerYUVShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision, SamplerType>> {};
-
-TEST_P(PrecisionSamplerYUVShaderPixelTest, ShadersCompile) {
-  SamplerType sampler = std::get<1>(GetParam());
-  if (sampler != SAMPLER_TYPE_2D_RECT ||
-      context_provider()->ContextCapabilities().texture_rectangle) {
-    TestYUVShadersWithPrecisionAndSampler(
-        std::get<0>(GetParam()),  // TexCoordPrecision
-        sampler);
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(PrecisionSamplerShadersCompile,
-                         PrecisionSamplerYUVShaderPixelTest,
-                         ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                                            ::testing::ValuesIn(kSamplerList)));
-
-class MaskShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
-
-TEST_P(MaskShaderPixelTest, ShadersCompile) {
-  SamplerType sampler = std::get<1>(GetParam());
-  if (sampler != SAMPLER_TYPE_2D_RECT ||
-      context_provider()->ContextCapabilities().texture_rectangle) {
-    TestShadersWithMasks(std::get<0>(GetParam()), sampler,
-                         std::get<2>(GetParam()), std::get<3>(GetParam()));
-  }
-}
-
-INSTANTIATE_TEST_SUITE_P(MaskShadersCompile,
-                         MaskShaderPixelTest,
-                         ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                                            ::testing::ValuesIn(kSamplerList),
-                                            ::testing::ValuesIn(kBlendModeList),
-                                            ::testing::Bool()));
-
-#endif
-
-class FakeRendererGL : public GLRenderer {
- public:
-  FakeRendererGL(const RendererSettings* settings,
-                 const DebugRendererSettings* debug_settings,
-                 OutputSurface* output_surface,
-                 DisplayResourceProviderGL* resource_provider)
-      : GLRenderer(settings,
-                   debug_settings,
-                   output_surface,
-                   resource_provider,
-                   nullptr,
-                   nullptr) {}
-
-  FakeRendererGL(const RendererSettings* settings,
-                 const DebugRendererSettings* debug_settings,
-                 OutputSurface* output_surface,
-                 DisplayResourceProviderGL* resource_provider,
-                 OverlayProcessorInterface* overlay_processor)
-      : GLRenderer(settings,
-                   debug_settings,
-                   output_surface,
-                   resource_provider,
-                   overlay_processor,
-                   nullptr) {}
-
-  FakeRendererGL(
-      const RendererSettings* settings,
-      const DebugRendererSettings* debug_settings,
-      OutputSurface* output_surface,
-      DisplayResourceProviderGL* resource_provider,
-      OverlayProcessorInterface* overlay_processor,
-      scoped_refptr<base::SingleThreadTaskRunner> current_task_runner)
-      : GLRenderer(settings,
-                   debug_settings,
-                   output_surface,
-                   resource_provider,
-                   overlay_processor,
-                   std::move(current_task_runner)) {}
-
-  // GLRenderer methods.
-
-  // Changing visibility to public.
-  using GLRenderer::stencil_enabled;
-};
-
-class GLRendererWithDefaultHarnessTest : public GLRendererTest {
- protected:
-  GLRendererWithDefaultHarnessTest() {
-    output_surface_ = FakeOutputSurface::Create3d();
-    output_surface_->BindToClient(&output_surface_client_);
-
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-    renderer_ = std::make_unique<FakeRendererGL>(&settings_, &debug_settings_,
-                                                 output_surface_.get(),
-                                                 resource_provider_.get());
-    renderer_->Initialize();
-    renderer_->SetVisible(true);
-  }
-
-  void SwapBuffers() { renderer_->SwapBuffers({}); }
-
-  RendererSettings settings_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-};
-
-// Closing the namespace here so that GLRendererShaderTest can take advantage
-// of the friend relationship with GLRenderer and all of the mock classes
-// declared above it.
-}  // namespace
-
-class GLRendererShaderTest : public GLRendererTest {
- protected:
-  GLRendererShaderTest() {
-    output_surface_ = FakeOutputSurface::Create3d();
-    output_surface_->BindToClient(&output_surface_client_);
-
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-    renderer_ = std::make_unique<FakeRendererGL>(
-        &settings_, &debug_settings_, output_surface_.get(),
-        resource_provider_.get(), nullptr);
-    renderer_->Initialize();
-    renderer_->SetVisible(true);
-
-    child_context_provider_ = TestContextProvider::Create();
-    child_context_provider_->BindToCurrentThread();
-    child_resource_provider_ = std::make_unique<ClientResourceProvider>();
-  }
-
-  ~GLRendererShaderTest() override {
-    child_resource_provider_->ShutdownAndReleaseAllResources();
-  }
-
-  void TestRenderPassProgram(TexCoordPrecision precision,
-                             BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, NO_AA,
-                               NO_MASK, false, false, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
-                                        BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, NO_AA,
-                               NO_MASK, false, true, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassMaskProgram(TexCoordPrecision precision,
-                                 SamplerType sampler,
-                                 BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK,
-                               false, false, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
-                                            SamplerType sampler,
-                                            BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, sampler, blend_mode, NO_AA, HAS_MASK,
-                               false, true, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassProgramAA(TexCoordPrecision precision,
-                               BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, USE_AA,
-                               NO_MASK, false, false, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
-                                          BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, SAMPLER_TYPE_2D, blend_mode, USE_AA,
-                               NO_MASK, false, true, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
-                                   SamplerType sampler,
-                                   BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK,
-                               false, false, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
-                                              SamplerType sampler,
-                                              BlendMode blend_mode) {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::RenderPass(precision, sampler, blend_mode, USE_AA, HAS_MASK,
-                               false, true, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  void TestSolidColorProgramAA() {
-    const Program* program = renderer_->GetProgramIfInitialized(
-        ProgramKey::SolidColor(USE_AA, false, false));
-    EXPECT_PROGRAM_VALID(program);
-    EXPECT_EQ(program, renderer_->current_program_);
-  }
-
-  RendererSettings settings_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  scoped_refptr<TestContextProvider> child_context_provider_;
-  std::unique_ptr<ClientResourceProvider> child_resource_provider_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-};
-
-namespace {
-
-TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
-  gfx::Size viewport_size(1, 1);
-  EXPECT_FALSE(renderer_->stencil_enabled());
-
-  output_surface_->set_has_external_stencil_test(true);
-
-  auto* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  DrawFrame(renderer_.get(), viewport_size);
-  EXPECT_TRUE(renderer_->stencil_enabled());
-}
-
-TEST_F(GLRendererWithDefaultHarnessTest, TextureDrawQuadShaderPrecisionHigh) {
-  // TestContextProvider, used inside FakeOuputSurfaceClient, redefines
-  // GetShaderPrecisionFormat() and sets the resolution of mediump with
-  // 10-bits (1024). So any value higher than 1024 should use highp.
-  // The goal is to make sure the fragment shaders used in DoDrawQuad() use
-  // the correct precision qualifier.
-
-  const gfx::Size viewport_size(1, 1);
-  auto* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-
-  const bool needs_blending = false;
-  const bool premultiplied_alpha = false;
-  const bool flipped = false;
-  const bool nearest_neighbor = false;
-  const float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  const gfx::PointF uv_top_left(0, 0);
-  const gfx::PointF uv_bottom_right(1, 1);
-
-  auto child_context_provider = TestContextProvider::Create();
-  child_context_provider->BindToCurrentThread();
-
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  // Here is where the texture is created. Any value bigger than 1024 should use
-  // a highp.
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-      gfx::Size(1025, 1025), true);
-  ResourceId client_resource_id = child_resource_provider->ImportResource(
-      transfer_resource, base::DoNothing());
-
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      cc::SendResourceAndGetChildToParentMap(
-          {client_resource_id}, resource_provider_.get(),
-          child_resource_provider.get(), child_context_provider.get());
-  ResourceId resource_id = resource_map[client_resource_id];
-
-  // The values defined here should not alter the size of the already created
-  // texture.
-  TextureDrawQuad* overlay_quad =
-      root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size),
-                       gfx::Rect(1023, 1023), gfx::MaskFilterInfo(),
-                       absl::nullopt, false, 1, SkBlendMode::kSrcOver, 0);
-  overlay_quad->SetNew(shared_state, gfx::Rect(1023, 1023),
-                       gfx::Rect(1023, 1023), needs_blending, resource_id,
-                       premultiplied_alpha, uv_top_left, uv_bottom_right,
-                       SK_ColorTRANSPARENT, vertex_opacity, flipped,
-                       nearest_neighbor, /*secure_output_only=*/false,
-                       gfx::ProtectedVideoType::kClear);
-
-  DrawFrame(renderer_.get(), viewport_size);
-
-  TexCoordPrecision precision = get_cached_tex_coord_precision(renderer_.get());
-  EXPECT_EQ(precision, TEX_COORD_PRECISION_HIGH);
-
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-
-TEST_F(GLRendererWithDefaultHarnessTest, TextureDrawQuadShaderPrecisionMedium) {
-  // TestContextProvider, used inside FakeOuputSurfaceClient, redefines
-  // GetShaderPrecisionFormat() and sets the resolution of mediump with
-  // 10-bits (1024). So any value higher than 1024 should use highp.
-  // The goal is to make sure the fragment shaders used in DoDrawQuad() use
-  // the correct precision qualifier.
-
-  const gfx::Size viewport_size(1, 1);
-  auto* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-
-  const bool needs_blending = false;
-  const bool premultiplied_alpha = false;
-  const bool flipped = false;
-  const bool nearest_neighbor = false;
-  const float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  const gfx::PointF uv_top_left(0, 0);
-  const gfx::PointF uv_bottom_right(1, 1);
-
-  auto child_context_provider = TestContextProvider::Create();
-  child_context_provider->BindToCurrentThread();
-
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  // Here is where the texture is created. Any value smaller than 1024 should
-  // use a mediump.
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-      gfx::Size(1023, 1023), true);
-  ResourceId client_resource_id = child_resource_provider->ImportResource(
-      transfer_resource, base::DoNothing());
-
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      cc::SendResourceAndGetChildToParentMap(
-          {client_resource_id}, resource_provider_.get(),
-          child_resource_provider.get(), child_context_provider.get());
-  ResourceId resource_id = resource_map[client_resource_id];
-
-  // The values defined here should not alter the size of the already created
-  // texture.
-  TextureDrawQuad* overlay_quad =
-      root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size),
-                       gfx::Rect(1025, 1025), gfx::MaskFilterInfo(),
-                       absl::nullopt, false, 1, SkBlendMode::kSrcOver, 0);
-  overlay_quad->SetNew(shared_state, gfx::Rect(1025, 1025),
-                       gfx::Rect(1025, 1025), needs_blending, resource_id,
-                       premultiplied_alpha, uv_top_left, uv_bottom_right,
-                       SK_ColorTRANSPARENT, vertex_opacity, flipped,
-                       nearest_neighbor, /*secure_output_only=*/false,
-                       gfx::ProtectedVideoType::kClear);
-
-  DrawFrame(renderer_.get(), viewport_size);
-
-  TexCoordPrecision precision = get_cached_tex_coord_precision(renderer_.get());
-  EXPECT_EQ(precision, TEX_COORD_PRECISION_MEDIUM);
-
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-
-class GLRendererTextureDrawQuadHDRTest
-    : public GLRendererWithDefaultHarnessTest {
- protected:
-  void RunTest(bool is_video_frame) {
-    const gfx::Size viewport_size(10, 10);
-    auto* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-        gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-
-    const bool needs_blending = false;
-    const bool premultiplied_alpha = false;
-    const bool flipped = false;
-    const bool nearest_neighbor = false;
-    const float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-    const gfx::PointF uv_top_left(0, 0);
-    const gfx::PointF uv_bottom_right(1, 1);
-
-    auto child_context_provider = TestContextProvider::Create();
-    child_context_provider->BindToCurrentThread();
-
-    auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-    constexpr gfx::Size kTextureSize = gfx::Size(10, 10);
-    auto transfer_resource = TransferableResource::MakeGL(
-        gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-        kTextureSize, true);
-    transfer_resource.color_space = gfx::ColorSpace::CreateSCRGBLinear();
-    ResourceId client_resource_id = child_resource_provider->ImportResource(
-        transfer_resource, base::DoNothing());
-
-    std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-        cc::SendResourceAndGetChildToParentMap(
-            {client_resource_id}, resource_provider_.get(),
-            child_resource_provider.get(), child_context_provider.get());
-    ResourceId resource_id = resource_map[client_resource_id];
-
-    TextureDrawQuad* overlay_quad =
-        root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-    SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-    shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size),
-                         gfx::Rect(kTextureSize), gfx::MaskFilterInfo(),
-                         absl::nullopt, false, 1, SkBlendMode::kSrcOver, 0);
-    overlay_quad->SetNew(shared_state, gfx::Rect(kTextureSize),
-                         gfx::Rect(kTextureSize), needs_blending, resource_id,
-                         premultiplied_alpha, uv_top_left, uv_bottom_right,
-                         SK_ColorTRANSPARENT, vertex_opacity, flipped,
-                         nearest_neighbor, /*secure_output_only=*/false,
-                         gfx::ProtectedVideoType::kClear);
-    overlay_quad->is_video_frame = is_video_frame;
-
-    constexpr float kSDRWhiteLevel = 123.0f;
-    gfx::DisplayColorSpaces display_color_spaces;
-    display_color_spaces.SetSDRMaxLuminanceNits(kSDRWhiteLevel);
-
-    DrawFrame(renderer_.get(), viewport_size, display_color_spaces);
-
-    const Program* program = current_program(renderer_.get());
-    DCHECK(program);
-    DCHECK(program->color_transform_for_testing())
-        << program->fragment_shader().GetShaderString();
-
-    const gfx::ColorSpace expected_src_color_space =
-        is_video_frame
-            ? gfx::ColorSpace::CreateSCRGBLinear().GetWithSDRWhiteLevel(
-                  kSDRWhiteLevel)
-            : gfx::ColorSpace::CreateSCRGBLinear();
-    EXPECT_EQ(program->color_transform_for_testing()->GetSrcColorSpace(),
-              expected_src_color_space);
-
-    child_resource_provider->ShutdownAndReleaseAllResources();
-  }
-};
-
-TEST_F(GLRendererTextureDrawQuadHDRTest, VideoFrame) {
-  RunTest(/*is_video_frame=*/true);
-}
-
-TEST_F(GLRendererTextureDrawQuadHDRTest, NotVideoFrame) {
-  RunTest(/*is_video_frame=*/false);
-}
-
-class ForbidSynchronousCallGLES2Interface : public TestGLES2Interface {
- public:
-  ForbidSynchronousCallGLES2Interface() = default;
-
-  void GetAttachedShaders(GLuint program,
-                          GLsizei max_count,
-                          GLsizei* count,
-                          GLuint* shaders) override {
-    ADD_FAILURE();
-  }
-
-  GLint GetAttribLocation(GLuint program, const GLchar* name) override {
-    ADD_FAILURE();
-    return 0;
-  }
-
-  void GetBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
-
-  void GetBufferParameteriv(GLenum target,
-                            GLenum pname,
-                            GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  GLenum GetError() override {
-    ADD_FAILURE();
-    return GL_NO_ERROR;
-  }
-
-  void GetFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
-
-  void GetFramebufferAttachmentParameteriv(GLenum target,
-                                           GLenum attachment,
-                                           GLenum pname,
-                                           GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetIntegerv(GLenum pname, GLint* value) override {
-    if (pname == GL_MAX_TEXTURE_SIZE) {
-      // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
-      *value = 1024;
-    } else {
-      ADD_FAILURE();
-    }
-  }
-
-  // We allow querying the shader compilation and program link status in debug
-  // mode, but not release.
-  void GetProgramiv(GLuint program, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetShaderiv(GLuint shader, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetRenderbufferParameteriv(GLenum target,
-                                  GLenum pname,
-                                  GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetShaderPrecisionFormat(GLenum shadertype,
-                                GLenum precisiontype,
-                                GLint* range,
-                                GLint* precision) override {
-    ADD_FAILURE();
-  }
-
-  void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetUniformfv(GLuint program, GLint location, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetUniformiv(GLuint program, GLint location, GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  GLint GetUniformLocation(GLuint program, const GLchar* name) override {
-    ADD_FAILURE();
-    return 0;
-  }
-
-  void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void GetVertexAttribPointerv(GLuint index,
-                               GLenum pname,
-                               void** pointer) override {
-    ADD_FAILURE();
-  }
-};
-
-TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
-  auto gl_owned = std::make_unique<ForbidSynchronousCallGLES2Interface>();
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-}
-
-class LoseContextOnFirstGetGLES2Interface : public TestGLES2Interface {
- public:
-  LoseContextOnFirstGetGLES2Interface() {}
-
-  void GetProgramiv(GLuint program, GLenum pname, GLint* value) override {
-    LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
-                        GL_INNOCENT_CONTEXT_RESET_ARB);
-    *value = 0;
-  }
-
-  void GetShaderiv(GLuint shader, GLenum pname, GLint* value) override {
-    LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
-                        GL_INNOCENT_CONTEXT_RESET_ARB);
-    *value = 0;
-  }
-};
-
-TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
-  auto gl_owned = std::make_unique<LoseContextOnFirstGetGLES2Interface>();
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-}
-
-class ClearCountingGLES2Interface : public TestGLES2Interface {
- public:
-  ClearCountingGLES2Interface() = default;
-
-  MOCK_METHOD3(DiscardFramebufferEXT,
-               void(GLenum target,
-                    GLsizei numAttachments,
-                    const GLenum* attachments));
-  MOCK_METHOD1(Clear, void(GLbitfield mask));
-};
-
-TEST_F(GLRendererTest, OpaqueBackground) {
-  auto gl_owned = std::make_unique<ClearCountingGLES2Interface>();
-  gl_owned->set_have_discard_framebuffer(true);
-
-  auto* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(1, 1);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  // On DEBUG builds, render passes with opaque background clear to blue to
-  // easily see regions that were not drawn on the screen.
-  EXPECT_CALL(*gl, DiscardFramebufferEXT(GL_FRAMEBUFFER, _, _))
-      .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
-      .Times(1);
-#ifdef NDEBUG
-  EXPECT_CALL(*gl, Clear(_)).Times(0);
-#else
-  EXPECT_CALL(*gl, Clear(_)).Times(1);
-#endif
-  DrawFrame(&renderer, viewport_size);
-  Mock::VerifyAndClearExpectations(gl);
-}
-
-TEST_F(GLRendererTest, TransparentBackground) {
-  auto gl_owned = std::make_unique<ClearCountingGLES2Interface>();
-  auto* gl = gl_owned.get();
-  gl_owned->set_have_discard_framebuffer(true);
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(1, 1);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = true;
-
-  EXPECT_CALL(*gl, DiscardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
-  EXPECT_CALL(*gl, Clear(_)).Times(1);
-  DrawFrame(&renderer, viewport_size);
-
-  Mock::VerifyAndClearExpectations(gl);
-}
-
-TEST_F(GLRendererTest, OffscreenOutputSurface) {
-  auto gl_owned = std::make_unique<ClearCountingGLES2Interface>();
-  auto* gl = gl_owned.get();
-  gl_owned->set_have_discard_framebuffer(true);
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::CreateOffscreen(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(1, 1);
-  cc::AddRenderPass(&render_passes_in_draw_order_, AggregatedRenderPassId{1},
-                    gfx::Rect(viewport_size), gfx::Transform(),
-                    cc::FilterOperations());
-
-  EXPECT_CALL(*gl, DiscardFramebufferEXT(GL_FRAMEBUFFER, _, _))
-      .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
-      .Times(1);
-  EXPECT_CALL(*gl, Clear(_)).Times(AnyNumber());
-  DrawFrame(&renderer, viewport_size);
-  Mock::VerifyAndClearExpectations(gl);
-}
-
-class TextureStateTrackingGLES2Interface : public TestGLES2Interface {
- public:
-  TextureStateTrackingGLES2Interface() : active_texture_(GL_INVALID_ENUM) {}
-
-  MOCK_METHOD1(WaitSyncTokenCHROMIUM, void(const GLbyte* sync_token));
-  MOCK_METHOD3(TexParameteri, void(GLenum target, GLenum pname, GLint param));
-  MOCK_METHOD4(
-      DrawElements,
-      void(GLenum mode, GLsizei count, GLenum type, const void* indices));
-
-  void ActiveTexture(GLenum texture) override {
-    EXPECT_NE(texture, active_texture_);
-    active_texture_ = texture;
-  }
-
-  GLenum active_texture() const { return active_texture_; }
-
- private:
-  GLenum active_texture_;
-};
-
-#define EXPECT_FILTER_CALL(filter)                                          \
-  EXPECT_CALL(*gl,                                                          \
-              TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter)); \
-  EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter));
-
-TEST_F(GLRendererTest, ActiveTextureState) {
-  auto child_gl_owned = std::make_unique<TextureStateTrackingGLES2Interface>();
-  auto child_context_provider =
-      TestContextProvider::Create(std::move(child_gl_owned));
-  child_context_provider->BindToCurrentThread();
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  auto gl_owned = std::make_unique<TextureStateTrackingGLES2Interface>();
-  gl_owned->set_have_extension_egl_image(true);
-  auto* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  // During initialization we are allowed to set any texture parameters.
-  EXPECT_CALL(*gl, TexParameteri(_, _, _)).Times(AnyNumber());
-
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(100, 100), gfx::Transform(), cc::FilterOperations());
-  gpu::SyncToken mailbox_sync_token;
-  cc::AddOneOfEveryQuadTypeInDisplayResourceProvider(
-      root_pass, resource_provider.get(), child_resource_provider.get(),
-      child_context_provider.get(), AggregatedRenderPassId{0},
-      &mailbox_sync_token);
-
-  EXPECT_EQ(12u, resource_provider->num_resources());
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // Set up expected texture filter state transitions that match the quads
-  // created in AppendOneOfEveryQuadType().
-  Mock::VerifyAndClearExpectations(gl);
-  {
-    InSequence sequence;
-    // The verified flush flag will be set by
-    // ClientResourceProvider::PrepareSendToParent. Before checking if
-    // the gpu::SyncToken matches, set this flag first.
-    mailbox_sync_token.SetVerifyFlush();
-    // In AddOneOfEveryQuadTypeInDisplayResourceProvider, resources are added
-    // into RenderPass with the below order: resource6, resource1, resource8
-    // (with mailbox), resource2, resource3, resource4, resource9, resource10,
-    // resource11, resource12. resource8 has its own mailbox mailbox_sync_token.
-    // The rest resources share a common default sync token.
-    EXPECT_CALL(*gl, WaitSyncTokenCHROMIUM(_)).Times(2);
-    EXPECT_CALL(*gl,
-                WaitSyncTokenCHROMIUM(MatchesSyncToken(mailbox_sync_token)))
-        .Times(1);
-    EXPECT_CALL(*gl, WaitSyncTokenCHROMIUM(_)).Times(7);
-
-    // yuv_quad is drawn with the default linear filter.
-    for (int i = 0; i < 4; ++i) {
-      EXPECT_FILTER_CALL(GL_LINEAR);
-    }
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    // tile_quad is drawn with GL_NEAREST because it is not transformed or
-    // scaled.
-    EXPECT_FILTER_CALL(GL_NEAREST);
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    // transformed tile_quad
-    EXPECT_FILTER_CALL(GL_LINEAR);
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    // scaled tile_quad
-    EXPECT_FILTER_CALL(GL_LINEAR);
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    // texture_quad without nearest neighbor
-    EXPECT_FILTER_CALL(GL_LINEAR);
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    // texture_quad without nearest neighbor
-    EXPECT_FILTER_CALL(GL_LINEAR);
-    EXPECT_CALL(*gl, DrawElements(_, _, _, _));
-
-    if (features::IsUsingFastPathForSolidColorQuad()) {
-      // stream video and debug draw quads
-      EXPECT_CALL(*gl, DrawElements(_, _, _, _)).Times(2);
-    } else {
-      // stream video, solid color, and debug draw quads
-      EXPECT_CALL(*gl, DrawElements(_, _, _, _)).Times(3);
-    }
-  }
-
-  gfx::Size viewport_size(100, 100);
-  DrawFrame(&renderer, viewport_size);
-  Mock::VerifyAndClearExpectations(gl);
-
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-
-class BufferSubDataTrackingGLES2Interface : public TestGLES2Interface {
- public:
-  BufferSubDataTrackingGLES2Interface() = default;
-  ~BufferSubDataTrackingGLES2Interface() override = default;
-
-  void BufferSubData(GLenum target,
-                     GLintptr offset,
-                     GLsizeiptr size,
-                     const void* data) override {
-    if (target != GL_ARRAY_BUFFER)
-      return;
-    DCHECK_EQ(0, offset);
-    last_array_data.resize(size);
-    memcpy(last_array_data.data(), data, size);
-  }
-
-  std::vector<uint8_t> last_array_data;
-};
-
-TEST_F(GLRendererTest, DrawYUVVideoDrawQuadWithVisibleRect) {
-  gfx::Size viewport_size(100, 100);
-
-  auto mock_gl_owned = std::make_unique<BufferSubDataTrackingGLES2Interface>();
-  BufferSubDataTrackingGLES2Interface* mock_gl = mock_gl_owned.get();
-  auto provider = TestContextProvider::Create(std::move(mock_gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  gfx::Rect rect(viewport_size);
-  gfx::Rect visible_rect(rect);
-  gfx::RectF tex_coord_rect(0, 0, 1, 1);
-  visible_rect.Inset(gfx::Insets::TLBR(20, 10, 40, 30));
-
-  SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), gfx::Rect(), rect,
-                       gfx::MaskFilterInfo(), absl::nullopt, false, 1,
-                       SkBlendMode::kSrcOver, 0);
-
-  YUVVideoDrawQuad* quad =
-      root_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
-  quad->SetNew(shared_state, rect, visible_rect, /*needs_blending=*/false,
-               tex_coord_rect, tex_coord_rect, rect.size(), rect.size(),
-               ResourceId(1), ResourceId(1), ResourceId(1), ResourceId(1),
-               gfx::ColorSpace(), 0, 1.0, 8);
-
-  DrawFrame(&renderer, viewport_size);
-
-  ASSERT_EQ(96u, mock_gl->last_array_data.size());
-  float* geometry_binding_vertexes =
-      reinterpret_cast<float*>(mock_gl->last_array_data.data());
-
-  const double kEpsilon = 1e-6;
-  EXPECT_NEAR(-0.4f, geometry_binding_vertexes[0], kEpsilon);
-  EXPECT_NEAR(-0.3f, geometry_binding_vertexes[1], kEpsilon);
-  EXPECT_NEAR(0.1f, geometry_binding_vertexes[3], kEpsilon);
-  EXPECT_NEAR(0.2f, geometry_binding_vertexes[4], kEpsilon);
-
-  EXPECT_NEAR(0.2f, geometry_binding_vertexes[12], kEpsilon);
-  EXPECT_NEAR(0.1f, geometry_binding_vertexes[13], kEpsilon);
-  EXPECT_NEAR(0.7f, geometry_binding_vertexes[15], kEpsilon);
-  EXPECT_NEAR(0.6f, geometry_binding_vertexes[16], kEpsilon);
-}
-
-class NoClearRootRenderPassMockGLES2Interface : public TestGLES2Interface {
- public:
-  MOCK_METHOD1(Clear, void(GLbitfield mask));
-  MOCK_METHOD4(
-      DrawElements,
-      void(GLenum mode, GLsizei count, GLenum type, const void* indices));
-};
-
-TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
-  auto mock_gl_owned =
-      std::make_unique<NoClearRootRenderPassMockGLES2Interface>();
-  NoClearRootRenderPassMockGLES2Interface* mock_gl = mock_gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(mock_gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  settings.should_clear_root_render_pass = false;
-
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(10, 10);
-
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPass* child_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, child_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  cc::AddQuad(child_pass, gfx::Rect(viewport_size), SK_ColorBLUE);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-
-  cc::AddRenderPassQuad(root_pass, child_pass);
-
-#ifdef NDEBUG
-  GLint clear_bits = GL_COLOR_BUFFER_BIT;
-#else
-  GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
-#endif
-
-  // First render pass is not the root one, clearing should happen.
-  EXPECT_CALL(*mock_gl, Clear(clear_bits)).Times(AtLeast(1));
-
-  Expectation first_render_pass =
-      EXPECT_CALL(*mock_gl, DrawElements(_, _, _, _)).Times(1);
-
-  if (features::IsUsingFastPathForSolidColorQuad()) {
-    // The second render pass is the root one, clearing should be prevented. The
-    // one call is expected due to the solid color draw quad which uses glClear
-    // to draw the quad.
-    EXPECT_CALL(*mock_gl, Clear(clear_bits)).Times(1).After(first_render_pass);
-  } else {
-    // The second render pass is the root one, clearing should be prevented.
-    EXPECT_CALL(*mock_gl, Clear(clear_bits)).Times(0).After(first_render_pass);
-  }
-
-  EXPECT_CALL(*mock_gl, DrawElements(_, _, _, _))
-      .Times(AnyNumber())
-      .After(first_render_pass);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(&renderer, viewport_size);
-
-  // In multiple render passes all but the root pass should clear the
-  // framebuffer.
-  Mock::VerifyAndClearExpectations(&mock_gl);
-}
-
-class ScissorTestOnClearCheckingGLES2Interface : public TestGLES2Interface {
- public:
-  ScissorTestOnClearCheckingGLES2Interface() = default;
-
-  void ClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) override {
-    // RGBA - {0, 0, 0, 0} is used to clear the buffer before drawing onto the
-    // render target. Any other color means a solid color draw quad is being
-    // drawn.
-    if (features::IsUsingFastPathForSolidColorQuad())
-      is_drawing_solid_color_quad_ = !(r == 0 && g == 0 && b == 0 && a == 0);
-  }
-
-  void Clear(GLbitfield bits) override {
-    // GL clear is also used to draw solid color draw quads.
-    if ((bits & GL_COLOR_BUFFER_BIT) && is_drawing_solid_color_quad_)
-      return;
-    EXPECT_FALSE(scissor_enabled_);
-  }
-
-  void Enable(GLenum cap) override {
-    if (cap == GL_SCISSOR_TEST)
-      scissor_enabled_ = true;
-  }
-
-  void Disable(GLenum cap) override {
-    if (cap == GL_SCISSOR_TEST)
-      scissor_enabled_ = false;
-  }
-
- private:
-  bool scissor_enabled_ = false;
-  bool is_drawing_solid_color_quad_ = false;
-};
-
-TEST_F(GLRendererTest, ScissorTestWhenClearing) {
-  auto gl_owned = std::make_unique<ScissorTestOnClearCheckingGLES2Interface>();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  EXPECT_FALSE(renderer.use_partial_swap());
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(100, 100);
-
-  gfx::Rect grand_child_rect(25, 25);
-  AggregatedRenderPassId grand_child_pass_id{3};
-  AggregatedRenderPass* grand_child_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, grand_child_pass_id, grand_child_rect,
-      gfx::Transform(), cc::FilterOperations());
-  cc::AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
-
-  gfx::Rect child_rect(50, 50);
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPass* child_pass =
-      cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                        child_rect, gfx::Transform(), cc::FilterOperations());
-  cc::AddQuad(child_pass, child_rect, SK_ColorBLUE);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-
-  cc::AddRenderPassQuad(root_pass, child_pass);
-  cc::AddRenderPassQuad(child_pass, grand_child_pass);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(&renderer, viewport_size);
-}
-
-class DiscardCheckingGLES2Interface : public TestGLES2Interface {
- public:
-  DiscardCheckingGLES2Interface() = default;
-
-  void DiscardFramebufferEXT(GLenum target,
-                             GLsizei numAttachments,
-                             const GLenum* attachments) override {
-    ++discarded_;
-  }
-
-  int discarded() const { return discarded_; }
-  void reset_discarded() { discarded_ = 0; }
-
- private:
-  int discarded_ = 0;
-};
-
-TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
-  auto gl_owned = std::make_unique<DiscardCheckingGLES2Interface>();
-  gl_owned->set_have_post_sub_buffer(true);
-  gl_owned->set_have_discard_framebuffer(true);
-
-  auto* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  auto output_surface = FakeOutputSurface::Create3d(std::move(provider));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  EXPECT_TRUE(renderer.use_partial_swap());
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(100, 100);
-  {
-    // Draw one black frame to make sure the output surface is reshaped before
-    // testes.
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorBLACK);
-    root_pass->damage_rect = gfx::Rect(viewport_size);
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    gl->reset_discarded();
-  }
-  {
-    // Partial frame, should not discard.
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-    root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    EXPECT_EQ(0, gl->discarded());
-    gl->reset_discarded();
-  }
-  {
-    // Full frame, should discard.
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    EXPECT_EQ(1, gl->discarded());
-    gl->reset_discarded();
-  }
-  {
-    // Full frame, external scissor is set, should not discard.
-    output_surface->set_has_external_stencil_test(true);
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-    root_pass->has_transparent_background = false;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    EXPECT_EQ(0, gl->discarded());
-    gl->reset_discarded();
-    output_surface->set_has_external_stencil_test(false);
-  }
-}
-
-class ResourceTrackingGLES2Interface : public TestGLES2Interface {
- public:
-  ResourceTrackingGLES2Interface() = default;
-  ~ResourceTrackingGLES2Interface() override { CheckNoResources(); }
-
-  void CheckNoResources() {
-    EXPECT_TRUE(textures_.empty());
-    EXPECT_TRUE(buffers_.empty());
-    EXPECT_TRUE(framebuffers_.empty());
-    EXPECT_TRUE(renderbuffers_.empty());
-    EXPECT_TRUE(queries_.empty());
-    EXPECT_TRUE(shaders_.empty());
-    EXPECT_TRUE(programs_.empty());
-  }
-
-  void GenTextures(GLsizei n, GLuint* textures) override {
-    GenIds(&textures_, n, textures);
-  }
-
-  void GenBuffers(GLsizei n, GLuint* buffers) override {
-    GenIds(&buffers_, n, buffers);
-  }
-
-  void GenFramebuffers(GLsizei n, GLuint* framebuffers) override {
-    GenIds(&framebuffers_, n, framebuffers);
-  }
-
-  void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override {
-    GenIds(&renderbuffers_, n, renderbuffers);
-  }
-
-  void GenQueriesEXT(GLsizei n, GLuint* queries) override {
-    GenIds(&queries_, n, queries);
-  }
-
-  GLuint CreateProgram() override { return GenId(&programs_); }
-
-  GLuint CreateShader(GLenum type) override { return GenId(&shaders_); }
-
-  void BindTexture(GLenum target, GLuint texture) override {
-    CheckId(&textures_, texture);
-  }
-
-  void BindBuffer(GLenum target, GLuint buffer) override {
-    CheckId(&buffers_, buffer);
-  }
-
-  void BindRenderbuffer(GLenum target, GLuint renderbuffer) override {
-    CheckId(&renderbuffers_, renderbuffer);
-  }
-
-  void BindFramebuffer(GLenum target, GLuint framebuffer) override {
-    CheckId(&framebuffers_, framebuffer);
-  }
-
-  void UseProgram(GLuint program) override { CheckId(&programs_, program); }
-
-  void DeleteTextures(GLsizei n, const GLuint* textures) override {
-    DeleteIds(&textures_, n, textures);
-  }
-
-  void DeleteBuffers(GLsizei n, const GLuint* buffers) override {
-    DeleteIds(&buffers_, n, buffers);
-  }
-
-  void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override {
-    DeleteIds(&framebuffers_, n, framebuffers);
-  }
-
-  void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override {
-    DeleteIds(&renderbuffers_, n, renderbuffers);
-  }
-
-  void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override {
-    DeleteIds(&queries_, n, queries);
-  }
-
-  void DeleteProgram(GLuint program) override { DeleteId(&programs_, program); }
-
-  void DeleteShader(GLuint shader) override { DeleteId(&shaders_, shader); }
-
-  void BufferData(GLenum target,
-                  GLsizeiptr size,
-                  const void* data,
-                  GLenum usage) override {}
-
- private:
-  GLuint GenId(std::set<GLuint>* resource_set) {
-    GLuint id = next_id_++;
-    resource_set->insert(id);
-    return id;
-  }
-
-  void GenIds(std::set<GLuint>* resource_set, GLsizei n, GLuint* ids) {
-    for (GLsizei i = 0; i < n; ++i)
-      ids[i] = GenId(resource_set);
-  }
-
-  void CheckId(std::set<GLuint>* resource_set, GLuint id) {
-    if (id == 0)
-      return;
-    EXPECT_TRUE(resource_set->find(id) != resource_set->end());
-  }
-
-  void DeleteId(std::set<GLuint>* resource_set, GLuint id) {
-    if (id == 0)
-      return;
-    size_t num_erased = resource_set->erase(id);
-    EXPECT_EQ(1u, num_erased);
-  }
-
-  void DeleteIds(std::set<GLuint>* resource_set, GLsizei n, const GLuint* ids) {
-    for (GLsizei i = 0; i < n; ++i)
-      DeleteId(resource_set, ids[i]);
-  }
-
-  GLuint next_id_ = 1;
-  std::set<GLuint> textures_;
-  std::set<GLuint> buffers_;
-  std::set<GLuint> framebuffers_;
-  std::set<GLuint> renderbuffers_;
-  std::set<GLuint> queries_;
-  std::set<GLuint> shaders_;
-  std::set<GLuint> programs_;
-};
-
-TEST_F(GLRendererTest, NoResourceLeak) {
-  auto gl_owned = std::make_unique<ResourceTrackingGLES2Interface>();
-  auto* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  auto output_surface = FakeOutputSurface::Create3d(std::move(provider));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  {
-    RendererSettings settings;
-    FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                            resource_provider.get());
-    renderer.Initialize();
-    renderer.SetVisible(true);
-
-    gfx::Size viewport_size(100, 100);
-
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-    root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-  }
-  gl->CheckNoResources();
-}
-
-class DrawElementsGLES2Interface : public TestGLES2Interface {
- public:
-  MOCK_METHOD4(
-      DrawElements,
-      void(GLenum mode, GLsizei count, GLenum type, const void* indices));
-};
-
-class GLRendererSkipTest : public GLRendererTest {
- protected:
-  GLRendererSkipTest() {
-    auto gl_owned = std::make_unique<StrictMock<DrawElementsGLES2Interface>>();
-    gl_owned->set_have_post_sub_buffer(true);
-    gl_ = gl_owned.get();
-
-    auto provider = TestContextProvider::Create(std::move(gl_owned));
-    provider->BindToCurrentThread();
-
-    output_surface_ = FakeOutputSurface::Create3d(std::move(provider));
-    output_surface_->BindToClient(&output_surface_client_);
-
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-    settings_.partial_swap_enabled = true;
-    renderer_ = std::make_unique<FakeRendererGL>(&settings_, &debug_settings_,
-                                                 output_surface_.get(),
-                                                 resource_provider_.get());
-    renderer_->Initialize();
-    renderer_->SetVisible(true);
-  }
-
-  void DrawBlackFrame(const gfx::Size& viewport_size) {
-    // The feature enables a faster path to draw solid color quads that does not
-    // use GL draw calls but instead uses glClear.
-    if (!features::IsUsingFastPathForSolidColorQuad())
-      EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
-
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    root_pass->damage_rect = gfx::Rect(viewport_size);
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorBLACK);
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    Mock::VerifyAndClearExpectations(gl_);
-  }
-
-  StrictMock<DrawElementsGLES2Interface>* gl_;
-  RendererSettings settings_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-};
-
-TEST_F(GLRendererSkipTest, DrawQuad) {
-  gfx::Size viewport_size(100, 100);
-  gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
-
-  // Draw the a black frame to make sure output surface is reshaped before
-  // tests.
-  DrawBlackFrame(viewport_size);
-
-  EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = gfx::Rect(0, 0, 25, 25);
-  cc::AddQuad(root_pass, quad_rect, SK_ColorGREEN);
-
-  // Add rounded corners to the solid color draw quad so that the fast path
-  // of drawing using glClear is not used.
-  root_pass->shared_quad_state_list.front()->mask_filter_info =
-      gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 2.f));
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(renderer_.get(), viewport_size);
-}
-
-TEST_F(GLRendererSkipTest, SkipVisibleRect) {
-  gfx::Size viewport_size(100, 100);
-  gfx::Rect quad_rect = gfx::Rect(0, 0, 40, 40);
-
-  // Draw the a black frame to make sure output surface is reshaped before
-  // tests.
-  DrawBlackFrame(viewport_size);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = gfx::Rect(0, 0, 10, 10);
-  cc::AddQuad(root_pass, quad_rect, SK_ColorGREEN);
-  root_pass->shared_quad_state_list.front()->clip_rect =
-      gfx::Rect(0, 0, 40, 40);
-  root_pass->quad_list.front()->visible_rect = gfx::Rect(20, 20, 20, 20);
-
-  // Add rounded corners to the solid color draw quad so that the fast path
-  // of drawing using glClear is not used.
-  root_pass->shared_quad_state_list.front()->mask_filter_info =
-      gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 1.f));
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(renderer_.get(), viewport_size);
-  // DrawElements should not be called because the visible rect is outside the
-  // scissor, even though the clip rect and quad rect intersect the scissor.
-}
-
-TEST_F(GLRendererSkipTest, SkipClippedQuads) {
-  gfx::Size viewport_size(100, 100);
-  gfx::Rect quad_rect = gfx::Rect(25, 25, 90, 90);
-
-  // Draw the a black frame to make sure output surface is reshaped before
-  // tests.
-  DrawBlackFrame(viewport_size);
-
-  AggregatedRenderPassId root_pass_id{1};
-
-  auto* root_pass = cc::AddRenderPass(&render_passes_in_draw_order_,
-                                      root_pass_id, gfx::Rect(viewport_size),
-                                      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = gfx::Rect(0, 0, 25, 25);
-  cc::AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
-  root_pass->quad_list.front()->rect = gfx::Rect(20, 20, 20, 20);
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(renderer_.get(), viewport_size);
-  // DrawElements should not be called because the clip rect is outside the
-  // scissor.
-}
-
-TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
-  // When using render-to-FBO to display the surface, all rendering is done
-  // to a non-zero FBO. Make sure that the framebuffer is always restored to
-  // the correct framebuffer during rendering, if changed.
-  // Note: there is one path that will set it to 0, but that is after the render
-  // has finished.
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d());
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  EXPECT_FALSE(renderer.use_partial_swap());
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(100, 100);
-  gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  cc::AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
-
-  unsigned fbo;
-  gpu::gles2::GLES2Interface* gl =
-      output_surface->context_provider()->ContextGL();
-  gl->GenFramebuffers(1, &fbo);
-  output_surface->set_framebuffer(fbo, GL_RGB);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(&renderer, viewport_size);
-
-  int bound_fbo;
-  gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
-  EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
-}
-
-TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
-  gfx::Size viewport_size(60, 75);
-
-  gfx::Rect child_rect(50, 50);
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPass* child_pass;
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass;
-
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-      child_rect.size(), false /* is_overlay_candidate */);
-  ResourceId mask = child_resource_provider_->ImportResource(transfer_resource,
-                                                             base::DoNothing());
-
-  // Return the mapped resource id.
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      cc::SendResourceAndGetChildToParentMap({mask}, resource_provider_.get(),
-                                             child_resource_provider_.get(),
-                                             child_context_provider_.get());
-  ResourceId mapped_mask = resource_map[mask];
-
-  float matrix[20];
-  float amount = 0.5f;
-  matrix[0] = 0.213f + 0.787f * amount;
-  matrix[1] = 0.715f - 0.715f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = matrix[4] = 0;
-  matrix[5] = 0.213f - 0.213f * amount;
-  matrix[6] = 0.715f + 0.285f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = matrix[9] = 0;
-  matrix[10] = 0.213f - 0.213f * amount;
-  matrix[11] = 0.715f - 0.715f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = matrix[14] = 0;
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
-  matrix[18] = 1;
-  cc::FilterOperations filters;
-  filters.Append(cc::FilterOperation::CreateReferenceFilter(
-      sk_make_sp<cc::ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix),
-                                             nullptr)));
-
-  gfx::Transform transform_causing_aa;
-  transform_causing_aa.Rotate(20.0);
-
-  for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
-    BlendMode blend_mode = static_cast<BlendMode>(i);
-    SkBlendMode xfer_mode = BlendModeToSkXfermode(blend_mode);
-    settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
-    // RenderPassProgram
-    render_passes_in_draw_order_.clear();
-    child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          child_rect, gfx::Transform(), cc::FilterOperations());
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassColorMatrixProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, transform_causing_aa, filters);
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassMaskProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          child_rect, gfx::Transform(), cc::FilterOperations());
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask, gfx::Transform(),
-                          xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
-                              blend_mode);
-
-    // RenderPassMaskColorMatrixProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, gfx::Transform(), filters);
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask, gfx::Transform(),
-                          xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
-                                         SAMPLER_TYPE_2D, blend_mode);
-
-    // RenderPassProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, transform_causing_aa,
-                                   cc::FilterOperations());
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassColorMatrixProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, transform_causing_aa, filters);
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassMaskProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, transform_causing_aa,
-                                   cc::FilterOperations());
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size), gfx::Transform(),
-                                  cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask,
-                          transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
-                                blend_mode);
-
-    // RenderPassMaskColorMatrixProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                   child_rect, transform_causing_aa, filters);
-
-    root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                  gfx::Rect(viewport_size),
-                                  transform_causing_aa, cc::FilterOperations());
-
-    cc::AddRenderPassQuad(root_pass, child_pass, mapped_mask,
-                          transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(renderer_.get(), viewport_size);
-    TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
-                                           SAMPLER_TYPE_2D, blend_mode);
-  }
-}
-
-// At this time, the AA code path cannot be taken if the surface's rect would
-// project incorrectly by the given transform, because of w<0 clipping.
-TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
-  gfx::Rect child_rect(50, 50);
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPass* child_pass;
-
-  gfx::Size viewport_size(100, 100);
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass;
-
-  gfx::Transform transform_preventing_aa;
-  transform_preventing_aa.ApplyPerspectiveDepth(40.0);
-  transform_preventing_aa.RotateAboutYAxis(-20.0);
-  transform_preventing_aa.Scale(30.0, 1.0);
-
-  // Verify that the test transform and test rect actually do cause the clipped
-  // flag to trigger. Otherwise we are not testing the intended scenario.
-  bool clipped = false;
-  cc::MathUtil::MapQuad(transform_preventing_aa,
-                        gfx::QuadF(gfx::RectF(child_rect)), &clipped);
-  ASSERT_TRUE(clipped);
-
-  child_pass = cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                                 child_rect, transform_preventing_aa,
-                                 cc::FilterOperations());
-
-  root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                gfx::Rect(viewport_size), gfx::Transform(),
-                                cc::FilterOperations());
-
-  cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                        transform_preventing_aa, SkBlendMode::kSrcOver);
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(renderer_.get(), viewport_size);
-
-  // If use_aa incorrectly ignores clipping, it will use the
-  // RenderPassProgramAA shader instead of the RenderPassProgram.
-  TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
-}
-
-TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
-  gfx::Size viewport_size(30, 30);  // Don't translate out of the viewport.
-  gfx::Size quad_size(3, 3);
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass;
-
-  gfx::Transform pixel_aligned_transform_causing_aa;
-  pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
-  pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
-
-  root_pass = cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                                gfx::Rect(viewport_size), gfx::Transform(),
-                                cc::FilterOperations());
-  cc::AddTransformedQuad(root_pass, gfx::Rect(quad_size), SK_ColorYELLOW,
-                         pixel_aligned_transform_causing_aa);
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(renderer_.get(), viewport_size);
-
-  TestSolidColorProgramAA();
-}
-
-class OutputSurfaceMockGLES2Interface : public TestGLES2Interface {
- public:
-  OutputSurfaceMockGLES2Interface() = default;
-
-  // Specifically override methods even if they are unused (used in conjunction
-  // with StrictMock). We need to make sure that GLRenderer does not issue
-  // framebuffer-related GLuint calls directly. Instead these are supposed to go
-  // through the OutputSurface abstraction.
-  MOCK_METHOD2(BindFramebuffer, void(GLenum target, GLuint framebuffer));
-  MOCK_METHOD5(ResizeCHROMIUM,
-               void(GLuint width,
-                    GLuint height,
-                    float device_scale,
-                    GLcolorSpace color_space,
-                    GLboolean has_alpha));
-  MOCK_METHOD4(
-      DrawElements,
-      void(GLenum mode, GLsizei count, GLenum type, const void* indices));
-};
-
-class MockOutputSurface : public OutputSurface {
- public:
-  explicit MockOutputSurface(scoped_refptr<ContextProvider> provider)
-      : OutputSurface(std::move(provider)) {}
-  ~MockOutputSurface() override {}
-
-  void BindToClient(OutputSurfaceClient*) override {}
-  unsigned UpdateGpuFence() override { return 0; }
-
-  MOCK_METHOD0(EnsureBackbuffer, void());
-  MOCK_METHOD0(DiscardBackbuffer, void());
-  MOCK_METHOD5(Reshape,
-               void(const gfx::Size& size,
-                    float scale_factor,
-                    const gfx::ColorSpace& color_space,
-                    gfx::BufferFormat format,
-                    bool use_stencil));
-  MOCK_METHOD0(BindFramebuffer, void());
-  MOCK_METHOD1(SetDrawRectangle, void(const gfx::Rect&));
-  MOCK_METHOD1(SetEnableDCLayers, void(bool));
-  MOCK_METHOD0(GetFramebufferCopyTextureFormat, GLenum());
-  MOCK_METHOD1(SwapBuffers_, void(OutputSurfaceFrame& frame));  // NOLINT
-  void SwapBuffers(OutputSurfaceFrame frame) override { SwapBuffers_(frame); }
-  MOCK_CONST_METHOD0(IsDisplayedAsOverlayPlane, bool());
-  MOCK_CONST_METHOD0(GetOverlayTextureId, unsigned());
-  MOCK_CONST_METHOD0(HasExternalStencilTest, bool());
-  MOCK_METHOD0(ApplyExternalStencil, void());
-  MOCK_METHOD1(SetUpdateVSyncParametersCallback,
-               void(UpdateVSyncParametersCallback));
-  MOCK_METHOD1(SetDisplayTransformHint, void(gfx::OverlayTransform));
-
-  gfx::OverlayTransform GetDisplayTransform() override {
-    return gfx::OVERLAY_TRANSFORM_NONE;
-  }
-};
-
-class MockOutputSurfaceTest : public GLRendererTest {
- protected:
-  void SetUp() override {
-    auto gl = std::make_unique<StrictMock<OutputSurfaceMockGLES2Interface>>();
-    gl->set_have_post_sub_buffer(true);
-    gl_ = gl.get();
-    auto provider = TestContextProvider::Create(std::move(gl));
-    provider->BindToCurrentThread();
-    output_surface_ =
-        std::make_unique<StrictMock<MockOutputSurface>>(std::move(provider));
-
-    output_surface_->BindToClient(&output_surface_client_);
-
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-
-    renderer_ = std::make_unique<FakeRendererGL>(&settings_, &debug_settings_,
-                                                 output_surface_.get(),
-                                                 resource_provider_.get());
-    renderer_->Initialize();
-
-    EXPECT_CALL(*output_surface_, EnsureBackbuffer()).Times(1);
-    renderer_->SetVisible(true);
-    Mock::VerifyAndClearExpectations(output_surface_.get());
-  }
-
-  void SwapBuffers() {
-    renderer_->SwapBuffers(DirectRenderer::SwapFrameData());
-  }
-
-  void DrawFrame(float device_scale_factor,
-                 const gfx::Size& viewport_size,
-                 bool transparent) {
-    gfx::BufferFormat format = transparent ? gfx::BufferFormat::RGBA_8888
-                                           : gfx::BufferFormat::RGBX_8888;
-    AggregatedRenderPassId render_pass_id{1};
-    AggregatedRenderPass* render_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, render_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(render_pass, gfx::Rect(viewport_size), SK_ColorGREEN);
-    render_pass->has_transparent_background = transparent;
-
-    EXPECT_CALL(*output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
-
-    EXPECT_CALL(*output_surface_,
-                Reshape(viewport_size, device_scale_factor, _, format, _))
-        .Times(1);
-
-    EXPECT_CALL(*output_surface_, BindFramebuffer()).Times(1);
-
-    EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(1);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    SurfaceDamageRectList surface_damage_rect_list;
-    renderer_->DrawFrame(&render_passes_in_draw_order_, device_scale_factor,
-                         viewport_size, gfx::DisplayColorSpaces(),
-                         std::move(surface_damage_rect_list));
-  }
-
-  RendererSettings settings_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  OutputSurfaceMockGLES2Interface* gl_ = nullptr;
-  std::unique_ptr<StrictMock<MockOutputSurface>> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-};
-
-TEST_F(MockOutputSurfaceTest, BackbufferDiscard) {
-  // Drop backbuffer on hide.
-  EXPECT_CALL(*output_surface_, DiscardBackbuffer()).Times(1);
-  renderer_->SetVisible(false);
-  Mock::VerifyAndClearExpectations(output_surface_.get());
-
-  // Restore backbuffer on show.
-  EXPECT_CALL(*output_surface_, EnsureBackbuffer()).Times(1);
-  renderer_->SetVisible(true);
-  Mock::VerifyAndClearExpectations(output_surface_.get());
-}
-
-#if BUILDFLAG(IS_WIN)
-class MockDCLayerOverlayProcessor : public DCLayerOverlayProcessor {
- public:
-  MockDCLayerOverlayProcessor()
-      : DCLayerOverlayProcessor(&debug_settings_,
-                                /*allowed_yuv_overlay_count=*/1,
-                                true) {}
-  ~MockDCLayerOverlayProcessor() override = default;
-  MOCK_METHOD8(Process,
-               void(DisplayResourceProvider* resource_provider,
-                    const gfx::RectF& display_rect,
-                    const FilterOperationsMap& render_pass_filters,
-                    const FilterOperationsMap& render_pass_backdrop_filters,
-                    AggregatedRenderPassList* render_passes,
-                    gfx::Rect* damage_rect,
-                    SurfaceDamageRectList surface_damage_rect_list,
-                    DCLayerOverlayList* dc_layer_overlays));
-
- protected:
-  DebugRendererSettings debug_settings_;
-};
-class TestOverlayProcessor : public OverlayProcessorWin {
- public:
-  explicit TestOverlayProcessor(OutputSurface* output_surface)
-      : OverlayProcessorWin(output_surface,
-                            std::make_unique<MockDCLayerOverlayProcessor>()) {}
-  ~TestOverlayProcessor() override = default;
-
-  MockDCLayerOverlayProcessor* GetTestProcessor() {
-    return static_cast<MockDCLayerOverlayProcessor*>(GetOverlayProcessor());
-  }
-};
-#elif BUILDFLAG(IS_APPLE)
-class MockCALayerOverlayProcessor : public CALayerOverlayProcessor {
- public:
-  MockCALayerOverlayProcessor() : CALayerOverlayProcessor(true) {}
-  ~MockCALayerOverlayProcessor() override = default;
-
-  MOCK_METHOD6(
-      ProcessForCALayerOverlays,
-      bool(AggregatedRenderPass* render_pass,
-           DisplayResourceProvider* resource_provider,
-           const gfx::RectF& display_rect,
-           const base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>&
-               render_pass_filters,
-           const base::flat_map<AggregatedRenderPassId, cc::FilterOperations*>&
-               render_pass_backdrop_filters,
-           CALayerOverlayList* ca_layer_overlays));
-};
-
-class TestOverlayProcessor : public OverlayProcessorMac {
- public:
-  explicit TestOverlayProcessor(OutputSurface* output_surface)
-      : OverlayProcessorMac(std::make_unique<MockCALayerOverlayProcessor>()) {}
-  ~TestOverlayProcessor() override = default;
-
-  MockCALayerOverlayProcessor* GetTestProcessor() {
-    return static_cast<MockCALayerOverlayProcessor*>(GetOverlayProcessor());
-  }
-};
-
-#elif BUILDFLAG(IS_ANDROID) || defined(USE_OZONE)
-
-class TestOverlayProcessor : public OverlayProcessorUsingStrategy {
- public:
-  class TestStrategy : public OverlayProcessorStrategy {
-   public:
-    TestStrategy() = default;
-    ~TestStrategy() override = default;
-
-    MOCK_METHOD8(
-        Attempt,
-        bool(const SkM44& output_color_matrix,
-             const OverlayProcessorInterface::FilterOperationsMap&
-                 render_pass_backdrop_filters,
-             DisplayResourceProvider* resource_provider,
-             AggregatedRenderPassList* render_pass_list,
-             SurfaceDamageRectList* surface_damage_rect_list,
-             const OverlayProcessorInterface::OutputSurfaceOverlayPlane*
-                 primary_surface,
-             OverlayCandidateList* candidates,
-             std::vector<gfx::Rect>* content_bounds));
-
-    void ProposePrioritized(
-        const SkM44& output_color_matrix,
-        const FilterOperationsMap& render_pass_backdrop_filters,
-        DisplayResourceProvider* resource_provider,
-        AggregatedRenderPassList* render_pass_list,
-        SurfaceDamageRectList* surface_damage_rect_list,
-        const PrimaryPlane* primary_plane,
-        std::vector<OverlayProposedCandidate>* candidates,
-        std::vector<gfx::Rect>* content_bounds) override {
-      auto* render_pass = render_pass_list->back().get();
-      QuadList& quad_list = render_pass->quad_list;
-      OverlayCandidate candidate;
-      candidates->push_back({quad_list.end(), candidate, this});
-    }
-
-    MOCK_METHOD9(AttemptPrioritized,
-                 bool(const SkM44& output_color_matrix,
-                      const FilterOperationsMap& render_pass_backdrop_filters,
-                      DisplayResourceProvider* resource_provider,
-                      AggregatedRenderPassList* render_pass_list,
-                      SurfaceDamageRectList* surface_damage_rect_list,
-                      const PrimaryPlane* primary_plane,
-                      OverlayCandidateList* candidates,
-                      std::vector<gfx::Rect>* content_bounds,
-                      const OverlayProposedCandidate& proposed_candidate));
-
-    MOCK_METHOD2(CommitCandidate,
-                 void(const OverlayProposedCandidate& proposed_candidate,
-                      AggregatedRenderPass* render_pass));
-  };
-
-  bool IsOverlaySupported() const override { return true; }
-
-  // A list of possible overlay candidates is presented to this function.
-  // The expected result is that those candidates that can be in a separate
-  // plane are marked with |overlay_handled| set to true, otherwise they are
-  // to be traditionally composited. Candidates with |overlay_handled| set to
-  // true must also have their |display_rect| converted to integer
-  // coordinates if necessary.
-  void CheckOverlaySupportImpl(
-      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
-      OverlayCandidateList* surfaces) override {}
-
-  TestStrategy& strategy() {
-    auto* strategy = strategies_.back().get();
-    return *(static_cast<TestStrategy*>(strategy));
-  }
-
-  MOCK_CONST_METHOD0(NeedsSurfaceDamageRectList, bool());
-  explicit TestOverlayProcessor(OutputSurface* output_surface) {
-    strategies_.push_back(std::make_unique<TestStrategy>());
-    prioritization_config_.changing_threshold = false;
-    prioritization_config_.damage_rate_threshold = false;
-  }
-  ~TestOverlayProcessor() override = default;
-};
-#else  // Default to no overlay.
-class TestOverlayProcessor : public OverlayProcessorStub {
- public:
-  explicit TestOverlayProcessor(OutputSurface* output_surface)
-      : OverlayProcessorStub() {}
-  ~TestOverlayProcessor() override = default;
-};
-#endif
-
-void MailboxReleased(const gpu::SyncToken& sync_token, bool lost_resource) {}
-
-static void CollectResources(std::vector<ReturnedResource>* array,
-                             std::vector<ReturnedResource> returned) {
-  array->insert(array->end(), std::make_move_iterator(returned.begin()),
-                std::make_move_iterator(returned.end()));
-}
-
-TEST_F(GLRendererTest, DontOverlayWithCopyRequests) {
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d());
-#if BUILDFLAG(IS_WIN)
-  output_surface->set_supports_dc_layers(true);
-#endif
-  output_surface->BindToClient(&output_surface_client);
-
-  auto parent_resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  auto child_context_provider = TestContextProvider::Create();
-  child_context_provider->BindToCurrentThread();
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-      gfx::Size(256, 256), true);
-  auto release_callback = base::BindOnce(&MailboxReleased);
-  ResourceId resource_id = child_resource_provider->ImportResource(
-      transfer_resource, std::move(release_callback));
-
-  std::vector<ReturnedResource> returned_to_child;
-  int child_id = parent_resource_provider->CreateChild(
-      base::BindRepeating(&CollectResources, &returned_to_child), SurfaceId());
-
-  // Transfer resource to the parent.
-  std::vector<ResourceId> resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(resource_id);
-  std::vector<TransferableResource> list;
-  child_resource_provider->PrepareSendToParent(
-      resource_ids_to_transfer, &list,
-      static_cast<RasterContextProvider*>(child_context_provider.get()));
-  parent_resource_provider->ReceiveFromChild(child_id, list);
-
-  // In DisplayResourceProvider's namespace, use the mapped resource id.
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      parent_resource_provider->GetChildToParentMap(child_id);
-  ResourceId parent_resource_id = resource_map[list[0].id];
-
-  auto processor = std::make_unique<TestOverlayProcessor>(output_surface.get());
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          parent_resource_provider.get(), processor.get(),
-                          base::ThreadTaskRunnerHandle::Get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-#if BUILDFLAG(IS_APPLE)
-  MockCALayerOverlayProcessor* mock_ca_processor =
-      processor->GetTestProcessor();
-#elif BUILDFLAG(IS_WIN)
-  MockDCLayerOverlayProcessor* dc_processor = processor->GetTestProcessor();
-#endif
-
-  gfx::Size viewport_size(1, 1);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-  root_pass->copy_requests.push_back(CopyOutputRequest::CreateStubForTesting());
-
-  bool needs_blending = false;
-  bool premultiplied_alpha = false;
-  bool flipped = false;
-  bool nearest_neighbor = false;
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
-  TextureDrawQuad* overlay_quad =
-      root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  overlay_quad->SetNew(
-      root_pass->CreateAndAppendSharedQuadState(), gfx::Rect(viewport_size),
-      gfx::Rect(viewport_size), needs_blending, parent_resource_id,
-      premultiplied_alpha, gfx::PointF(0, 0), gfx::PointF(1, 1),
-      SK_ColorTRANSPARENT, vertex_opacity, flipped, nearest_neighbor,
-      /*secure_output_only=*/false, gfx::ProtectedVideoType::kClear);
-
-  // DirectRenderer::DrawFrame calls into OverlayProcessor::ProcessForOverlays.
-  // Attempt will be called for each strategy in OverlayProcessor. We have
-  // added a fake strategy, so checking for Attempt calls checks if there was
-  // any attempt to overlay, which there shouldn't be. We can't use the quad
-  // list because the render pass is cleaned up by DrawFrame.
-#if defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-  if (features::IsOverlayPrioritizationEnabled()) {
-    EXPECT_CALL(processor->strategy(),
-                AttemptPrioritized(_, _, _, _, _, _, _, _, _))
-        .Times(0);
-  } else {
-    EXPECT_CALL(processor->strategy(), Attempt(_, _, _, _, _, _, _, _))
-        .Times(0);
-  }
-#elif BUILDFLAG(IS_APPLE)
-  EXPECT_CALL(*mock_ca_processor, ProcessForCALayerOverlays(_, _, _, _, _, _))
-      .WillOnce(Return(false));
-#elif BUILDFLAG(IS_WIN)
-  EXPECT_CALL(*dc_processor, Process(_, _, _, _, _, _, _, _)).Times(0);
-#endif
-  DrawFrame(&renderer, viewport_size);
-#if defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-  Mock::VerifyAndClearExpectations(&processor->strategy());
-#elif BUILDFLAG(IS_APPLE)
-  Mock::VerifyAndClearExpectations(
-      const_cast<MockCALayerOverlayProcessor*>(mock_ca_processor));
-#elif BUILDFLAG(IS_WIN)
-  Mock::VerifyAndClearExpectations(
-      const_cast<MockDCLayerOverlayProcessor*>(dc_processor));
-#endif
-
-  // Without a copy request Attempt() should be called once.
-  root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  overlay_quad->SetNew(
-      root_pass->CreateAndAppendSharedQuadState(), gfx::Rect(viewport_size),
-      gfx::Rect(viewport_size), needs_blending, parent_resource_id,
-      premultiplied_alpha, gfx::PointF(0, 0), gfx::PointF(1, 1),
-      SK_ColorTRANSPARENT, vertex_opacity, flipped, nearest_neighbor,
-      /*secure_output_only=*/false, gfx::ProtectedVideoType::kClear);
-#if defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-  if (features::IsOverlayPrioritizationEnabled()) {
-    EXPECT_CALL(processor->strategy(),
-                AttemptPrioritized(_, _, _, _, _, _, _, _, _))
-        .Times(1);
-  } else {
-    EXPECT_CALL(processor->strategy(), Attempt(_, _, _, _, _, _, _, _))
-        .Times(1);
-  }
-#elif BUILDFLAG(IS_APPLE)
-  EXPECT_CALL(*mock_ca_processor, ProcessForCALayerOverlays(_, _, _, _, _, _))
-      .WillOnce(Return(true));
-#elif BUILDFLAG(IS_WIN)
-  EXPECT_CALL(*dc_processor, Process(_, _, _, _, _, _, _, _)).Times(1);
-#endif
-  DrawFrame(&renderer, viewport_size);
-
-  // Transfer resources back from the parent to the child. Set no resources as
-  // being in use.
-  parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
-                                                          ResourceIdSet());
-
-  child_resource_provider->RemoveImportedResource(resource_id);
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-
-#if BUILDFLAG(IS_ANDROID) || defined(USE_OZONE)
-class SingleOverlayOnTopProcessor : public OverlayProcessorUsingStrategy {
- public:
-  SingleOverlayOnTopProcessor() : OverlayProcessorUsingStrategy() {
-    strategies_.push_back(std::make_unique<OverlayStrategySingleOnTop>(this));
-    strategies_.push_back(std::make_unique<OverlayStrategyUnderlay>(this));
-    prioritization_config_.changing_threshold = false;
-    prioritization_config_.damage_rate_threshold = false;
-  }
-
-  bool NeedsSurfaceDamageRectList() const override { return true; }
-  bool IsOverlaySupported() const override { return true; }
-
-  void CheckOverlaySupportImpl(
-      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
-      OverlayCandidateList* surfaces) override {
-    if (!multiple_candidates_)
-      ASSERT_EQ(1U, surfaces->size());
-    OverlayCandidate& candidate = surfaces->back();
-    candidate.overlay_handled = true;
-  }
-
-  void AllowMultipleCandidates() { multiple_candidates_ = true; }
-
- private:
-  bool multiple_candidates_ = false;
-};
-
-class WaitSyncTokenCountingGLES2Interface : public TestGLES2Interface {
- public:
-  MOCK_METHOD1(WaitSyncTokenCHROMIUM, void(const GLbyte* sync_token));
-};
-
-class MockOverlayScheduler {
- public:
-  MOCK_METHOD7(Schedule,
-               void(int plane_z_order,
-                    gfx::OverlayTransform plane_transform,
-                    unsigned overlay_texture_id,
-                    const gfx::Rect& display_bounds,
-                    const gfx::RectF& uv_rect,
-                    bool enable_blend,
-                    unsigned gpu_fence_id));
-};
-
-TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) {
-  auto gl_owned = std::make_unique<WaitSyncTokenCountingGLES2Interface>();
-  WaitSyncTokenCountingGLES2Interface* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  MockOverlayScheduler overlay_scheduler;
-  provider->support()->SetScheduleOverlayPlaneCallback(base::BindRepeating(
-      &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler)));
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto parent_resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  auto child_context_provider = TestContextProvider::Create();
-  child_context_provider->BindToCurrentThread();
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  gpu::SyncToken sync_token(gpu::CommandBufferNamespace::GPU_IO,
-                            gpu::CommandBufferId::FromUnsafeValue(0x123), 29);
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, sync_token,
-      gfx::Size(256, 256), true);
-  auto release_callback = base::BindOnce(&MailboxReleased);
-  ResourceId resource_id = child_resource_provider->ImportResource(
-      transfer_resource, std::move(release_callback));
-
-  std::vector<ReturnedResource> returned_to_child;
-  int child_id = parent_resource_provider->CreateChild(
-      base::BindRepeating(&CollectResources, &returned_to_child), SurfaceId());
-
-  // Transfer resource to the parent.
-  std::vector<ResourceId> resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(resource_id);
-  std::vector<TransferableResource> list;
-  child_resource_provider->PrepareSendToParent(
-      resource_ids_to_transfer, &list,
-      static_cast<RasterContextProvider*>(child_context_provider.get()));
-  parent_resource_provider->ReceiveFromChild(child_id, list);
-
-  // In DisplayResourceProvider's namespace, use the mapped resource id.
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      parent_resource_provider->GetChildToParentMap(child_id);
-  ResourceId parent_resource_id = resource_map[list[0].id];
-
-  RendererSettings settings;
-  auto processor = std::make_unique<SingleOverlayOnTopProcessor>();
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          parent_resource_provider.get(), processor.get(),
-                          base::ThreadTaskRunnerHandle::Get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(1, 1);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  bool needs_blending = false;
-  bool premultiplied_alpha = false;
-  bool flipped = false;
-  bool nearest_neighbor = false;
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  gfx::PointF uv_top_left(0, 0);
-  gfx::PointF uv_bottom_right(1, 1);
-
-  TextureDrawQuad* overlay_quad =
-      root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size),
-                       gfx::Rect(viewport_size), gfx::MaskFilterInfo(),
-                       absl::nullopt, false, 1, SkBlendMode::kSrcOver, 0);
-  overlay_quad->SetNew(shared_state, gfx::Rect(viewport_size),
-                       gfx::Rect(viewport_size), needs_blending,
-                       parent_resource_id, premultiplied_alpha, uv_top_left,
-                       uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
-                       flipped, nearest_neighbor, /*secure_output_only=*/false,
-                       gfx::ProtectedVideoType::kClear);
-
-  // The verified flush flag will be set by
-  // ClientResourceProvider::PrepareSendToParent. Before checking if the
-  // gpu::SyncToken matches, set this flag first.
-  sync_token.SetVerifyFlush();
-
-  // Verify that overlay_quad actually gets turned into an overlay, and even
-  // though it's not drawn, that its sync point is waited on.
-  EXPECT_CALL(*gl, WaitSyncTokenCHROMIUM(MatchesSyncToken(sync_token)))
-      .Times(1);
-
-  EXPECT_CALL(
-      overlay_scheduler,
-      Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, gfx::Rect(viewport_size),
-               BoundingRect(uv_top_left, uv_bottom_right), _, _))
-      .Times(1);
-
-  DrawFrame(&renderer, viewport_size);
-
-  // Transfer resources back from the parent to the child. Set no resources as
-  // being in use.
-  parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
-                                                          ResourceIdSet());
-
-  child_resource_provider->RemoveImportedResource(resource_id);
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-#endif  // defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-
-class OutputColorMatrixMockGLES2Interface : public TestGLES2Interface {
- public:
-  OutputColorMatrixMockGLES2Interface() = default;
-
-  MOCK_METHOD4(UniformMatrix4fv,
-               void(GLint location,
-                    GLsizei count,
-                    GLboolean transpose,
-                    const GLfloat* value));
-};
-
-TEST_F(GLRendererTest, OutputColorMatrixTest) {
-  // Initialize the mock GL interface, the output surface and the renderer.
-  auto gl_owned = std::make_unique<OutputColorMatrixMockGLES2Interface>();
-  auto* gl = gl_owned.get();
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-  std::unique_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  cc::FakeOutputSurfaceClient output_surface_client;
-  output_surface->BindToClient(&output_surface_client);
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  // Set a non-identity color matrix on the output surface.
-  SkM44 color_matrix;
-  color_matrix.setRC(0, 0, 0.7f);
-  color_matrix.setRC(1, 1, 0.4f);
-  color_matrix.setRC(2, 2, 0.5f);
-  output_surface->set_color_matrix(color_matrix);
-
-  // Create a root and a child passes to test that the output color matrix is
-  // registered only for the root pass.
-  gfx::Size viewport_size(100, 100);
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPass* child_pass =
-      cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                        gfx::Rect(viewport_size) + gfx::Vector2d(1, 2),
-                        gfx::Transform(), cc::FilterOperations());
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = gfx::Rect(0, 0, 25, 25);
-  cc::AddRenderPassQuad(root_pass, child_pass);
-
-  // Verify that UniformMatrix4fv() is called only once on the root pass with
-  // the correct matrix values.
-  int call_count = 0;
-  bool output_color_matrix_invoked = false;
-  EXPECT_CALL(*gl, UniformMatrix4fv(_, 1, false, _))
-      .WillRepeatedly(testing::WithArgs<0, 3>(testing::Invoke(
-          [&color_matrix, &renderer, &call_count, &output_color_matrix_invoked](
-              int matrix_location, const GLfloat* gl_matrix) {
-            DCHECK(current_program(&renderer));
-            const int color_matrix_location =
-                current_program(&renderer)->output_color_matrix_location();
-
-            if (matrix_location != color_matrix_location)
-              return;
-
-            call_count++;
-            output_color_matrix_invoked = true;
-            float expected_matrix[16];
-            color_matrix.getColMajor(expected_matrix);
-            for (int i = 0; i < 16; ++i)
-              EXPECT_FLOAT_EQ(expected_matrix[i], gl_matrix[i]);
-          })));
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  DrawFrame(&renderer, viewport_size);
-
-  EXPECT_EQ(1, call_count);
-  EXPECT_TRUE(output_color_matrix_invoked);
-}
-
-class GenerateMipmapMockGLESInterface : public TestGLES2Interface {
- public:
-  GenerateMipmapMockGLESInterface() = default;
-
-  MOCK_METHOD3(TexParameteri, void(GLenum target, GLenum pname, GLint param));
-  MOCK_METHOD1(GenerateMipmap, void(GLenum target));
-};
-
-// TODO(crbug.com/803286): Currently npot texture always return false on ubuntu
-// desktop.  The npot texture check is probably failing on desktop GL. This test
-// crashes DCHECK npot texture to catch this. When
-// GLRendererPixelTest.DISABLED_TrilinearFiltering got passed, can remove this.
-TEST_F(GLRendererTest, GenerateMipmap) {
-  // Initialize the mock GL interface, the output surface and the renderer.
-  auto gl_owned = std::make_unique<GenerateMipmapMockGLESInterface>();
-  gl_owned->set_support_texture_npot(true);
-
-  auto* gl = gl_owned.get();
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  std::unique_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  cc::FakeOutputSurfaceClient output_surface_client;
-  output_surface->BindToClient(&output_surface_client);
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          resource_provider.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(100, 100);
-  AggregatedRenderPassId child_pass_id{2};
-  // Create a child pass with mipmap to verify that npot texture is enabled.
-  AggregatedRenderPass* child_pass =
-      cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                        gfx::Rect(viewport_size) + gfx::Vector2d(1, 2),
-                        gfx::Transform(), cc::FilterOperations());
-  child_pass->generate_mipmap = true;
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = gfx::Rect(0, 0, 25, 25);
-  cc::AddRenderPassQuad(root_pass, child_pass);
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  EXPECT_CALL(*gl, TexParameteri(_, _, _)).Times(4);
-  EXPECT_CALL(*gl, GenerateMipmap(GL_TEXTURE_2D)).Times(1);
-  // When generate_mipmap enabled, the GL_TEXTURE_MIN_FILTER should be
-  // GL_LINEAR_MIPMAP_LINEAR.
-  EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-                                 GL_LINEAR_MIPMAP_LINEAR));
-  DrawFrame(&renderer, viewport_size);
-}
-
-class FastSolidColorMockGLES2Interface : public TestGLES2Interface {
- public:
-  FastSolidColorMockGLES2Interface() = default;
-
-  MOCK_METHOD1(Enable, void(GLenum cap));
-  MOCK_METHOD1(Disable, void(GLenum cap));
-  MOCK_METHOD4(ClearColor,
-               void(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha));
-  MOCK_METHOD4(Scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
-};
-
-class GLRendererFastSolidColorTest : public GLRendererTest {
- public:
-  void SetUp() override {
-    feature_list_.InitAndEnableFeature(features::kFastSolidColorDraw);
-    GLRendererTest::SetUp();
-
-    auto gl_owned = std::make_unique<FastSolidColorMockGLES2Interface>();
-    gl_owned->set_have_post_sub_buffer(true);
-    gl_ = gl_owned.get();
-
-    auto provider = TestContextProvider::Create(std::move(gl_owned));
-    provider->BindToCurrentThread();
-
-    output_surface_ = FakeOutputSurface::Create3d(std::move(provider));
-    output_surface_->BindToClient(&output_surface_client_);
-
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-
-    settings_.partial_swap_enabled = true;
-    settings_.slow_down_compositing_scale_factor = 1;
-    settings_.allow_antialiasing = true;
-
-    fake_renderer_ = std::make_unique<FakeRendererGL>(
-        &settings_, &debug_settings_, output_surface_.get(),
-        resource_provider_.get());
-    fake_renderer_->Initialize();
-    EXPECT_TRUE(fake_renderer_->use_partial_swap());
-    fake_renderer_->SetVisible(true);
-  }
-
-  void TearDown() override {
-    resource_provider_.reset();
-    fake_renderer_.reset();
-    output_surface_.reset();
-    gl_ = nullptr;
-
-    GLRendererTest::TearDown();
-  }
-
-  FastSolidColorMockGLES2Interface* gl_ptr() { return gl_; }
-
-  FakeOutputSurface* output_surface() { return output_surface_.get(); }
-
- protected:
-  void AddExpectations(bool use_fast_path,
-                       const gfx::Rect& scissor_rect,
-                       SkColor color = SK_ColorBLACK,
-                       bool enable_stencil = false) {
-    auto* gl = gl_ptr();
-
-    InSequence seq;
-
-    // Restore GL state method calls
-    EXPECT_CALL(*gl, Disable(GL_DEPTH_TEST));
-    EXPECT_CALL(*gl, Disable(GL_CULL_FACE));
-    EXPECT_CALL(*gl, Disable(GL_STENCIL_TEST));
-    EXPECT_CALL(*gl, Enable(GL_BLEND));
-    EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-    EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-
-    if (!enable_stencil)
-      EXPECT_CALL(*gl, ClearColor(0, 0, 0, 0));
-
-    if (use_fast_path) {
-      EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-      EXPECT_CALL(*gl, Scissor(scissor_rect.x(), scissor_rect.y(),
-                               scissor_rect.width(), scissor_rect.height()));
-
-      SkColor4f color_f = SkColor4f::FromColor(color);
-      EXPECT_CALL(*gl,
-                  ClearColor(color_f.fR, color_f.fG, color_f.fB, color_f.fA));
-
-      EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-      EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-    }
-
-    if (enable_stencil) {
-      EXPECT_CALL(*gl, Enable(GL_STENCIL_TEST));
-      EXPECT_CALL(*gl, Disable(GL_BLEND));
-    }
-
-    EXPECT_CALL(*gl, Disable(GL_BLEND));
-  }
-
-  void RunTest(const gfx::Size& viewport_size) {
-    fake_renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(fake_renderer_.get(), viewport_size);
-
-    auto* gl = gl_ptr();
-    ASSERT_TRUE(gl);
-    Mock::VerifyAndClearExpectations(gl);
-  }
-
- private:
-  FastSolidColorMockGLES2Interface* gl_ = nullptr;
-  std::unique_ptr<FakeRendererGL> fake_renderer_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  RendererSettings settings_;
-  base::test::ScopedFeatureList feature_list_;
-};
-
-TEST_F(GLRendererFastSolidColorTest, RoundedCorners) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_output_rect(400, 400);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 50, 100, 100);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPassWithDamage(
-      &render_passes_in_draw_order_, root_pass_id, root_pass_output_rect,
-      root_pass_damage_rect, gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  root_pass->shared_quad_state_list.front()->mask_filter_info =
-      gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(quad_rect), 5.f));
-
-  // Fast Solid color draw quads should not be executed.
-  AddExpectations(false /*use_fast_path*/, gfx::Rect());
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, Transform3DSlowPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 50, 100, 100);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  gfx::Transform tm_3d;
-  tm_3d.RotateAboutYAxis(30.0);
-  ASSERT_FALSE(tm_3d.IsFlat());
-
-  root_pass->shared_quad_state_list.front()->quad_to_target_transform = tm_3d;
-
-  AddExpectations(false /*use_fast_path*/, gfx::Rect());
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, NonTransform3DFastPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 0, 200, 200);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  gfx::Transform tm_non_3d;
-  tm_non_3d.Translate(10.f, 10.f);
-  ASSERT_TRUE(tm_non_3d.IsFlat());
-
-  root_pass->shared_quad_state_list.front()->quad_to_target_transform =
-      tm_non_3d;
-
-  AddExpectations(true /*use_fast_path*/, gfx::Rect(10, 290, 200, 200),
-                  SK_ColorRED);
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, NonAxisAlignSlowPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 0, 200, 200);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  gfx::Transform tm_non_axis_align;
-  tm_non_axis_align.RotateAboutZAxis(45.0);
-  ASSERT_TRUE(tm_non_axis_align.IsFlat());
-
-  root_pass->shared_quad_state_list.front()->quad_to_target_transform =
-      tm_non_axis_align;
-
-  AddExpectations(false /*use_fast_path*/, gfx::Rect());
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, StencilSlowPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 0, 200, 200);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  root_pass->has_transparent_background = false;
-
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  AddExpectations(false /*use_fast_path*/, gfx::Rect(), SK_ColorRED,
-                  true /*enable_stencil*/);
-  output_surface()->set_has_external_stencil_test(true);
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, NeedsBlendingSlowPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(2, 3, 300, 200);
-  gfx::Rect full_quad_rect(0, 0, 50, 50);
-  gfx::Rect quad_rect_1(0, 0, 20, 20);
-  gfx::Rect quad_rect_2(20, 0, 20, 20);
-  gfx::Rect quad_rect_3(0, 20, 20, 20);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-
-  cc::AddQuad(root_pass, quad_rect_1, SkColorSetARGB(0x33, 0xFF, 0, 0));
-
-  cc::AddQuad(root_pass, quad_rect_2, SK_ColorBLUE);
-  root_pass->shared_quad_state_list.back()->opacity = 0.5f;
-
-  cc::AddQuad(root_pass, quad_rect_3, SK_ColorGREEN);
-  root_pass->shared_quad_state_list.back()->blend_mode = SkBlendMode::kDstIn;
-
-  cc::AddQuad(root_pass, full_quad_rect, SK_ColorBLACK);
-
-  // The first solid color quad would use a fast path, but the other quads that
-  // require blending will use the slower method.
-  AddExpectations(true /*use_fast_path*/, gfx::Rect(0, 450, 50, 50),
-                  SK_ColorBLACK, false /*enable_stencil*/);
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, NeedsBlendingFastPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(2, 3, 300, 200);
-  gfx::Rect quad_rect_1(0, 0, 20, 20);
-  gfx::Rect quad_rect_2(20, 0, 20, 20);
-  gfx::Rect quad_rect_3(0, 20, 20, 20);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-
-  cc::AddQuad(root_pass, quad_rect_1, SkColorSetARGB(0x33, 0xFF, 0, 0));
-
-  cc::AddQuad(root_pass, quad_rect_2, SK_ColorBLUE);
-  root_pass->shared_quad_state_list.back()->opacity = 0.5f;
-
-  cc::AddQuad(root_pass, quad_rect_3, SK_ColorGREEN);
-  root_pass->shared_quad_state_list.back()->blend_mode = SkBlendMode::kSrc;
-
-  auto* gl = gl_ptr();
-
-  // The quads here despite having blend requirements can still use fast path
-  // because they do not intersect with any other quad that has already been
-  // drawn onto the render target.
-  InSequence seq;
-
-  // // Restore GL state method calls
-  EXPECT_CALL(*gl, Disable(GL_DEPTH_TEST));
-  EXPECT_CALL(*gl, Disable(GL_CULL_FACE));
-  EXPECT_CALL(*gl, Disable(GL_STENCIL_TEST));
-  EXPECT_CALL(*gl, Enable(GL_BLEND));
-  EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-  EXPECT_CALL(*gl, ClearColor(0, 0, 0, 0));
-
-  // Fast path draw used for green quad.
-  EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 460, 20, 20));
-  EXPECT_CALL(*gl, ClearColor(0, 1, 0, 1));
-  EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-
-  // Fast path draw used for blue quad.
-  EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(20, 480, 20, 20));
-  EXPECT_CALL(*gl, ClearColor(0, 0, 0.5f, 0.5f));
-  EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-
-  // Fast path draw used for red quad.
-  EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 480, 20, 20));
-  EXPECT_CALL(*gl, ClearColor(::testing::FloatEq(0.2f), 0, 0,
-                              ::testing::FloatEq(0.2f)));
-  EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-  EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-
-  EXPECT_CALL(*gl, Disable(GL_BLEND));
-
-  RunTest(viewport_size);
-}
-
-TEST_F(GLRendererFastSolidColorTest, AntiAliasSlowPath) {
-  gfx::Size viewport_size(500, 500);
-  gfx::Rect root_pass_damage_rect(10, 20, 300, 200);
-  gfx::Rect quad_rect(0, 0, 200, 200);
-
-  AggregatedRenderPassId root_pass_id{1};
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-      gfx::Transform(), cc::FilterOperations());
-  root_pass->damage_rect = root_pass_damage_rect;
-  cc::AddQuad(root_pass, quad_rect, SK_ColorRED);
-
-  gfx::Transform tm_aa;
-  tm_aa.Translate(0.1f, 0.1f);
-  ASSERT_TRUE(tm_aa.IsFlat());
-
-  root_pass->shared_quad_state_list.front()->quad_to_target_transform = tm_aa;
-
-  AddExpectations(false /*use_fast_path*/, gfx::Rect());
-
-  RunTest(viewport_size);
-}
-
-class PartialSwapMockGLES2Interface : public TestGLES2Interface {
- public:
-  PartialSwapMockGLES2Interface() = default;
-
-  MOCK_METHOD1(Enable, void(GLenum cap));
-  MOCK_METHOD1(Disable, void(GLenum cap));
-  MOCK_METHOD4(Scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
-  MOCK_METHOD1(SetEnableDCLayersCHROMIUM, void(GLboolean enable));
-};
-
-class GLRendererPartialSwapTest : public GLRendererTest {
- public:
-  void SetUp() override {
-    // Force enable fast solid color draw path.
-    scoped_feature_list_.InitAndEnableFeature(features::kFastSolidColorDraw);
-    GLRendererTest::SetUp();
-  }
-
- protected:
-  void RunTest(bool partial_swap, bool set_draw_rectangle) {
-    auto gl_owned = std::make_unique<PartialSwapMockGLES2Interface>();
-    gl_owned->set_have_post_sub_buffer(true);
-
-    auto* gl = gl_owned.get();
-
-    auto provider = TestContextProvider::Create(std::move(gl_owned));
-    provider->BindToCurrentThread();
-
-    cc::FakeOutputSurfaceClient output_surface_client;
-    std::unique_ptr<FakeOutputSurface> output_surface(
-        FakeOutputSurface::Create3d(std::move(provider)));
-    output_surface->set_supports_dc_layers(set_draw_rectangle);
-    output_surface->BindToClient(&output_surface_client);
-
-    auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-        output_surface->context_provider());
-
-    RendererSettings settings;
-    settings.partial_swap_enabled = partial_swap;
-    FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                            resource_provider.get());
-    renderer.Initialize();
-    EXPECT_EQ(partial_swap, renderer.use_partial_swap());
-    renderer.SetVisible(true);
-
-    gfx::Size viewport_size(100, 100);
-    gfx::Rect root_pass_output_rect(80, 80);
-    gfx::Rect root_pass_damage_rect(2, 2, 3, 3);
-
-    // Draw one black frame to make sure the output surface is reshaped before
-    // tests.
-    EXPECT_CALL(*gl, Disable(GL_DEPTH_TEST)).Times(1);
-    EXPECT_CALL(*gl, Disable(GL_CULL_FACE)).Times(1);
-    EXPECT_CALL(*gl, Disable(GL_STENCIL_TEST)).Times(1);
-    EXPECT_CALL(*gl, Enable(GL_BLEND)).Times(1);
-
-    if (output_surface->capabilities().supports_dc_layers) {
-      EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST)).Times(1);
-      EXPECT_CALL(*gl, Scissor(0, 0, 0, 0)).Times(1);
-
-      // Root render pass requires a scissor if the output surface supports
-      // dc layers.
-      EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST)).Times(3);
-      EXPECT_CALL(*gl, Scissor(0, 0, 100, 100)).Times(3);
-    } else {
-      EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST)).Times(2);
-      EXPECT_CALL(*gl, Scissor(0, 0, 0, 0)).Times(2);
-      if (set_draw_rectangle) {
-        EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST)).Times(2);
-        EXPECT_CALL(*gl, Scissor(0, 0, 100, 100)).Times(2);
-      } else {
-        EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST)).Times(1);
-        EXPECT_CALL(*gl, Scissor(0, 0, 100, 100)).Times(1);
-      }
-    }
-
-    EXPECT_CALL(*gl, Disable(GL_BLEND)).Times(1);
-
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    root_pass->damage_rect = gfx::Rect(viewport_size);
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorBLACK);
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    Mock::VerifyAndClearExpectations(gl);
-
-    for (int i = 0; i < 2; ++i) {
-      root_pass = cc::AddRenderPassWithDamage(
-          &render_passes_in_draw_order_, root_pass_id, root_pass_output_rect,
-          root_pass_damage_rect, gfx::Transform(), cc::FilterOperations());
-      cc::AddQuad(root_pass, gfx::Rect(root_pass_output_rect), SK_ColorGREEN);
-
-      InSequence seq;
-
-      // A bunch of initialization that happens.
-      EXPECT_CALL(*gl, Disable(GL_DEPTH_TEST));
-      EXPECT_CALL(*gl, Disable(GL_CULL_FACE));
-      EXPECT_CALL(*gl, Disable(GL_STENCIL_TEST));
-      EXPECT_CALL(*gl, Enable(GL_BLEND));
-      EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-      EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-
-      // Partial frame, we should use a scissor to swap only that part when
-      // partial swap is enabled.
-      gfx::Rect output_rectangle =
-          partial_swap ? root_pass_damage_rect : gfx::Rect(viewport_size);
-
-      // The scissor is flipped, so subtract the y coord and height from the
-      // bottom of the GL viewport.
-      gfx::Rect scissor_rect(output_rectangle.x(),
-                             viewport_size.height() - output_rectangle.y() -
-                                 output_rectangle.height(),
-                             output_rectangle.width(),
-                             output_rectangle.height());
-
-      // Drawing the solid color quad using glClear and scissor rect.
-      EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-      EXPECT_CALL(*gl, Scissor(scissor_rect.x(), scissor_rect.y(),
-                               scissor_rect.width(), scissor_rect.height()));
-
-      if (partial_swap || set_draw_rectangle) {
-        EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-        EXPECT_CALL(*gl, Scissor(scissor_rect.x(), scissor_rect.y(),
-                                 scissor_rect.width(), scissor_rect.height()));
-      }
-
-      // Restore GL state after solid color draw quad.
-      if (partial_swap || set_draw_rectangle) {
-        EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST));
-        EXPECT_CALL(*gl, Scissor(scissor_rect.x(), scissor_rect.y(),
-                                 scissor_rect.width(), scissor_rect.height()));
-      } else {
-        EXPECT_CALL(*gl, Disable(GL_SCISSOR_TEST));
-        EXPECT_CALL(*gl, Scissor(0, 0, 0, 0));
-      }
-
-      // Blending is disabled at the end of the frame.
-      EXPECT_CALL(*gl, Disable(GL_BLEND));
-
-      renderer.DecideRenderPassAllocationsForFrame(
-          render_passes_in_draw_order_);
-      DrawFrame(&renderer, viewport_size);
-
-      if (set_draw_rectangle) {
-        EXPECT_EQ(output_rectangle, output_surface->last_set_draw_rectangle());
-      }
-
-      Mock::VerifyAndClearExpectations(gl);
-    }
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(GLRendererPartialSwapTest, PartialSwap) {
-  RunTest(true, false);
-}
-
-TEST_F(GLRendererPartialSwapTest, NoPartialSwap) {
-  RunTest(false, false);
-}
-
-#if BUILDFLAG(IS_WIN)
-TEST_F(GLRendererPartialSwapTest, SetDrawRectangle_PartialSwap) {
-  RunTest(true, true);
-}
-
-TEST_F(GLRendererPartialSwapTest, SetDrawRectangle_NoPartialSwap) {
-  RunTest(false, true);
-}
-
-// Test that SetEnableDCLayersCHROMIUM is properly called when enabling
-// and disabling DC layers.
-TEST_F(GLRendererTest, DCLayerOverlaySwitch) {
-  auto gl_owned = std::make_unique<PartialSwapMockGLES2Interface>();
-  gl_owned->set_have_post_sub_buffer(true);
-  auto* gl = gl_owned.get();
-
-  auto provider = TestContextProvider::Create(std::move(gl_owned));
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  std::unique_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d(std::move(provider)));
-  output_surface->set_supports_dc_layers(true);
-  output_surface->BindToClient(&output_surface_client);
-
-  auto parent_resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  auto child_context_provider = TestContextProvider::Create();
-  child_context_provider->BindToCurrentThread();
-  auto child_resource_provider = std::make_unique<ClientResourceProvider>();
-
-  auto transfer_resource = TransferableResource::MakeGL(
-      gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-      gfx::Size(256, 256), true);
-  auto release_callback = base::BindOnce(&MailboxReleased);
-  ResourceId resource_id = child_resource_provider->ImportResource(
-      transfer_resource, std::move(release_callback));
-
-  std::vector<ReturnedResource> returned_to_child;
-  int child_id = parent_resource_provider->CreateChild(
-      base::BindRepeating(&CollectResources, &returned_to_child), SurfaceId());
-
-  // Transfer resource to the parent.
-  std::vector<ResourceId> resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(resource_id);
-  std::vector<TransferableResource> list;
-  child_resource_provider->PrepareSendToParent(
-      resource_ids_to_transfer, &list,
-      static_cast<RasterContextProvider*>(child_context_provider.get()));
-  parent_resource_provider->ReceiveFromChild(child_id, list);
-  // In DisplayResourceProvider's namespace, use the mapped resource id.
-  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-      parent_resource_provider->GetChildToParentMap(child_id);
-  ResourceId parent_resource_id = resource_map[list[0].id];
-
-  auto processor = std::make_unique<OverlayProcessorWin>(
-      output_surface.get(),
-      std::make_unique<DCLayerOverlayProcessor>(
-          &debug_settings_, /*allowed_yuv_overlay_count=*/1, true));
-
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                          parent_resource_provider.get(), processor.get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  gfx::Size viewport_size(100, 100);
-
-  for (int i = 0; i < 65; i++) {
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    if (i == 0) {
-      gfx::Rect rect(0, 0, 100, 100);
-      bool needs_blending = false;
-      gfx::RectF tex_coord_rect(0, 0, 1, 1);
-      SharedQuadState* shared_state =
-          root_pass->CreateAndAppendSharedQuadState();
-      shared_state->SetAll(gfx::Transform(), rect, rect, gfx::MaskFilterInfo(),
-                           absl::nullopt, false, 1, SkBlendMode::kSrcOver, 0);
-      YUVVideoDrawQuad* quad =
-          root_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
-      quad->SetNew(shared_state, rect, rect, needs_blending, tex_coord_rect,
-                   tex_coord_rect, rect.size(), rect.size(), parent_resource_id,
-                   parent_resource_id, parent_resource_id, parent_resource_id,
-                   gfx::ColorSpace(), 0, 1.0, 8);
-    }
-
-    // A bunch of initialization that happens.
-    EXPECT_CALL(*gl, Disable(_)).Times(AnyNumber());
-    EXPECT_CALL(*gl, Enable(_)).Times(AnyNumber());
-    EXPECT_CALL(*gl, Scissor(_, _, _, _)).Times(AnyNumber());
-
-    // Partial frame, we should use a scissor to swap only that part when
-    // partial swap is enabled.
-    root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
-    // Frame 0 should be completely damaged because it's the first.
-    // Frame 1 should be because it changed. Frame 60 should be
-    // because it's disabling DC layers.
-    gfx::Rect output_rectangle = (i == 0 || i == 1 || i == 60)
-                                     ? root_pass->output_rect
-                                     : root_pass->damage_rect;
-
-    // Frame 0 should have DC Layers enabled because of the overlay.
-    // After 60 frames of no overlays DC layers should be disabled again.
-    if (i == 0)
-      EXPECT_CALL(*gl, SetEnableDCLayersCHROMIUM(GL_TRUE));
-    else if (i == 60)
-      EXPECT_CALL(*gl, SetEnableDCLayersCHROMIUM(GL_FALSE));
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-    EXPECT_EQ(output_rectangle, output_surface->last_set_draw_rectangle());
-    testing::Mock::VerifyAndClearExpectations(gl);
-  }
-
-  // Transfer resources back from the parent to the child. Set no resources as
-  // being in use.
-  parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
-                                                          ResourceIdSet());
-
-  child_resource_provider->RemoveImportedResource(resource_id);
-  child_resource_provider->ShutdownAndReleaseAllResources();
-}
-#endif
-
-class GLRendererWithMockContextTest : public ::testing::Test {
- protected:
-  class MockContextSupport : public TestContextSupport {
-   public:
-    MockContextSupport() {}
-    MOCK_METHOD1(SetAggressivelyFreeResources,
-                 void(bool aggressively_free_resources));
-  };
-
-  void SetUp() override {
-    auto context_support = std::make_unique<MockContextSupport>();
-    context_support_ptr_ = context_support.get();
-    auto context_provider =
-        TestContextProvider::Create(std::move(context_support));
-    ASSERT_EQ(context_provider->BindToCurrentThread(),
-              gpu::ContextResult::kSuccess);
-    output_surface_ = FakeOutputSurface::Create3d(std::move(context_provider));
-    output_surface_->BindToClient(&output_surface_client_);
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-    renderer_ = std::make_unique<GLRenderer>(
-        &settings_, &debug_settings_, output_surface_.get(),
-        resource_provider_.get(), nullptr, nullptr);
-    renderer_->Initialize();
-  }
-
-  RendererSettings settings_;
-  DebugRendererSettings debug_settings_;
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  MockContextSupport* context_support_ptr_;
-  std::unique_ptr<OutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  std::unique_ptr<GLRenderer> renderer_;
-};
-
-TEST_F(GLRendererWithMockContextTest,
-       ContextPurgedWhenRendererBecomesInvisible) {
-  EXPECT_CALL(*context_support_ptr_, SetAggressivelyFreeResources(false));
-  renderer_->SetVisible(true);
-  Mock::VerifyAndClearExpectations(context_support_ptr_);
-
-  EXPECT_CALL(*context_support_ptr_, SetAggressivelyFreeResources(true));
-  renderer_->SetVisible(false);
-  Mock::VerifyAndClearExpectations(context_support_ptr_);
-}
-
-#if defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-class ContentBoundsOverlayProcessor : public OverlayProcessorUsingStrategy {
- public:
-  class TestStrategy : public OverlayProcessorStrategy {
-   public:
-    explicit TestStrategy(const std::vector<gfx::Rect>& content_bounds)
-        : content_bounds_(content_bounds) {}
-    ~TestStrategy() override = default;
-
-    bool Attempt(const SkM44& output_color_matrix,
-                 const OverlayProcessorInterface::FilterOperationsMap&
-                     render_pass_backdrop_filters,
-                 DisplayResourceProvider* resource_provider,
-                 AggregatedRenderPassList* render_pass_list,
-                 SurfaceDamageRectList* surface_damage_rect_list,
-                 const PrimaryPlane* primary_plane,
-                 OverlayCandidateList* candidates,
-                 std::vector<gfx::Rect>* content_bounds) override {
-      content_bounds->insert(content_bounds->end(), content_bounds_.begin(),
-                             content_bounds_.end());
-      return true;
-    }
-
-    void ProposePrioritized(
-        const SkM44& output_color_matrix,
-        const FilterOperationsMap& render_pass_backdrop_filters,
-        DisplayResourceProvider* resource_provider,
-        AggregatedRenderPassList* render_pass_list,
-        SurfaceDamageRectList* surface_damage_rect_list,
-        const PrimaryPlane* primary_plane,
-        std::vector<OverlayProposedCandidate>* candidates,
-        std::vector<gfx::Rect>* content_bounds) override {
-      auto* render_pass = render_pass_list->back().get();
-      QuadList& quad_list = render_pass->quad_list;
-      OverlayCandidate candidate;
-      // Adding a mock candidate to the propose list so that
-      // 'AttemptPrioritized' will be called.
-      candidates->push_back({quad_list.end(), candidate, this});
-    }
-
-    bool AttemptPrioritized(
-        const SkM44& output_color_matrix,
-        const FilterOperationsMap& render_pass_backdrop_filters,
-        DisplayResourceProvider* resource_provider,
-        AggregatedRenderPassList* render_pass_list,
-        SurfaceDamageRectList* surface_damage_rect_list,
-        const PrimaryPlane* primary_plane,
-        OverlayCandidateList* candidates,
-        std::vector<gfx::Rect>* content_bounds,
-        const OverlayProposedCandidate& proposed_candidate) override {
-      content_bounds->insert(content_bounds->end(), content_bounds_.begin(),
-                             content_bounds_.end());
-      return true;
-    }
-
-    void CommitCandidate(const OverlayProposedCandidate& proposed_candidate,
-                         AggregatedRenderPass* render_pass) override {}
-
-   private:
-    const std::vector<gfx::Rect> content_bounds_;
-  };
-
-  explicit ContentBoundsOverlayProcessor(
-      const std::vector<gfx::Rect>& content_bounds)
-      : OverlayProcessorUsingStrategy(), content_bounds_(content_bounds) {
-    strategies_.push_back(
-        std::make_unique<TestStrategy>(std::move(content_bounds_)));
-    prioritization_config_.changing_threshold = false;
-    prioritization_config_.damage_rate_threshold = false;
-  }
-
-  TestStrategy& strategy() {
-    return static_cast<TestStrategy&>(*strategies_.back());
-  }
-  // Empty mock methods since this test set up uses strategies, which are only
-  // for ozone and android.
-  MOCK_CONST_METHOD0(NeedsSurfaceDamageRectList, bool());
-  bool IsOverlaySupported() const override { return true; }
-
-  // A list of possible overlay candidates is presented to this function.
-  // The expected result is that those candidates that can be in a separate
-  // plane are marked with |overlay_handled| set to true, otherwise they are
-  // to be traditionally composited. Candidates with |overlay_handled| set to
-  // true must also have their |display_rect| converted to integer
-  // coordinates if necessary.
-  void CheckOverlaySupportImpl(
-      const OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane,
-      OverlayCandidateList* surfaces) override {}
-
- private:
-  std::vector<gfx::Rect> content_bounds_;
-};
-
-class GLRendererSwapWithBoundsTest : public GLRendererTest {
- protected:
-  void RunTest(const std::vector<gfx::Rect>& content_bounds) {
-    auto gl_owned = std::make_unique<TestGLES2Interface>();
-    gl_owned->set_have_swap_buffers_with_bounds(true);
-
-    auto provider = TestContextProvider::Create(std::move(gl_owned));
-    provider->BindToCurrentThread();
-
-    cc::FakeOutputSurfaceClient output_surface_client;
-    std::unique_ptr<FakeOutputSurface> output_surface(
-        FakeOutputSurface::Create3d(std::move(provider)));
-    output_surface->BindToClient(&output_surface_client);
-
-    auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-        output_surface->context_provider());
-
-    RendererSettings settings;
-    auto processor =
-        std::make_unique<ContentBoundsOverlayProcessor>(content_bounds);
-    FakeRendererGL renderer(&settings, &debug_settings_, output_surface.get(),
-                            resource_provider.get(), processor.get());
-    renderer.Initialize();
-    EXPECT_EQ(true, renderer.use_swap_with_bounds());
-    renderer.SetVisible(true);
-
-    gfx::Size viewport_size(100, 100);
-
-    {
-      AggregatedRenderPassId root_pass_id{1};
-      cc::AddRenderPass(&render_passes_in_draw_order_, root_pass_id,
-                        gfx::Rect(viewport_size), gfx::Transform(),
-                        cc::FilterOperations());
-
-      renderer.DecideRenderPassAllocationsForFrame(
-          render_passes_in_draw_order_);
-      DrawFrame(&renderer, viewport_size);
-      renderer.SwapBuffers({});
-
-      std::vector<gfx::Rect> expected_content_bounds;
-      EXPECT_EQ(content_bounds,
-                output_surface->last_sent_frame()->content_bounds);
-    }
-  }
-};
-
-TEST_F(GLRendererSwapWithBoundsTest, EmptyContent) {
-  std::vector<gfx::Rect> content_bounds;
-  RunTest(content_bounds);
-}
-
-TEST_F(GLRendererSwapWithBoundsTest, NonEmpty) {
-  std::vector<gfx::Rect> content_bounds;
-  content_bounds.push_back(gfx::Rect(0, 0, 10, 10));
-  content_bounds.push_back(gfx::Rect(20, 20, 30, 30));
-  RunTest(content_bounds);
-}
-#endif  // defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_APPLE)
-class MockCALayerGLES2Interface : public TestGLES2Interface {
- public:
-  MOCK_METHOD6(ScheduleCALayerSharedStateCHROMIUM,
-               void(GLfloat opacity,
-                    GLboolean is_clipped,
-                    const GLfloat* clip_rect,
-                    const GLfloat* rounded_corner_bounds,
-                    GLint sorting_context_id,
-                    const GLfloat* transform));
-  MOCK_METHOD6(ScheduleCALayerCHROMIUM,
-               void(GLuint contents_texture_id,
-                    const GLfloat* contents_rect,
-                    GLuint background_color,
-                    GLuint edge_aa_mask,
-                    const GLfloat* bounds_rect,
-                    GLuint filter));
-  MOCK_METHOD2(ScheduleCALayerInUseQueryCHROMIUM,
-               void(GLsizei count, const GLuint* textures));
-  MOCK_METHOD5(
-      Uniform4f,
-      void(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
-};
-
-class CALayerGLRendererTest : public GLRendererTest {
- protected:
-  void SetUp() override {
-    // A mock GLES2Interface that can watch CALayer stuff happen.
-    auto gles2_interface = std::make_unique<MockCALayerGLES2Interface>();
-    // Support image storage for GpuMemoryBuffers, needed for
-    // CALayers/IOSurfaces backed by textures.
-    gles2_interface->set_support_texture_storage_image(true);
-    // Allow the renderer to make an empty SwapBuffers - skipping even the
-    // root RenderPass.
-    gles2_interface->set_have_commit_overlay_planes(true);
-
-    gl_ = gles2_interface.get();
-
-    auto provider = TestContextProvider::Create(std::move(gles2_interface));
-    provider->BindToCurrentThread();
-
-    cc::FakeOutputSurfaceClient output_surface_client;
-    output_surface_ = FakeOutputSurface::Create3d(std::move(provider));
-    output_surface_->BindToClient(&output_surface_client);
-
-    display_resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-
-    settings_ = std::make_unique<RendererSettings>();
-    // This setting is enabled to use CALayer overlays.
-    settings_->release_overlay_resources_after_gpu_query = true;
-    // The Mac TestOverlayProcessor default to enable CALayer overlays, then all
-    // damage is removed and we can skip the root RenderPass, swapping empty.
-    overlay_processor_ = std::make_unique<OverlayProcessorMac>(
-        std::make_unique<CALayerOverlayProcessor>());
-    renderer_ = std::make_unique<FakeRendererGL>(
-        settings_.get(), &debug_settings_, output_surface_.get(),
-        display_resource_provider_.get(), overlay_processor_.get(),
-        base::ThreadTaskRunnerHandle::Get());
-    renderer_->Initialize();
-    renderer_->SetVisible(true);
-  }
-
-  void TearDown() override {
-    renderer_.reset();
-    display_resource_provider_.reset();
-    output_surface_.reset();
-  }
-
-  void DrawBlackFrame(const gfx::Size& viewport_size) {
-    AggregatedRenderPassId root_pass_id{1};
-
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorBLACK);
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-
-    DrawFrame(&renderer(), viewport_size);
-    renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-    renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-
-  MockCALayerGLES2Interface& gl() const { return *gl_; }
-  FakeRendererGL& renderer() const { return *renderer_; }
-  FakeOutputSurface& output_surface() const { return *output_surface_; }
-
- private:
-  MockCALayerGLES2Interface* gl_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> display_resource_provider_;
-  std::unique_ptr<RendererSettings> settings_;
-  std::unique_ptr<OverlayProcessorInterface> overlay_processor_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-};
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysWithAllQuadsPromoted) {
-  gfx::Size viewport_size(10, 10);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  // This frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass that is at 1,2 to make it identifiable.
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPassId root_pass_id{1};
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(viewport_size) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child pass is drawn, promoted to an overlay, and scheduled as a
-  // CALayer.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([](GLuint contents_texture_id, const GLfloat* contents_rect,
-                      GLuint background_color, GLuint edge_aa_mask,
-                      const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // The damage was eliminated when everything was promoted to CALayers.
-  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
-  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
-
-  // Frame number 2. Same inputs, except...
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(viewport_size) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-
-    // Use a cached RenderPass for the child.
-    child_pass->cache_render_pass = true;
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child CompositorRenderPassDrawQuad gets promoted again, but importantly
-  // it did not itself have to be drawn this time as it can use the cached
-  // texture. Because we can skip the child pass, and the root pass (all quads
-  // were promoted), this exposes edge cases in GLRenderer if it assumes we draw
-  // at least one RenderPass. This still works, doesn't crash, etc, and the
-  // CompositorRenderPassDrawQuad is emitted.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-}
-
-TEST_F(CALayerGLRendererTest, CALayerRoundRects) {
-  gfx::Size viewport_size(10, 10);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  for (size_t subtest = 0; subtest < 3; ++subtest) {
-    AggregatedRenderPass* child_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-        gfx::Rect(250, 250), gfx::Transform(), cc::FilterOperations());
-
-    AggregatedRenderPassId root_pass_id{1};
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    auto* quad = cc::AddRenderPassQuad(root_pass, child_pass);
-    SharedQuadState* sqs =
-        const_cast<SharedQuadState*>(quad->shared_quad_state);
-
-    sqs->clip_rect = gfx::Rect(2, 2, 6, 6);
-    const float radius = 2;
-    sqs->mask_filter_info =
-        gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(*sqs->clip_rect), radius));
-
-    switch (subtest) {
-      case 0:
-        // Subtest 0 is a simple round rect that matches the clip rect, and
-        // should be handled by CALayers.
-        EXPECT_CALL(gl(), Uniform4f(_, _, _, _, _)).Times(1);
-        EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _))
-            .Times(1);
-        EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _)).Times(1);
-        break;
-      case 1:
-        // Subtest 1 doesn't match clip and rounded rect, but we can still
-        // use CALayers.
-        sqs->clip_rect = gfx::Rect(3, 3, 4, 4);
-        EXPECT_CALL(gl(), Uniform4f(_, _, _, _, _)).Times(1);
-        EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _)).Times(1);
-        break;
-      case 2:
-        // Subtest 2 has a non-simple rounded rect.
-        gfx::RRectF rounded_corner_bounds =
-            sqs->mask_filter_info.rounded_corner_bounds();
-        rounded_corner_bounds.SetCornerRadii(gfx::RRectF::Corner::kUpperLeft, 1,
-                                             1);
-        sqs->mask_filter_info = gfx::MaskFilterInfo(rounded_corner_bounds);
-        // Called 2 extra times in order to set up the rounded corner
-        // parameters in the shader, because the CALayer is not handling
-        // the rounded corners.
-        EXPECT_CALL(gl(), Uniform4f(_, _, _, _, _)).Times(3);
-        EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _)).Times(0);
-        break;
-    }
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    DrawFrame(&renderer(), viewport_size);
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-}
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysReusesTextureWithDifferentSizes) {
-  gfx::Size viewport_size(300, 300);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  // This frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass that is at 1,2 to make it identifiable. The child's size is
-  // 250x251, but it will be rounded up to a multiple of 64 in order to promote
-  // easier texture reuse. See https://crbug.com/146070.
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPassId root_pass_id{1};
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child pass is drawn, promoted to an overlay, and scheduled as a
-  // CALayer. The bounds of the texture are rounded up to 256x256. We save the
-  // texture ID to make sure we reuse it correctly.
-  uint32_t saved_texture_id = 0;
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The size is rounded to a multiple of 64.
-              EXPECT_EQ(256, bounds_rect[2]);
-              EXPECT_EQ(256, bounds_rect[3]);
-              saved_texture_id = contents_texture_id;
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
-  EXPECT_NE(saved_texture_id, 0u);
-
-  // The damage was eliminated when everything was promoted to CALayers.
-  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
-  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
-
-  // The texture will be checked to verify if it is free yet.
-  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
-  renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // Frame number 2. We change the size of the child RenderPass to be smaller
-  // than the next multiple of 64, but larger than half the previous size so
-  // that our texture reuse heuristics will reuse the texture if it is free.
-  // For now, it is not.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(190, 191) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child RenderPass will use a new 192x192 texture, since the last texture
-  // is still in use.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // New texture id.
-              EXPECT_NE(saved_texture_id, contents_texture_id);
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The texture is 192x192 since we snap up to multiples of 64.
-              EXPECT_EQ(192, bounds_rect[2]);
-              EXPECT_EQ(192, bounds_rect[3]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // There are now 2 textures to check if they are free.
-  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
-  renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // The first (256x256) texture is returned to the GLRenderer.
-  renderer().DidReceiveTextureInUseResponses({{saved_texture_id, false}});
-
-  // Frame number 3 looks just like frame number 2. The child RenderPass is
-  // smaller than the next multiple of 64 from the released texture, but larger
-  // than half of its size so that our texture reuse heuristics will kick in.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(190, 191) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child RenderPass would try to use a 192x192 texture, but since we have
-  // an existing 256x256 texture, we can reuse that.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // The first texture is reused.
-              EXPECT_EQ(saved_texture_id, contents_texture_id);
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The size here is the size of the texture being used, not
-              // the size we tried to use (192x192).
-              EXPECT_EQ(256, bounds_rect[2]);
-              EXPECT_EQ(256, bounds_rect[3]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-}
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysDontReuseTooBigTexture) {
-  gfx::Size viewport_size(300, 300);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  // This frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass that is at 1,2 to make it identifiable. The child's size is
-  // 250x251, but it will be rounded up to a multiple of 64 in order to promote
-  // easier texture reuse. See https://crbug.com/146070.
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPassId root_pass_id{1};
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child pass is drawn, promoted to an overlay, and scheduled as a
-  // CALayer. The bounds of the texture are rounded up to 256x256. We save the
-  // texture ID to make sure we reuse it correctly.
-  uint32_t saved_texture_id = 0;
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The size is rounded to a multiple of 64.
-              EXPECT_EQ(256, bounds_rect[2]);
-              EXPECT_EQ(256, bounds_rect[3]);
-              saved_texture_id = contents_texture_id;
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
-  EXPECT_NE(saved_texture_id, 0u);
-
-  // The damage was eliminated when everything was promoted to CALayers.
-  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
-  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
-
-  // The texture will be checked to verify if it is free yet.
-  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
-  renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // Frame number 2. We change the size of the child RenderPass to be much
-  // smaller.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(20, 21) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child RenderPass will use a new 64x64 texture, since the last texture
-  // is still in use.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // New texture id.
-              EXPECT_NE(saved_texture_id, contents_texture_id);
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The texture is 64x64 since we snap up to multiples of 64.
-              EXPECT_EQ(64, bounds_rect[2]);
-              EXPECT_EQ(64, bounds_rect[3]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // There are now 2 textures to check if they are free.
-  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
-  renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // The first (256x256) texture is returned to the GLRenderer.
-  renderer().DidReceiveTextureInUseResponses({{saved_texture_id, false}});
-
-  // Frame number 3 looks just like frame number 2. The child RenderPass is
-  // too small to reuse the old texture.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(20, 21) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child RenderPass would try to use a 64x64 texture. We have a free and
-  // existing 256x256 texture, but it's too large for us to reuse it.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // The first texture is not reused.
-              EXPECT_NE(saved_texture_id, contents_texture_id);
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              // The new texture has a smaller size.
-              EXPECT_EQ(64, bounds_rect[2]);
-              EXPECT_EQ(64, bounds_rect[3]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-}
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysReuseAfterNoSwapBuffers) {
-  gfx::Size viewport_size(300, 300);
-
-  // This frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass that is at 1,2 to make it identifiable.
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPassId root_pass_id{1};
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(100, 100) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The child pass is drawn, promoted to an overlay, and scheduled as a
-  // CALayer. We save the texture ID to make sure we reuse it correctly.
-  uint32_t saved_texture_id = 0;
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              saved_texture_id = contents_texture_id;
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
-  EXPECT_NE(saved_texture_id, 0u);
-
-  // SwapBuffers() is *not* called though! Display can do this sometimes.
-
-  // Frame number 2. We can not reuse the texture since the last one isn't
-  // returned yet. We use a different size so we can control which texture gets
-  // reused later.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(200, 200) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  uint32_t second_saved_texture_id = 0;
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // New texture id.
-              EXPECT_NE(saved_texture_id, contents_texture_id);
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              second_saved_texture_id = contents_texture_id;
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // SwapBuffers() *does* happen this time.
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-  // There are 2 textures to check if they are free.
-  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
-  renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-  Mock::VerifyAndClearExpectations(&gl());
-
-  // Both textures get returned and the 2nd one can be reused.
-  renderer().DidReceiveTextureInUseResponses(
-      {{saved_texture_id, false}, {second_saved_texture_id, false}});
-
-  // Frame number 3 looks just like frame number 2.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(200, 200) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // The 2nd texture that we sent has been returned so we can reuse it. We
-  // verify that happened.
-  {
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // The second texture is reused.
-              EXPECT_EQ(second_saved_texture_id, contents_texture_id);
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-            }));
-  }
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-}
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysReuseManyIfReturnedSlowly) {
-  gfx::Size viewport_size(300, 300);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  // Each frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass. We generate a bunch of frames and swap them, each with a
-  // different child RenderPass id, without getting any of the resources back
-  // from the OS.
-  AggregatedRenderPassId root_pass_id{1};
-
-  // The number is at least 2 larger than the number of textures we expect to
-  // reuse, so that we can leave one in the OS, and have 1 texture returned but
-  // not reused.
-  const int kNumSendManyTextureIds = 7;
-  uint32_t sent_texture_ids[kNumSendManyTextureIds];
-  for (int i = 0; i < kNumSendManyTextureIds; ++i) {
-    AggregatedRenderPass* child_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{i + 2},
-        gfx::Rect(250, 251) + gfx::Vector2d(1, 2), gfx::Transform(),
-        cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              sent_texture_ids[i] = contents_texture_id;
-            }));
-    DrawFrame(&renderer(), viewport_size);
-    Mock::VerifyAndClearExpectations(&gl());
-    renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-    // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
-    EXPECT_NE(sent_texture_ids[i], 0u);
-
-    // The damage was eliminated when everything was promoted to CALayers.
-    ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
-    EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
-
-    // All sent textures will be checked to verify if they are free yet.
-    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 1, _));
-    renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-
-  // Now all but 1 texture get returned by the OS, so they are all inserted
-  // into the cache for reuse.
-  std::vector<uint32_t> returned_texture_ids;
-  for (int i = 0; i < kNumSendManyTextureIds - 1; ++i) {
-    uint32_t id = sent_texture_ids[i];
-    renderer().DidReceiveTextureInUseResponses({{id, false}});
-    returned_texture_ids.push_back(id);
-  }
-
-  // We should keep *some* of these textures around to reuse them across
-  // multiple frames. https://crbug.com/146070 motivates this, and empirical
-  // testing found 5 to be a good number.
-  const int kNumSendReusedTextures = 5;
-  // See comment on |kNumSendManyTextureIds|.
-  ASSERT_LT(kNumSendReusedTextures, kNumSendManyTextureIds - 1);
-
-  for (int i = 0; i < kNumSendReusedTextures + 1; ++i) {
-    // We use different RenderPass ids to ensure that the cache allows reuse
-    // even if they don't match.
-    AggregatedRenderPass* child_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{i + 100},
-        gfx::Rect(250, 251) + gfx::Vector2d(1, 2), gfx::Transform(),
-        cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(Invoke([&](GLuint contents_texture_id,
-                             const GLfloat* contents_rect,
-                             GLuint background_color, GLuint edge_aa_mask,
-                             const GLfloat* bounds_rect, GLuint filter) {
-          // This is the child CompositorRenderPassDrawQuad.
-          EXPECT_EQ(1, bounds_rect[0]);
-          EXPECT_EQ(2, bounds_rect[1]);
-
-          if (i < kNumSendReusedTextures) {
-            // The texture id should be from the set of returned ones.
-            EXPECT_THAT(returned_texture_ids, Contains(contents_texture_id));
-            base::Erase(returned_texture_ids, contents_texture_id);
-          } else {
-            // More textures were returned at once than we expect to reuse
-            // so eventually we should be making a new texture to show we're
-            // not just keeping infinity textures in the cache.
-            EXPECT_THAT(returned_texture_ids,
-                        Not(Contains(contents_texture_id)));
-            // This shows that there was some returned id that we didn't use.
-            EXPECT_FALSE(returned_texture_ids.empty());
-          }
-        }));
-    DrawFrame(&renderer(), viewport_size);
-    Mock::VerifyAndClearExpectations(&gl());
-    renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-    // All sent textures will be checked to verify if they are free yet. There's
-    // also 1 outstanding texture to check for that wasn't returned yet from the
-    // above loop.
-    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 2, _));
-    renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-}
-
-TEST_F(CALayerGLRendererTest, CALayerOverlaysCachedTexturesAreFreed) {
-  gfx::Size viewport_size(300, 300);
-
-  // Draw an empty frame to make sure output surface is reshaped before tests.
-  DrawBlackFrame(viewport_size);
-
-  // Each frame has a root pass with a CompositorRenderPassDrawQuad pointing to
-  // a child pass. We generate a bunch of frames and swap them, each with a
-  // different child RenderPass id, without getting any of the resources back
-  // from the OS.
-  AggregatedRenderPassId child_pass_id{2};
-  AggregatedRenderPassId root_pass_id{1};
-
-  // We send a whole bunch of textures as overlays to the OS.
-  const int kNumSendManyTextureIds = 7;
-  uint32_t sent_texture_ids[kNumSendManyTextureIds];
-  for (int i = 0; i < kNumSendManyTextureIds; ++i) {
-    AggregatedRenderPass* child_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{i + 2},
-        gfx::Rect(250, 251) + gfx::Vector2d(1, 2), gfx::Transform(),
-        cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-        .WillOnce(
-            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
-                       GLuint background_color, GLuint edge_aa_mask,
-                       const GLfloat* bounds_rect, GLuint filter) {
-              // This is the child CompositorRenderPassDrawQuad.
-              EXPECT_EQ(1, bounds_rect[0]);
-              EXPECT_EQ(2, bounds_rect[1]);
-              sent_texture_ids[i] = contents_texture_id;
-            }));
-    DrawFrame(&renderer(), viewport_size);
-    Mock::VerifyAndClearExpectations(&gl());
-    renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-    // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
-    EXPECT_NE(sent_texture_ids[i], 0u);
-
-    // The damage was eliminated when everything was promoted to CALayers.
-    ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
-    EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
-
-    // All sent textures will be checked to verify if they are free yet.
-    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 1, _));
-    renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-
-  // Now all but 1 texture get returned by the OS, so they are all inserted
-  // into the cache for reuse.
-  std::vector<uint32_t> returned_texture_ids;
-  for (int i = 0; i < kNumSendManyTextureIds - 1; ++i) {
-    uint32_t id = sent_texture_ids[i];
-    renderer().DidReceiveTextureInUseResponses({{id, false}});
-    returned_texture_ids.push_back(id);
-  }
-
-  // We generate a bunch of frames that don't use the cache, one less than the
-  // number of textures returned.
-  for (int i = 0; i < kNumSendManyTextureIds - 2; ++i) {
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(100, 100), SK_ColorRED);
-
-    renderer().DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-
-    InSequence sequence;
-    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _));
-    DrawFrame(&renderer(), viewport_size);
-    Mock::VerifyAndClearExpectations(&gl());
-    renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-
-    // There's just 1 outstanding RenderPass texture to query for.
-    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
-    renderer().SwapBuffersComplete(/*release_fence=*/gfx::GpuFenceHandle());
-    Mock::VerifyAndClearExpectations(&gl());
-  }
-
-  // By now the cache should be empty, to show that we don't keep cached
-  // textures that won't be used forever. We generate a frame with a
-  // CompositorRenderPassDrawQuad and verify that it does not reuse a texture
-  // from the (empty) cache.
-  {
-    AggregatedRenderPass* child_pass =
-        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
-                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
-                          gfx::Transform(), cc::FilterOperations());
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-  }
-
-  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  InSequence sequence;
-  EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _, _));
-  EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
-      .WillOnce(Invoke([&](GLuint contents_texture_id,
-                           const GLfloat* contents_rect,
-                           GLuint background_color, GLuint edge_aa_mask,
-                           const GLfloat* bounds_rect, GLuint filter) {
-        // This is the child CompositorRenderPassDrawQuad.
-        EXPECT_EQ(1, bounds_rect[0]);
-        EXPECT_EQ(2, bounds_rect[1]);
-
-        // More textures were returned at once than we expect to reuse
-        // so eventually we should be making a new texture to show we're
-        // not just keeping infinity textures in the cache.
-        EXPECT_THAT(returned_texture_ids, Not(Contains(contents_texture_id)));
-        // This shows that there was some returned id that we didn't use.
-        EXPECT_FALSE(returned_texture_ids.empty());
-      }));
-  DrawFrame(&renderer(), viewport_size);
-  Mock::VerifyAndClearExpectations(&gl());
-  renderer().SwapBuffers(DirectRenderer::SwapFrameData());
-}
-#endif
-
-class FramebufferWatchingGLRenderer : public FakeRendererGL {
- public:
-  FramebufferWatchingGLRenderer(RendererSettings* settings,
-                                const DebugRendererSettings* debug_settings,
-                                OutputSurface* output_surface,
-                                DisplayResourceProviderGL* resource_provider)
-      : FakeRendererGL(settings,
-                       debug_settings,
-                       output_surface,
-                       resource_provider) {}
-
-  void BindFramebufferToOutputSurface() override {
-    ++bind_root_framebuffer_calls_;
-    FakeRendererGL::BindFramebufferToOutputSurface();
-  }
-
-  void BindFramebufferToTexture(
-      const AggregatedRenderPassId render_pass_id) override {
-    ++bind_child_framebuffer_calls_;
-    FakeRendererGL::BindFramebufferToTexture(render_pass_id);
-  }
-
-  int bind_root_framebuffer_calls() const {
-    return bind_root_framebuffer_calls_;
-  }
-  int bind_child_framebuffer_calls() const {
-    return bind_child_framebuffer_calls_;
-  }
-
-  void ResetBindCalls() {
-    bind_root_framebuffer_calls_ = bind_child_framebuffer_calls_ = 0;
-  }
-
- private:
-  int bind_root_framebuffer_calls_ = 0;
-  int bind_child_framebuffer_calls_ = 0;
-};
-
-TEST_F(GLRendererTest, UndamagedRenderPassStillDrawnWhenNoPartialSwap) {
-  auto provider = TestContextProvider::Create();
-  provider->UnboundTestContextGL()->set_have_post_sub_buffer(true);
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  auto output_surface = FakeOutputSurface::Create3d(std::move(provider));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto resource_provider = std::make_unique<DisplayResourceProviderGL>(
-      output_surface->context_provider());
-
-  for (int i = 0; i < 2; ++i) {
-    bool use_partial_swap = i == 0;
-    SCOPED_TRACE(use_partial_swap);
-
-    RendererSettings settings;
-    settings.partial_swap_enabled = use_partial_swap;
-    FramebufferWatchingGLRenderer renderer(&settings, &debug_settings_,
-                                           output_surface.get(),
-                                           resource_provider.get());
-    renderer.Initialize();
-    EXPECT_EQ(use_partial_swap, renderer.use_partial_swap());
-    renderer.SetVisible(true);
-
-    gfx::Size viewport_size(100, 100);
-    gfx::Rect child_rect(10, 10);
-
-    // First frame, the child and root RenderPass each have damage.
-    AggregatedRenderPass* child_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{2}, child_rect,
-        gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(child_pass, child_rect, SK_ColorGREEN);
-    child_pass->damage_rect = child_rect;
-
-    AggregatedRenderPass* root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-        gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorRED);
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-    root_pass->damage_rect = gfx::Rect(viewport_size);
-
-    EXPECT_EQ(0, renderer.bind_root_framebuffer_calls());
-    EXPECT_EQ(0, renderer.bind_child_framebuffer_calls());
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-
-    // We had to draw the root, and the child.
-    EXPECT_EQ(1, renderer.bind_child_framebuffer_calls());
-    // When the CompositorRenderPassDrawQuad in the root is drawn, we may
-    // re-bind the root framebuffer. So it can be bound more than once.
-    EXPECT_GE(renderer.bind_root_framebuffer_calls(), 1);
-
-    // Reset counting.
-    renderer.ResetBindCalls();
-
-    // Second frame, the child RenderPass has no damage in it.
-    child_pass = cc::AddRenderPass(&render_passes_in_draw_order_,
-                                   AggregatedRenderPassId{2}, child_rect,
-                                   gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(child_pass, child_rect, SK_ColorGREEN);
-    child_pass->damage_rect = gfx::Rect();
-
-    // Root RenderPass has some damage that doesn't intersect the child.
-    root_pass = cc::AddRenderPass(
-        &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-        gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SK_ColorRED);
-    cc::AddRenderPassQuad(root_pass, child_pass, kInvalidResourceId,
-                          gfx::Transform(), SkBlendMode::kSrcOver);
-    root_pass->damage_rect = gfx::Rect(child_rect.right(), 0, 10, 10);
-
-    EXPECT_EQ(0, renderer.bind_root_framebuffer_calls());
-    EXPECT_EQ(0, renderer.bind_child_framebuffer_calls());
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    DrawFrame(&renderer, viewport_size);
-
-    if (use_partial_swap) {
-      // Without damage overlapping the child, it didn't need to be drawn (it
-      // may choose to anyway but that'd be a waste). So we don't check for
-      // |bind_child_framebuffer_calls|. But the root should have been drawn.
-      EXPECT_EQ(renderer.bind_root_framebuffer_calls(), 1);
-    } else {
-      // Without partial swap, we have to draw the child still, this means
-      // the child is bound as the framebuffer.
-      EXPECT_EQ(1, renderer.bind_child_framebuffer_calls());
-      // When the CompositorRenderPassDrawQuad in the root is drawn, as it must
-      // be since we must draw the entire output, we may re-bind the root
-      // framebuffer. So it can be bound more than once.
-      EXPECT_GE(renderer.bind_root_framebuffer_calls(), 1);
-    }
-  }
-}
-
-#if defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-class GLRendererWithGpuFenceTest : public GLRendererTest {
- protected:
-  GLRendererWithGpuFenceTest() {
-    auto provider = TestContextProvider::Create();
-    provider->BindToCurrentThread();
-    provider->TestContextGL()->set_have_commit_overlay_planes(true);
-    test_context_support_ = provider->support();
-
-    output_surface_ = FakeOutputSurface::Create3d(std::move(provider));
-    output_surface_->set_overlay_texture_id(kSurfaceOverlayTextureId);
-    output_surface_->set_gpu_fence_id(kGpuFenceId);
-    resource_provider_ = std::make_unique<DisplayResourceProviderGL>(
-        output_surface_->context_provider());
-    overlay_processor_ = std::make_unique<SingleOverlayOnTopProcessor>();
-    overlay_processor_->AllowMultipleCandidates();
-    renderer_ = std::make_unique<FakeRendererGL>(
-        &settings_, &debug_settings_, output_surface_.get(),
-        resource_provider_.get(), overlay_processor_.get(),
-        base::ThreadTaskRunnerHandle::Get());
-    renderer_->Initialize();
-    renderer_->SetVisible(true);
-
-    test_context_support_->SetScheduleOverlayPlaneCallback(
-        base::BindRepeating(&MockOverlayScheduler::Schedule,
-                            base::Unretained(&overlay_scheduler_)));
-  }
-
-  ~GLRendererWithGpuFenceTest() override {
-    if (child_resource_provider_)
-      child_resource_provider_->ShutdownAndReleaseAllResources();
-  }
-
-  ResourceId create_overlay_resource() {
-    child_context_provider_ = TestContextProvider::Create();
-    child_context_provider_->BindToCurrentThread();
-
-    child_resource_provider_ = std::make_unique<ClientResourceProvider>();
-    auto transfer_resource = TransferableResource::MakeGL(
-        gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
-        gfx::Size(256, 256), true);
-    ResourceId client_resource_id = child_resource_provider_->ImportResource(
-        transfer_resource, base::DoNothing());
-
-    std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
-        cc::SendResourceAndGetChildToParentMap(
-            {client_resource_id}, resource_provider_.get(),
-            child_resource_provider_.get(), child_context_provider_.get());
-    return resource_map[client_resource_id];
-  }
-
-  static constexpr unsigned kSurfaceOverlayTextureId = 33;
-  static constexpr unsigned kGpuFenceId = 66;
-  static constexpr unsigned kGpuNoFenceId = 0;
-
-  TestContextSupport* test_context_support_;
-
-  cc::FakeOutputSurfaceClient output_surface_client_;
-  std::unique_ptr<FakeOutputSurface> output_surface_;
-  std::unique_ptr<DisplayResourceProviderGL> resource_provider_;
-  scoped_refptr<TestContextProvider> child_context_provider_;
-  std::unique_ptr<ClientResourceProvider> child_resource_provider_;
-  RendererSettings settings_;
-  std::unique_ptr<SingleOverlayOnTopProcessor> overlay_processor_;
-  std::unique_ptr<FakeRendererGL> renderer_;
-  MockOverlayScheduler overlay_scheduler_;
-};
-
-TEST_F(GLRendererWithGpuFenceTest, GpuFenceIdIsUsedWithRootRenderPassOverlay) {
-  gfx::Size viewport_size(100, 100);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  EXPECT_CALL(overlay_scheduler_,
-              Schedule(0, gfx::OVERLAY_TRANSFORM_NONE, kSurfaceOverlayTextureId,
-                       gfx::Rect(viewport_size), _, _, kGpuFenceId))
-      .Times(1);
-  DrawFrame(renderer_.get(), viewport_size);
-}
-
-TEST_F(GLRendererWithGpuFenceTest,
-       GpuFenceIdIsUsedOnlyForRootRenderPassOverlay) {
-  gfx::Size viewport_size(100, 100);
-  AggregatedRenderPass* root_pass = cc::AddRenderPass(
-      &render_passes_in_draw_order_, AggregatedRenderPassId{1},
-      gfx::Rect(viewport_size), gfx::Transform(), cc::FilterOperations());
-  root_pass->has_transparent_background = false;
-
-  bool needs_blending = false;
-  bool premultiplied_alpha = false;
-  bool flipped = false;
-  bool nearest_neighbor = false;
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  gfx::PointF uv_top_left(0, 0);
-  gfx::PointF uv_bottom_right(1, 1);
-
-  TextureDrawQuad* overlay_quad =
-      root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size),
-                       gfx::Rect(50, 50), gfx::MaskFilterInfo(), absl::nullopt,
-                       false, 1, SkBlendMode::kSrcOver, 0);
-  overlay_quad->SetNew(
-      shared_state, gfx::Rect(viewport_size), gfx::Rect(viewport_size),
-      needs_blending, create_overlay_resource(), premultiplied_alpha,
-      uv_top_left, uv_bottom_right, SK_ColorTRANSPARENT, vertex_opacity,
-      flipped, nearest_neighbor,
-      /*secure_output_only=*/false, gfx::ProtectedVideoType::kClear);
-
-  EXPECT_CALL(overlay_scheduler_,
-              Schedule(0, gfx::OVERLAY_TRANSFORM_NONE, kSurfaceOverlayTextureId,
-                       gfx::Rect(viewport_size), _, _, kGpuFenceId))
-      .Times(1);
-  EXPECT_CALL(overlay_scheduler_,
-              Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _,
-                       gfx::Rect(viewport_size), _, _, kGpuNoFenceId))
-      .Times(1);
-  DrawFrame(renderer_.get(), viewport_size);
-}
-#endif  // defined(USE_OZONE) || BUILDFLAG(IS_ANDROID)
-
-}  // namespace
-}  // namespace viz
diff --git a/components/viz/service/display/overlay_ca_unittest.cc b/components/viz/service/display/overlay_ca_unittest.cc
index 2a1b231..fc79f7f6 100644
--- a/components/viz/service/display/overlay_ca_unittest.cc
+++ b/components/viz/service/display/overlay_ca_unittest.cc
@@ -24,10 +24,10 @@
 #include "components/viz/common/quads/stream_video_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/quads/video_hole_draw_quad.h"
+#include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/resources/transferable_resource.h"
 #include "components/viz/service/display/ca_layer_overlay.h"
 #include "components/viz/service/display/display_resource_provider_gl.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
diff --git a/components/viz/service/display/overlay_dc_unittest.cc b/components/viz/service/display/overlay_dc_unittest.cc
index d49769e1..221f9f6 100644
--- a/components/viz/service/display/overlay_dc_unittest.cc
+++ b/components/viz/service/display/overlay_dc_unittest.cc
@@ -22,10 +22,10 @@
 #include "components/viz/common/quads/stream_video_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/quads/video_hole_draw_quad.h"
+#include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/resources/transferable_resource.h"
 #include "components/viz/service/display/dc_layer_overlay.h"
 #include "components/viz/service/display/display_resource_provider_gl.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index bfc32b1b..244f338 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -22,6 +22,7 @@
 #include "cc/test/resource_provider_test_utils.h"
 #include "components/viz/client/client_resource_provider.h"
 #include "components/viz/common/features.h"
+#include "components/viz/common/quads/aggregated_render_pass_draw_quad.h"
 #include "components/viz/common/quads/compositor_render_pass.h"
 #include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
@@ -32,7 +33,6 @@
 #include "components/viz/common/resources/transferable_resource.h"
 #include "components/viz/service/display/ca_layer_overlay.h"
 #include "components/viz/service/display/display_resource_provider_gl.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/output_surface_frame.h"
diff --git a/components/viz/service/display/renderer_perftest.cc b/components/viz/service/display/renderer_perftest.cc
index 827da3a6..3cb09dc 100644
--- a/components/viz/service/display/renderer_perftest.cc
+++ b/components/viz/service/display/renderer_perftest.cc
@@ -4,12 +4,11 @@
 
 // This perf test measures the time from when the display compositor starts
 // drawing on the compositor thread to when a swap buffers occurs on the
-// GPU main thread. It tests both GLRenderer and SkiaRenderer under
-// simple work loads.
+// GPU main thread.
 //
 // Example usage:
 //
-// $ out/release/viz_perftests --gtest_filter="*RendererPerfTest*" \
+// $ out/release/viz_perftests --gtest_filter="RendererPerfTest*" \
 //    --use-gpu-in-tests --test-launcher-timeout=300000 \
 //    --perf-test-time-ms=240000 --disable_discard_framebuffer=1 \
 //    --use_virtualized_gl_contexts=1
@@ -26,9 +25,9 @@
 #include "components/viz/client/client_resource_provider.h"
 #include "components/viz/common/display/renderer_settings.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/output_surface_client.h"
 #include "components/viz/service/display/overlay_processor_stub.h"
 #include "components/viz/service/display/skia_renderer.h"
@@ -229,7 +228,6 @@
 
 }  // namespace
 
-template <typename RendererType>
 class RendererPerfTest : public VizPerfTest {
  public:
   RendererPerfTest()
@@ -243,19 +241,15 @@
   RendererPerfTest(const RendererPerfTest&) = delete;
   RendererPerfTest& operator=(const RendererPerfTest&) = delete;
 
-  // Overloaded for concrete RendererType below.
-  std::unique_ptr<OutputSurface> CreateOutputSurface(
+  std::unique_ptr<SkiaOutputSurface> CreateOutputSurface(
       GpuServiceImpl* gpu_service,
-      DisplayCompositorMemoryAndTaskController* display_controller);
+      DisplayCompositorMemoryAndTaskController* display_controller) {
+    return SkiaOutputSurfaceImpl::Create(display_controller, renderer_settings_,
+                                         &debug_settings_);
+  }
 
   void SetUp() override {
     enable_pixel_output_ = std::make_unique<gl::DisableNullDrawGLBindings>();
-    renderer_settings_.use_skia_renderer =
-        std::is_base_of<SkiaRenderer, RendererType>::value;
-    if (renderer_settings_.use_skia_renderer)
-      printf("Using SkiaRenderer\n");
-    else
-      printf("Using GLRenderer\n");
 
 #if BUILDFLAG(IS_ANDROID)
     renderer_settings_.color_space = gfx::ColorSpace::CreateSRGB();
@@ -320,8 +314,7 @@
 
   void TearDown() override {
     std::string story =
-        renderer_settings_.use_skia_renderer ? "SkiaRenderer_" : "GLRenderer_";
-    story += ::testing::UnitTest::GetInstance()->current_test_info()->name();
+        ::testing::UnitTest::GetInstance()->current_test_info()->name();
     auto reporter = SetUpRendererReporter(story);
     reporter.AddResult(kMetricFps, timer_.LapsPerSecond());
 
@@ -673,57 +666,28 @@
   std::unique_ptr<gl::DisableNullDrawGLBindings> enable_pixel_output_;
 };
 
-template <>
-std::unique_ptr<OutputSurface>
-RendererPerfTest<SkiaRenderer>::CreateOutputSurface(
-    GpuServiceImpl* gpu_service,
-    DisplayCompositorMemoryAndTaskController* display_controller) {
-  return SkiaOutputSurfaceImpl::Create(
-      display_controller, renderer_settings_, &debug_settings_);
-}
-
-template <>
-std::unique_ptr<OutputSurface>
-RendererPerfTest<GLRenderer>::CreateOutputSurface(
-    GpuServiceImpl* gpu_service,
-    DisplayCompositorMemoryAndTaskController* display_controller) {
-  gpu::ImageFactory* image_factory = gpu_service->gpu_image_factory();
-  auto* gpu_channel_manager_delegate =
-      gpu_service->gpu_channel_manager()->delegate();
-  auto context_provider = base::MakeRefCounted<VizProcessContextProvider>(
-      TestGpuServiceHolder::GetInstance()->task_executor(),
-      gpu::kNullSurfaceHandle, gpu_memory_buffer_manager_.get(), image_factory,
-      gpu_channel_manager_delegate, display_controller, renderer_settings_);
-  context_provider->BindToCurrentThread();
-  return std::make_unique<GLOutputSurfaceOffscreen>(
-      std::move(context_provider));
-}
-
-using RendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
-TYPED_TEST_SUITE(RendererPerfTest, RendererTypes);
-
-TYPED_TEST(RendererPerfTest, SingleTextureQuad) {
+TEST_F(RendererPerfTest, SingleTextureQuad) {
   this->RunSingleTextureQuad();
 }
 
-TYPED_TEST(RendererPerfTest, TextureQuads5x5) {
+TEST_F(RendererPerfTest, TextureQuads5x5) {
   this->RunTextureQuads5x5();
 }
 
-TYPED_TEST(RendererPerfTest, TextureQuads5x5SameTex) {
+TEST_F(RendererPerfTest, TextureQuads5x5SameTex) {
   this->RunTextureQuads5x5SameTex();
 }
 
-TYPED_TEST(RendererPerfTest, RotatedTileQuadsShared) {
+TEST_F(RendererPerfTest, RotatedTileQuadsShared) {
   this->RunRotatedTileQuadsShared();
 }
 
-TYPED_TEST(RendererPerfTest, RotatedTileQuads) {
+TEST_F(RendererPerfTest, RotatedTileQuads) {
   this->RunRotatedTileQuads();
 }
 
 #define TOP_REAL_WORLD_DESKTOP_RENDERER_PERF_TEST(SITE, FRAME)              \
-  TYPED_TEST(RendererPerfTest, SITE) {                                      \
+  TEST_F(RendererPerfTest, SITE) {                                          \
     this->RunSingleRenderPassListFromJSON(/*tag=*/"top_real_world_desktop", \
                                           /*site=*/#SITE, /*year=*/2018,    \
                                           /*frame_index=*/FRAME);           \
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index beac6c8..58dc336 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -29,13 +29,16 @@
 #include "cc/test/test_types.h"
 #include "components/viz/client/client_resource_provider.h"
 #include "components/viz/common/features.h"
+#include "components/viz/common/quads/aggregated_render_pass_draw_quad.h"
+#include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
 #include "components/viz/common/quads/picture_draw_quad.h"
+#include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/resources/bitmap_allocation.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/switches.h"
 #include "components/viz/service/display/delegated_ink_point_pixel_test_helper.h"
-#include "components/viz/service/display/gl_renderer.h"
 #include "components/viz/service/display/software_renderer.h"
 #include "components/viz/service/display/viz_pixel_test.h"
 #include "components/viz/test/buildflags.h"
@@ -905,27 +908,6 @@
 // GetGpuRendererTypesNoDawn() can return an empty list, e.g. on Fuchsia ARM64.
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GPURendererPixelTest);
 
-// Provides an exact comparator for GLRenderer and fuzzy comparator for Skia
-// based (eg. SoftwareRenderer and SkiaRenderer).
-class FuzzyForSkiaOnlyPixelComparator : public cc::PixelComparator {
- public:
-  explicit FuzzyForSkiaOnlyPixelComparator(RendererType type) {
-    if (type == RendererType::kGL) {
-      comparator_ = std::make_unique<cc::ExactPixelComparator>(false);
-    } else {
-      comparator_ = std::make_unique<cc::FuzzyPixelOffByOneComparator>(false);
-    }
-  }
-
-  bool Compare(const SkBitmap& actual_bmp,
-               const SkBitmap& expected_bmp) const override {
-    return comparator_->Compare(actual_bmp, expected_bmp);
-  }
-
- private:
-  std::unique_ptr<cc::PixelComparator> comparator_;
-};
-
 TEST_P(RendererPixelTest, SimpleGreenRect) {
   gfx::Rect rect(this->device_viewport_size_);
 
@@ -1788,25 +1770,16 @@
 };
 
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-class VideoRendererPixelHiLoTest
-    : public VideoRendererPixelTestBase,
-      public testing::WithParamInterface<std::tuple<RendererType, bool>> {
+class VideoRendererPixelHiLoTest : public VideoRendererPixelTestBase,
+                                   public testing::WithParamInterface<bool> {
  public:
   VideoRendererPixelHiLoTest()
-      : VideoRendererPixelTestBase(std::get<0>(GetParam())) {}
+      : VideoRendererPixelTestBase(RendererType::kSkiaGL) {}
 
-  bool IsHighbit() const { return std::get<1>(GetParam()); }
+  bool IsHighbit() const { return GetParam(); }
 };
 
-INSTANTIATE_TEST_SUITE_P(,
-                         VideoRendererPixelHiLoTest,
-                         testing::Combine(testing::Values(
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-                                              RendererType::kGL,
-#endif
-                                              RendererType::kSkiaGL),
-                                          testing::Bool()),
-                         cc::PrintTupleToStringParamName());
+INSTANTIATE_TEST_SUITE_P(, VideoRendererPixelHiLoTest, testing::Bool());
 
 TEST_P(VideoRendererPixelHiLoTest, SimpleYUVRect) {
   gfx::Rect rect(this->device_viewport_size_);
@@ -2222,7 +2195,7 @@
   // renderer so use a fuzzy comparator.
   EXPECT_TRUE(this->RunPixelTest(
       &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
-      FuzzyForSkiaOnlyPixelComparator(renderer_type())));
+      cc::FuzzyPixelOffByOneComparator(false)));
 }
 
 TEST_P(RendererPixelTest, FastPassSaturateFilter) {
@@ -2282,7 +2255,7 @@
   // renderer so use a fuzzy comparator.
   EXPECT_TRUE(this->RunPixelTest(
       &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
-      FuzzyForSkiaOnlyPixelComparator(renderer_type())));
+      cc::FuzzyPixelOffByOneComparator(false)));
 }
 
 TEST_P(RendererPixelTest, FastPassFilterChain) {
@@ -2344,7 +2317,7 @@
   EXPECT_TRUE(this->RunPixelTest(
       &pass_list,
       base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
-      FuzzyForSkiaOnlyPixelComparator(renderer_type())));
+      cc::FuzzyPixelOffByOneComparator(false)));
 }
 
 TEST_P(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
@@ -2427,7 +2400,7 @@
   EXPECT_TRUE(this->RunPixelTest(
       &pass_list,
       base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
-      FuzzyForSkiaOnlyPixelComparator(renderer_type())));
+      cc::FuzzyPixelOffByOneComparator(false)));
 }
 
 TEST_P(RendererPixelTest, EnlargedRenderPassTexture) {
@@ -3090,11 +3063,6 @@
 }
 
 TEST_P(RendererPixelTestWithBackdropFilter, InvertFilterWithMask) {
-  // TODO(crbug.com/989312): Delete this condition with GLRendere. The mask
-  // appears to be offset from the correct location but this isn't relevant.
-  if (is_gl_renderer())
-    return;
-
   this->backdrop_filters_.Append(cc::FilterOperation::CreateInvertFilter(1.f));
   this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
   this->filter_pass_layer_rect_.Inset(gfx::Insets::TLBR(14, 12, 18, 16));
@@ -3112,170 +3080,6 @@
                                  cc::FuzzyPixelOffByOneComparator(false)));
 }
 
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-class GLRendererPixelTestWithBackdropFilter : public VizPixelTest {
- public:
-  GLRendererPixelTestWithBackdropFilter() : VizPixelTest(RendererType::kGL) {}
-
- protected:
-  void SetUpRenderPassList() {
-    pass_list_.clear();
-    gfx::Rect device_viewport_rect(this->device_viewport_size_);
-
-    AggregatedRenderPassId root_id{1};
-    auto root_pass = CreateTestRootRenderPass(root_id, device_viewport_rect);
-    root_pass->has_transparent_background = false;
-
-    gfx::Transform identity_quad_to_target_transform;
-
-    AggregatedRenderPassId filter_pass_id{2};
-    gfx::Transform transform_to_root;
-    auto filter_pass = CreateTestRenderPass(
-        filter_pass_id, filter_pass_layer_rect_, transform_to_root);
-    filter_pass->backdrop_filters = this->backdrop_filters_;
-    filter_pass->backdrop_filter_bounds = this->backdrop_filter_bounds_;
-
-    // A non-visible quad in the filtering render pass.
-    {
-      SharedQuadState* shared_state = CreateTestSharedQuadState(
-          identity_quad_to_target_transform, filter_pass_layer_rect_,
-          filter_pass.get(), gfx::MaskFilterInfo());
-      auto* color_quad =
-          filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-      color_quad->SetNew(shared_state, filter_pass_layer_rect_,
-                         filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
-    }
-
-    {
-      SharedQuadState* shared_state = CreateTestSharedQuadState(
-          filter_pass_to_target_transform_, filter_pass_layer_rect_,
-          filter_pass.get(), gfx::MaskFilterInfo());
-      auto* filter_pass_quad =
-          root_pass->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>();
-      filter_pass_quad->SetAll(
-          shared_state, filter_pass_layer_rect_, filter_pass_layer_rect_,
-          /*needs_blending=*/true, filter_pass_id, kInvalidResourceId,
-          gfx::RectF(), gfx::Size(),
-          gfx::Vector2dF(1.0f, 1.0f),  // filters_scale
-          gfx::PointF(),               // filters_origin
-          gfx::RectF(),                // tex_coord_rect
-          false,                       // force_anti_aliasing_off
-          backdrop_filter_quality_,    // backdrop_filter_quality
-          intersects_damage_under_);
-    }
-
-    const int kGridWidth = device_viewport_rect.width() / 3;
-    const int kGridHeight = device_viewport_rect.height() / 3;
-    gfx::Rect left_rect =
-        gfx::Rect(kGridWidth / 2, kGridHeight, kGridWidth, kGridHeight);
-
-    SharedQuadState* shared_state = CreateTestSharedQuadState(
-        identity_quad_to_target_transform, left_rect, root_pass.get(),
-        gfx::MaskFilterInfo());
-    auto* color_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    color_quad->SetNew(shared_state, left_rect, left_rect, SK_ColorGREEN,
-                       false);
-
-    gfx::Rect right_rect =
-        gfx::Rect(kGridWidth * 3 / 2, kGridHeight, kGridWidth, kGridHeight);
-    shared_state = CreateTestSharedQuadState(
-        identity_quad_to_target_transform, right_rect, root_pass.get(),
-        gfx::MaskFilterInfo());
-    color_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    color_quad->SetNew(shared_state, right_rect, right_rect, SK_ColorRED,
-                       false);
-
-    shared_state = CreateTestSharedQuadState(
-        identity_quad_to_target_transform, device_viewport_rect,
-        root_pass.get(), gfx::MaskFilterInfo());
-    auto* background_quad =
-        root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    background_quad->SetNew(shared_state, device_viewport_rect,
-                            device_viewport_rect, SK_ColorWHITE, false);
-
-    pass_list_.push_back(std::move(filter_pass));
-    pass_list_.push_back(std::move(root_pass));
-  }
-
-  AggregatedRenderPassList pass_list_;
-  cc::FilterOperations backdrop_filters_;
-  absl::optional<gfx::RRectF> backdrop_filter_bounds_;
-  float backdrop_filter_quality_ = 1.0f;
-  bool intersects_damage_under_ = true;
-  gfx::Transform filter_pass_to_target_transform_;
-  gfx::Rect filter_pass_layer_rect_;
-};
-
-TEST_F(GLRendererPixelTestWithBackdropFilter, FilterQuality) {
-  this->backdrop_filters_.Append(cc::FilterOperation::CreateBlurFilter(2.0f));
-  this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
-  this->backdrop_filter_bounds_ =
-      gfx::RRectF(gfx::RectF(this->filter_pass_layer_rect_));
-  this->backdrop_filter_quality_ = 1.0f;
-  this->SetUpRenderPassList();
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_1.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-
-  if (this->context_provider()->ContextCapabilities().major_version < 3)
-    return;
-  this->backdrop_filter_quality_ = 0.33f;
-  this->SetUpRenderPassList();
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_2.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-}
-
-TEST_F(GLRendererPixelTestWithBackdropFilter, CachedResultOfBackdropFilter) {
-  this->backdrop_filters_.Append(cc::FilterOperation::CreateBlurFilter(2.0f));
-  this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
-  this->backdrop_filter_bounds_ =
-      gfx::RRectF(gfx::RectF(this->filter_pass_layer_rect_));
-  // Set the flag to use cached backdrop filtered texture. This makes the
-  // GLRenderer cache backdrop filtered result.
-  this->intersects_damage_under_ = false;
-  this->SetUpRenderPassList();
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_1.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-
-  // Same render pass list makes the GLRenderer to skip backdrop filter
-  // calculation and use cached texture. This should correctly produce the
-  // same output image.
-  this->SetUpRenderPassList();
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_1.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-
-  // To prove the cached texture is used, change a quad on the root pass which
-  // is beneath the backdrop filter. The output image should still be the same
-  // as before.
-  this->SetUpRenderPassList();
-  DrawQuad* background_quad = *pass_list_.back()->quad_list.rbegin();
-  static_cast<SolidColorDrawQuad*>(background_quad)->color = SK_ColorYELLOW;
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_1.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-
-  // Set |intersects_damage_under_| to true to make GLRenderer re-run the
-  // backdrop filter calculation
-  this->intersects_damage_under_ = true;
-  this->SetUpRenderPassList();
-  background_quad = *pass_list_.back()->quad_list.rbegin();
-  static_cast<SolidColorDrawQuad*>(background_quad)->color = SK_ColorYELLOW;
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("gl_backdrop_filter_3.png")),
-      cc::FuzzyPixelOffByOneComparator(true)));
-}
-#endif
-
 // Software renderer does not support anti-aliased edges.
 TEST_P(GPURendererPixelTest, AntiAliasing) {
   gfx::Rect rect(this->device_viewport_size_);
@@ -4597,21 +4401,10 @@
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(root_pass));
 
-  if (is_gl_renderer()) {
-    // GL Renderer should have an exact match as that is the reference point.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
-        cc::ExactPixelComparator(true)));
-  } else {
-    // Software/skia renderer uses skia rrect to create rounded corner clip.
-    // This results in a different corner path due to a different anti aliasing
-    // approach than the fragment shader in gl renderer.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
-        cc::FuzzyPixelComparator(true, 0.55f, 0.f, 255.f, 255, 0)));
-  }
+  EXPECT_TRUE(this->RunPixelTest(
+      &pass_list,
+      base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
+      cc::FuzzyPixelComparator(true, 0.55f, 0.f, 255.f, 255, 0)));
 }
 
 TEST_P(GPURendererPixelTest, RoundedCornerSimpleTextureDrawQuad) {
@@ -4666,21 +4459,10 @@
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(root_pass));
 
-  if (is_gl_renderer()) {
-    // GL Renderer should have an exact match as that is the reference point.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
-        cc::ExactPixelComparator(true)));
-  } else {
-    // SkiaRenderer uses skia rrect to create rounded corner clip. This results
-    // in a different corner path due to a different anti aliasing approach than
-    // the fragment shader in gl renderer.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
-        cc::FuzzyPixelComparator(true, 0.6f, 0.f, 255.f, 255, 0)));
-  }
+  EXPECT_TRUE(this->RunPixelTest(
+      &pass_list,
+      base::FilePath(FILE_PATH_LITERAL("rounded_corner_simple.png")),
+      cc::FuzzyPixelComparator(true, 0.6f, 0.f, 255.f, 255, 0)));
 }
 
 TEST_P(RendererPixelTest, RoundedCornerOnRenderPass) {
@@ -4781,21 +4563,13 @@
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(root_pass));
 
-  if (is_gl_renderer()) {
-    // GL Renderer should have an exact match as that is the reference point.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_radii.png")),
-        cc::ExactPixelComparator(true)));
-  } else {
-    // Software/skia renderer uses skia rrect to create rounded corner clip.
-    // This results in a different corner path due to a different anti aliasing
-    // approach than the fragment shader in gl renderer.
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_radii.png")),
-        cc::FuzzyPixelComparator(true, 0.55f, 0.f, 255.f, 255, 0)));
-  }
+  // Software/skia renderer uses skia rrect to create rounded corner clip.
+  // This results in a different corner path due to a different anti aliasing
+  // approach than the fragment shader in gl renderer.
+  EXPECT_TRUE(this->RunPixelTest(
+      &pass_list,
+      base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_radii.png")),
+      cc::FuzzyPixelComparator(true, 0.55f, 0.f, 255.f, 255, 0)));
 }
 
 TEST_P(RendererPixelTest, RoundedCornerMultipleQads) {
@@ -4874,21 +4648,11 @@
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(root_pass));
 
-  // GL Renderer should have an exact match as that is the reference point.
-  // Software/skia renderer use skia rrect to create rounded corner clip.
-  // This results in a different corner path due to a different anti aliasing
-  // approach than the fragment shader in gl renderer.
-  std::unique_ptr<cc::PixelComparator> comparator;
-  comparator.reset(
-      is_gl_renderer()
-          ? static_cast<cc::PixelComparator*>(
-                new cc::ExactPixelComparator(true))
-          : static_cast<cc::PixelComparator*>(
-                new cc::FuzzyPixelComparator(true, 0.55f, 0.f, 255.f, 255, 0)));
+  cc::FuzzyPixelComparator comparator(true, 0.55f, 0.f, 255.f, 255, 0);
   EXPECT_TRUE(this->RunPixelTest(
       &pass_list,
       base::FilePath(FILE_PATH_LITERAL("rounded_corner_multi_quad.png")),
-      *comparator));
+      comparator));
 }
 
 class RendererPixelTestWithOverdrawFeedback : public VizPixelTestWithParam {
@@ -4920,19 +4684,12 @@
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(pass));
 
-  if (is_gl_renderer()) {
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("translucent_rectangles.png")),
-        cc::ExactPixelComparator(true)));
-  } else {
-    // TODO(xing.xu): investigate why overdraw feedback has small difference
-    // (http://crbug.com/909971)
-    EXPECT_TRUE(this->RunPixelTest(
-        &pass_list,
-        base::FilePath(FILE_PATH_LITERAL("skia_translucent_rectangles.png")),
-        cc::FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
-  }
+  // TODO(xing.xu): investigate why overdraw feedback has small difference
+  // (http://crbug.com/909971)
+  EXPECT_TRUE(this->RunPixelTest(
+      &pass_list,
+      base::FilePath(FILE_PATH_LITERAL("translucent_rectangles.png")),
+      cc::FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
 }
 
 INSTANTIATE_TEST_SUITE_P(,
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc
index 07e18fe..aa9f8cd 100644
--- a/components/viz/service/display/surface_aggregator_pixeltest.cc
+++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -339,10 +339,6 @@
 // Draw a simple frame with a delegated ink trail on top of it, then confirm
 // that it is erased by the next aggregation.
 TEST_P(SurfaceAggregatorPixelTest, DrawAndEraseDelegatedInkTrail) {
-  // DelegatedInkTrail isn't supported on non-Skia renderers.
-  if (renderer_type() == RendererType::kGL)
-    return;
-
   DelegatedInkPointPixelTestHelper delegated_ink_helper(renderer_.get());
 
   // Create and send metadata and points to the renderer that will be drawn.
diff --git a/components/viz/service/display/viz_pixel_test.cc b/components/viz/service/display/viz_pixel_test.cc
index c68d0e6..c3076fa 100644
--- a/components/viz/service/display/viz_pixel_test.cc
+++ b/components/viz/service/display/viz_pixel_test.cc
@@ -30,9 +30,6 @@
     case RendererType::kSoftware:
       SetUpSoftwareRenderer();
       break;
-    case RendererType::kGL:
-      SetUpGLRenderer(GetSurfaceOrigin());
-      break;
     case RendererType::kSkiaGL:
     case RendererType::kSkiaVk:
     case RendererType::kSkiaDawn:
diff --git a/components/viz/service/display/viz_pixel_test.h b/components/viz/service/display/viz_pixel_test.h
index ee041e7..5a3ca05d 100644
--- a/components/viz/service/display/viz_pixel_test.h
+++ b/components/viz/service/display/viz_pixel_test.h
@@ -33,8 +33,6 @@
     switch (renderer_type_) {
       case RendererType::kSoftware:
         return "software";
-      case RendererType::kGL:
-        return "gl";
       case RendererType::kSkiaGL:
       case RendererType::kSkiaVk:
         return "skia";
@@ -47,8 +45,6 @@
     return renderer_type_ == RendererType::kSoftware;
   }
 
-  bool is_gl_renderer() const { return renderer_type_ == RendererType::kGL; }
-
  protected:
   static GraphicsBackend RenderTypeToBackend(RendererType renderer_type);
 
diff --git a/components/viz/service/transitions/surface_animation_manager.cc b/components/viz/service/transitions/surface_animation_manager.cc
index 019856c..e7afbc05 100644
--- a/components/viz/service/transitions/surface_animation_manager.cc
+++ b/components/viz/service/transitions/surface_animation_manager.cc
@@ -321,9 +321,7 @@
 
 SurfaceAnimationManager::SurfaceAnimationManager(
     SharedBitmapManager* shared_bitmap_manager)
-    : animation_slowdown_factor_(
-          switches::GetDocumentTransitionSlowDownFactor()),
-      transferable_resource_tracker_(shared_bitmap_manager) {}
+    : transferable_resource_tracker_(shared_bitmap_manager) {}
 
 SurfaceAnimationManager::~SurfaceAnimationManager() = default;
 
@@ -1068,10 +1066,8 @@
               : gfx::CubicBezierTimingFunction::EaseType::EASE_OUT);
 
   // Create the transform curve.
-  base::TimeDelta total_duration =
-      ApplySlowdownFactor(save_directive_->root_config().duration);
-  base::TimeDelta total_delay =
-      ApplySlowdownFactor(save_directive_->root_config().delay);
+  base::TimeDelta total_duration = save_directive_->root_config().duration;
+  base::TimeDelta total_delay = save_directive_->root_config().delay;
 
   // The transform animation runs for the entire duration of the root
   // transition.
@@ -1130,14 +1126,14 @@
     const bool has_src_element = shared.has_value();
 
     const auto& config = save_directive_->shared_elements()[i].config;
-    const auto total_duration = ApplySlowdownFactor(config.duration);
-    const auto total_delay = ApplySlowdownFactor(config.delay);
+    const auto total_duration = config.duration;
+    const auto total_delay = config.delay;
 
-    const auto opacity_duration = ApplySlowdownFactor(
-        total_duration * kSharedOpacityTransitionDurationScaleFactor);
-    const auto opacity_delay = ApplySlowdownFactor(
+    const auto opacity_duration =
+        total_duration * kSharedOpacityTransitionDurationScaleFactor;
+    const auto opacity_delay =
         total_delay +
-        (total_duration * kSharedOpacityTransitionDelayScaleFactor));
+        (total_duration * kSharedOpacityTransitionDelayScaleFactor);
 
     // The kSrcOpacity curve animates the screen space opacity applied to the
     // blended content from src and dest elements. The value goes from the
@@ -1319,11 +1315,6 @@
   return &surface_saved_frame_storage_;
 }
 
-base::TimeDelta SurfaceAnimationManager::ApplySlowdownFactor(
-    base::TimeDelta original) const {
-  return original * animation_slowdown_factor_;
-}
-
 // RootAnimationState
 SurfaceAnimationManager::RootAnimationState::RootAnimationState() = default;
 SurfaceAnimationManager::RootAnimationState::RootAnimationState(
diff --git a/components/viz/service/transitions/surface_animation_manager.h b/components/viz/service/transitions/surface_animation_manager.h
index 03efd96..03a9623 100644
--- a/components/viz/service/transitions/surface_animation_manager.h
+++ b/components/viz/service/transitions/surface_animation_manager.h
@@ -159,8 +159,6 @@
   // Returns true if we have a running animation for root or shared elements.
   bool HasRunningAnimations() const;
 
-  base::TimeDelta ApplySlowdownFactor(base::TimeDelta original) const;
-
   // The state machine can take the following paths :
   // 1) Viz driven animation : kIdle -> kAnimating -> kLastFrame -> kIdle
   // 2) Renderer driven animation : kIdle -> kAnimatingRenderer -> kIdle
@@ -170,7 +168,6 @@
 
   uint32_t last_processed_sequence_id_ = 0;
 
-  const int animation_slowdown_factor_ = 1;
   TransferableResourceTracker transferable_resource_tracker_;
 
   absl::optional<TransferableResourceTracker::ResourceFrame> saved_textures_;
diff --git a/components/viz/test/BUILD.gn b/components/viz/test/BUILD.gn
index 147c6dfd..ba5d6888 100644
--- a/components/viz/test/BUILD.gn
+++ b/components/viz/test/BUILD.gn
@@ -11,7 +11,6 @@
   header = "buildflags.h"
 
   flags = [
-    "ENABLE_GL_RENDERER_TESTS=$enable_gl_renderer_tests",
     "ENABLE_GL_BACKEND_TESTS=$enable_gl_backend_tests",
     "ENABLE_VULKAN_BACKEND_TESTS=$enable_vulkan_backend_tests",
     "ENABLE_DAWN_BACKEND_TESTS=$enable_dawn_backend_tests",
diff --git a/components/viz/test/data/anti_aliasing_gl.png b/components/viz/test/data/anti_aliasing_gl.png
deleted file mode 100644
index 721d77b..0000000
--- a/components/viz/test/data/anti_aliasing_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/anti_aliasing_perspective_gl.png b/components/viz/test/data/anti_aliasing_perspective_gl.png
deleted file mode 100644
index 53ed4d9..0000000
--- a/components/viz/test/data/anti_aliasing_perspective_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/backdrop_filter_blur_gl.png b/components/viz/test/data/backdrop_filter_blur_gl.png
deleted file mode 100644
index d44f2ff4..0000000
--- a/components/viz/test/data/backdrop_filter_blur_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/backdrop_filter_blur_off_axis_gl.png b/components/viz/test/data/backdrop_filter_blur_off_axis_gl.png
deleted file mode 100644
index 0f97d7a..0000000
--- a/components/viz/test/data/backdrop_filter_blur_off_axis_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/backdrop_filter_blur_radius_gl.png b/components/viz/test/data/backdrop_filter_blur_radius_gl.png
deleted file mode 100644
index 25f3a631..0000000
--- a/components/viz/test/data/backdrop_filter_blur_radius_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/backdrop_filter_on_scaled_layer_gl.png b/components/viz/test/data/backdrop_filter_on_scaled_layer_gl.png
deleted file mode 100644
index e08e814f..0000000
--- a/components/viz/test/data/backdrop_filter_on_scaled_layer_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/backdrop_filter_rotated_gl.png b/components/viz/test/data/backdrop_filter_rotated_gl.png
deleted file mode 100644
index ff18be1..0000000
--- a/components/viz/test/data/backdrop_filter_rotated_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/blending_render_pass_cm.png b/components/viz/test/data/blending_render_pass_cm.png
deleted file mode 100644
index 9a72d44..0000000
--- a/components/viz/test/data/blending_render_pass_cm.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/blending_render_pass_mask_cm.png b/components/viz/test/data/blending_render_pass_mask_cm.png
deleted file mode 100644
index 4e210aa3..0000000
--- a/components/viz/test/data/blending_render_pass_mask_cm.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/blur_filter_with_clip_gl.png b/components/viz/test/data/blur_filter_with_clip_gl.png
deleted file mode 100644
index c4c6b83..0000000
--- a/components/viz/test/data/blur_filter_with_clip_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/checkers.png b/components/viz/test/data/checkers.png
deleted file mode 100644
index fdd2ee3b..0000000
--- a/components/viz/test/data/checkers.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/checkers_big.png b/components/viz/test/data/checkers_big.png
deleted file mode 100644
index 48edf608..0000000
--- a/components/viz/test/data/checkers_big.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_backdrop_filter_1.png b/components/viz/test/data/gl_backdrop_filter_1.png
deleted file mode 100644
index 9651d82..0000000
--- a/components/viz/test/data/gl_backdrop_filter_1.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_backdrop_filter_2.png b/components/viz/test/data/gl_backdrop_filter_2.png
deleted file mode 100644
index a039a49e..0000000
--- a/components/viz/test/data/gl_backdrop_filter_2.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_backdrop_filter_3.png b/components/viz/test/data/gl_backdrop_filter_3.png
deleted file mode 100644
index 50535c54..0000000
--- a/components/viz/test/data/gl_backdrop_filter_3.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_solid_color_DstIn.png b/components/viz/test/data/gl_solid_color_DstIn.png
deleted file mode 100644
index 35ef6a0..0000000
--- a/components/viz/test/data/gl_solid_color_DstIn.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_solid_color_DstOut.png b/components/viz/test/data/gl_solid_color_DstOut.png
deleted file mode 100644
index 35ef6a0..0000000
--- a/components/viz/test/data/gl_solid_color_DstOut.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_solid_color_Screen.png b/components/viz/test/data/gl_solid_color_Screen.png
deleted file mode 100644
index fc9630c8..0000000
--- a/components/viz/test/data/gl_solid_color_Screen.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/gl_solid_color_SrcOver.png b/components/viz/test/data/gl_solid_color_SrcOver.png
deleted file mode 100644
index fc9630c8..0000000
--- a/components/viz/test/data/gl_solid_color_SrcOver.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_of_backdrop_filter_and_blend_gl.png b/components/viz/test/data/mask_of_backdrop_filter_and_blend_gl.png
deleted file mode 100644
index 809b626..0000000
--- a/components/viz/test/data/mask_of_backdrop_filter_and_blend_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_of_replica.png b/components/viz/test/data/mask_of_replica.png
deleted file mode 100644
index 94e261d8..0000000
--- a/components/viz/test/data/mask_of_replica.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_of_replica_of_clipped_layer.png b/components/viz/test/data/mask_of_replica_of_clipped_layer.png
deleted file mode 100644
index 598da07..0000000
--- a/components/viz/test/data/mask_of_replica_of_clipped_layer.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_with_replica.png b/components/viz/test/data/mask_with_replica.png
deleted file mode 100644
index a330b08a..0000000
--- a/components/viz/test/data/mask_with_replica.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/mask_with_replica_of_clipped_layer.png b/components/viz/test/data/mask_with_replica_of_clipped_layer.png
deleted file mode 100644
index 2b786a7..0000000
--- a/components/viz/test/data/mask_with_replica_of_clipped_layer.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/rasp-grayator-half.png b/components/viz/test/data/rasp-grayator-half.png
deleted file mode 100644
index a5a8126..0000000
--- a/components/viz/test/data/rasp-grayator-half.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/rasp-grayator.png b/components/viz/test/data/rasp-grayator.png
deleted file mode 100644
index 1ca92be..0000000
--- a/components/viz/test/data/rasp-grayator.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/rotated_drop_shadow_filter_gl.png b/components/viz/test/data/rotated_drop_shadow_filter_gl.png
deleted file mode 100644
index 39b2207..0000000
--- a/components/viz/test/data/rotated_drop_shadow_filter_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/rotated_filter_gl.png b/components/viz/test/data/rotated_filter_gl.png
deleted file mode 100644
index 7576814..0000000
--- a/components/viz/test/data/rotated_filter_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/rounded_corner_render_pass_gl.png b/components/viz/test/data/rounded_corner_render_pass_gl.png
deleted file mode 100644
index 49f930b8..0000000
--- a/components/viz/test/data/rounded_corner_render_pass_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/scaled_mask_with_effect_gl.png b/components/viz/test/data/scaled_mask_with_effect_gl.png
deleted file mode 100644
index e309bf2..0000000
--- a/components/viz/test/data/scaled_mask_with_effect_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/scaled_render_surface_layer_gl.png b/components/viz/test/data/scaled_render_surface_layer_gl.png
deleted file mode 100644
index fbf764b..0000000
--- a/components/viz/test/data/scaled_render_surface_layer_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/skia_translucent_rectangles.png b/components/viz/test/data/skia_translucent_rectangles.png
deleted file mode 100644
index 36e26996..0000000
--- a/components/viz/test/data/skia_translucent_rectangles.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/translucent_rectangles.png b/components/viz/test/data/translucent_rectangles.png
index 22cdf0a..36e26996 100644
--- a/components/viz/test/data/translucent_rectangles.png
+++ b/components/viz/test/data/translucent_rectangles.png
Binary files differ
diff --git a/components/viz/test/data/wrap_mode_repeat.png b/components/viz/test/data/wrap_mode_repeat.png
deleted file mode 100644
index b6406019..0000000
--- a/components/viz/test/data/wrap_mode_repeat.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/data/zoom_filter_gl.png b/components/viz/test/data/zoom_filter_gl.png
deleted file mode 100644
index 4eaa23c..0000000
--- a/components/viz/test/data/zoom_filter_gl.png
+++ /dev/null
Binary files differ
diff --git a/components/viz/test/test_types.cc b/components/viz/test/test_types.cc
index d5e5056..30f55af5 100644
--- a/components/viz/test/test_types.cc
+++ b/components/viz/test/test_types.cc
@@ -13,8 +13,6 @@
 // Provides a test renderer suffix appropriate for |type|.
 const char* RendererTypeTestSuffix(RendererType type) {
   switch (type) {
-    case RendererType::kGL:
-      return "GL";
     case RendererType::kSkiaGL:
       return "SkiaGL";
     case RendererType::kSkiaVk:
@@ -33,10 +31,6 @@
   if (include_software && !skia_only)
     types.push_back(RendererType::kSoftware);
 #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS)
-#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS)
-  if (!skia_only)
-    types.push_back(RendererType::kGL);
-#endif
   types.push_back(RendererType::kSkiaGL);
 #endif
 #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS)
diff --git a/components/viz/test/test_types.h b/components/viz/test/test_types.h
index e4062cc..3c004ae8 100644
--- a/components/viz/test/test_types.h
+++ b/components/viz/test/test_types.h
@@ -11,7 +11,6 @@
 namespace viz {
 
 enum class RendererType {
-  kGL,
   kSkiaGL,
   kSkiaVk,
   // SkiaRenderer with the Dawn backend will be used; on Linux this will
diff --git a/components/viz/viz.gni b/components/viz/viz.gni
index 8cf2736..a8edfac 100644
--- a/components/viz/viz.gni
+++ b/components/viz/viz.gni
@@ -10,10 +10,6 @@
 # that code path.
 enable_gl_backend_tests = !is_fuchsia
 
-# Controls if GLRenderer related tests should be built and run.
-# TODO(crbug.com/1247756): Delete this flag along with GLRenderer.
-enable_gl_renderer_tests = false
-
 # TODO(samans): Support more configurations.
 # CFI issue: https://crbug.com/967819
 # Fuchsia ARM64 https://crbug.com/1058247
diff --git a/components/web_app_resources/web_app_default_offline.html b/components/web_app_resources/web_app_default_offline.html
index e52bc50..407b833 100644
--- a/components/web_app_resources/web_app_default_offline.html
+++ b/components/web_app_resources/web_app_default_offline.html
@@ -17,7 +17,7 @@
 </head>
   <body style="font-family: $i18n{fontfamily};font-size:$i18n{fontsize}">
     <img id="icon" src=$i18n{icon_url}>
-    <h1>$i18n{app_short_name}</h1>
+    <h1 id="app-name">$i18n{app_short_name}</h1>
     <h2 id="default-web-app-msg">$i18n{web_app_default_offline_message}</h2>
     <!--TODO(crbug.com/1285723: Add web app icon.)-->
   </body>
diff --git a/components/webapk/android/libs/client/BUILD.gn b/components/webapk/android/libs/client/BUILD.gn
index 4a6bb82..928bf20 100644
--- a/components/webapk/android/libs/client/BUILD.gn
+++ b/components/webapk/android/libs/client/BUILD.gn
@@ -27,7 +27,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/webapps/browser/android/BUILD.gn b/components/webapps/browser/android/BUILD.gn
index 70dde2df..9a5de41 100644
--- a/components/webapps/browser/android/BUILD.gn
+++ b/components/webapps/browser/android/BUILD.gn
@@ -172,7 +172,6 @@
   ]
   deps = [
     ":java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//base/test:test_support_java",
diff --git a/components/webxr/android/BUILD.gn b/components/webxr/android/BUILD.gn
index 7038a71..75fe703 100644
--- a/components/webxr/android/BUILD.gn
+++ b/components/webxr/android/BUILD.gn
@@ -64,6 +64,7 @@
   ]
 
   deps = [
+    "//components/browser_ui/widget/android:java",
     "//content/public/android:content_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
diff --git a/components/webxr/android/DEPS b/components/webxr/android/DEPS
index 4193c50..8e978f1 100644
--- a/components/webxr/android/DEPS
+++ b/components/webxr/android/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/gesture/BackPressHandler.java",
   "+components/messages",
   "+components/resources/android/theme_resources.h",
   "+components/strings/grit/components_strings.h",
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreJavaUtils.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreJavaUtils.java
index 28cf52e9..4cca526 100644
--- a/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreJavaUtils.java
+++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArCoreJavaUtils.java
@@ -15,6 +15,8 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.supplier.ObservableSupplier;
+import org.chromium.base.supplier.ObservableSupplierImpl;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
 
@@ -44,6 +46,10 @@
     // session.
     private static ArCoreJavaUtils sActiveSessionInstance;
 
+    /** Whether there is a non-null valid {@link #sActiveSessionInstance}. */
+    private static ObservableSupplierImpl<Boolean> sActiveSessionAvailableSupplier =
+            new ObservableSupplierImpl<>();
+
     // Helper, obtains android Activity out of passed in WebContents instance.
     // Equivalent to ChromeActivity.fromWebContents(), but does not require that
     // the resulting instance is a ChromeActivity.
@@ -86,6 +92,7 @@
         if (DEBUG_LOGS) Log.i(TAG, "startSession");
         mArImmersiveOverlay = new ArImmersiveOverlay();
         sActiveSessionInstance = this;
+        sActiveSessionAvailableSupplier.set(true);
         mArImmersiveOverlay.show(compositorDelegateProvider.create(webContents), webContents, this,
                 useOverlay, canRenderDomContent);
     }
@@ -98,6 +105,7 @@
         mArImmersiveOverlay.cleanupAndExit();
         mArImmersiveOverlay = null;
         sActiveSessionInstance = null;
+        sActiveSessionAvailableSupplier.set(false);
     }
 
     // Called from ArDelegateImpl
@@ -116,6 +124,10 @@
         return sActiveSessionInstance != null;
     }
 
+    public static ObservableSupplier<Boolean> hasActiveArSessionSupplier() {
+        return sActiveSessionAvailableSupplier;
+    }
+
     public void onDrawingSurfaceReady(
             Surface surface, WindowAndroid rootWindow, int rotation, int width, int height) {
         if (DEBUG_LOGS) Log.i(TAG, "onDrawingSurfaceReady");
diff --git a/components/webxr/android/java/src/org/chromium/components/webxr/ArDelegate.java b/components/webxr/android/java/src/org/chromium/components/webxr/ArDelegate.java
index 0369b43f..742235f 100644
--- a/components/webxr/android/java/src/org/chromium/components/webxr/ArDelegate.java
+++ b/components/webxr/android/java/src/org/chromium/components/webxr/ArDelegate.java
@@ -4,18 +4,20 @@
 
 package org.chromium.components.webxr;
 
+import org.chromium.components.browser_ui.widget.gesture.BackPressHandler;
+
 /**
  * Interface used by ChromeActivity to communicate with AR code that is only
  * available if |enable_arcore| is set to true at build time.
  */
-public interface ArDelegate {
+public interface ArDelegate extends BackPressHandler {
     /**
      * Used to let AR immersive mode intercept the Back button to exit immersive mode.
      */
-    public boolean onBackPressed();
+    boolean onBackPressed();
 
     /**
      * Used to query if there is an active immersive AR Session.
      */
-    public boolean hasActiveArSession();
+    boolean hasActiveArSession();
 }
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
index 40d4c9e..f453694 100644
--- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
+++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -37,6 +37,7 @@
 #include "third_party/abseil-cpp/absl/numeric/int128.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace content {
 
@@ -429,7 +430,7 @@
 
   for (const auto& event_trigger : trigger.event_triggers()) {
     web_ui_trigger->event_triggers.emplace_back(
-        base::in_place,
+        absl::in_place,
         /*data=*/event_trigger.data,
         /*priority=*/event_trigger.priority,
         /*deduplication_key=*/event_trigger.dedup_key
diff --git a/content/browser/attribution_reporting/attribution_src_browsertest.cc b/content/browser/attribution_reporting/attribution_src_browsertest.cc
index 982ed28..b5cc736 100644
--- a/content/browser/attribution_reporting/attribution_src_browsertest.cc
+++ b/content/browser/attribution_reporting/attribution_src_browsertest.cc
@@ -468,6 +468,36 @@
             url::Origin::Create(GURL("https://d.test")));
 }
 
+IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest, NoReferrer) {
+  // Create a separate server as we cannot register a `ControllableHttpResponse`
+  // after the server starts.
+  auto https_server = std::make_unique<net::EmbeddedTestServer>(
+      net::EmbeddedTestServer::TYPE_HTTPS);
+  https_server->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+  net::test_server::RegisterDefaultHandlers(https_server.get());
+  https_server->ServeFilesFromSourceDirectory(
+      "content/test/data/attribution_reporting");
+  https_server->ServeFilesFromSourceDirectory("content/test/data");
+
+  auto register_response =
+      std::make_unique<net::test_server::ControllableHttpResponse>(
+          https_server.get(), "/register_source");
+  ASSERT_TRUE(https_server->Start());
+
+  GURL page_url =
+      https_server->GetURL("b.test", "/page_with_impression_creator.html");
+  EXPECT_TRUE(NavigateToURL(web_contents(), page_url));
+
+  GURL register_url = https_server->GetURL("d.test", "/register_source");
+  EXPECT_TRUE(ExecJs(web_contents(),
+                     JsReplace("createAttributionSrcImg($1);", register_url)));
+
+  register_response->WaitForRequest();
+  const net::test_server::HttpRequest* request =
+      register_response->http_request();
+  EXPECT_TRUE(request->headers.find("Referer") == request->headers.end());
+}
+
 IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest,
                        AttributionSrcImg_TriggerRegistered) {
   GURL page_url =
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index 7ba9abdb..3ffdcf4 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -39,6 +39,7 @@
 #include "content/browser/prerender/prerender_internals_ui.h"
 #include "content/browser/process_internals/process_internals.mojom.h"
 #include "content/browser/process_internals/process_internals_ui.h"
+#include "content/browser/quota/quota_context.h"
 #include "content/browser/quota/quota_internals_ui.h"
 #include "content/browser/renderer_host/clipboard_host_impl.h"
 #include "content/browser/renderer_host/file_utilities_host_impl.h"
@@ -378,11 +379,11 @@
 }
 
 void BindQuotaManagerHost(
-    RenderFrameHost* host,
+    RenderFrameHostImpl* host,
     mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) {
-  host->GetProcess()->BindQuotaManagerHost(host->GetRoutingID(),
-                                           host->GetLastCommittedOrigin(),
-                                           std::move(receiver));
+  host->GetStoragePartition()->GetQuotaContext()->BindQuotaManagerHost(
+      host->GetProcess()->GetID(), host->GetRoutingID(), host->storage_key(),
+      std::move(receiver));
 }
 
 void BindNativeIOHost(
@@ -1268,6 +1269,8 @@
       &RenderProcessHostImpl::BindNativeIOHost, host));
   map->Add<blink::mojom::LockManager>(BindWorkerReceiverForStorageKey(
       &RenderProcessHostImpl::CreateLockManager, host));
+  map->Add<blink::mojom::QuotaManagerHost>(BindWorkerReceiverForStorageKey(
+      &RenderProcessHostImpl::BindQuotaManagerHost, host));
 }
 
 void PopulateBinderMapWithContext(
@@ -1285,9 +1288,6 @@
   map->Add<blink::mojom::NotificationService>(
       BindWorkerReceiverForOriginAndFrameId(
           &RenderProcessHostImpl::CreateNotificationService, host));
-  map->Add<blink::mojom::QuotaManagerHost>(
-      BindWorkerReceiverForOriginAndFrameId(
-          &RenderProcessHostImpl::BindQuotaManagerHost, host));
 }
 
 void PopulateBinderMap(DedicatedWorkerHost* host, mojo::BinderMap* map) {
@@ -1361,6 +1361,8 @@
       &RenderProcessHostImpl::CreateWebSocketConnector, host));
   map->Add<blink::mojom::LockManager>(BindWorkerReceiverForStorageKey(
       &RenderProcessHostImpl::CreateLockManager, host));
+  map->Add<blink::mojom::QuotaManagerHost>(BindWorkerReceiverForStorageKey(
+      &RenderProcessHostImpl::BindQuotaManagerHost, host));
 }
 
 void PopulateBinderMapWithContext(
@@ -1378,9 +1380,6 @@
   map->Add<blink::mojom::NotificationService>(
       BindWorkerReceiverForOriginAndFrameId(
           &RenderProcessHostImpl::CreateNotificationService, host));
-  map->Add<blink::mojom::QuotaManagerHost>(
-      BindWorkerReceiverForOriginAndFrameId(
-          &RenderProcessHostImpl::BindQuotaManagerHost, host));
 }
 
 void PopulateBinderMap(SharedWorkerHost* host, mojo::BinderMap* map) {
@@ -1488,14 +1487,14 @@
           &RenderProcessHostImpl::CreateWebSocketConnector, host));
   map->Add<blink::mojom::LockManager>(BindServiceWorkerReceiverForStorageKey(
       &RenderProcessHostImpl::CreateLockManager, host));
+  map->Add<blink::mojom::QuotaManagerHost>(
+      BindServiceWorkerReceiverForStorageKey(
+          &RenderProcessHostImpl::BindQuotaManagerHost, host));
 
   // RenderProcessHost binders taking a frame id and an origin
   map->Add<blink::mojom::NotificationService>(
       BindServiceWorkerReceiverForOriginAndFrameId(
           &RenderProcessHostImpl::CreateNotificationService, host));
-  map->Add<blink::mojom::QuotaManagerHost>(
-      BindServiceWorkerReceiverForOriginAndFrameId(
-          &RenderProcessHostImpl::BindQuotaManagerHost, host));
 
   // Give the embedder a chance to register binders.
   GetContentClient()
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index f5b91aa..bbc7c3ec 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -1489,12 +1489,16 @@
     int child_id,
     const IsolationContext& isolation_context,
     const UrlInfo& url_info) {
+  DCHECK(url_info.origin.has_value());
   const url::Origin url_origin =
-      url::Origin::Resolve(url_info.url, url_info.origin);
+      url::Origin::Resolve(url_info.url, *url_info.origin);
   if (!CanAccessDataForOrigin(child_id, url_origin)) {
     // Check for special cases, like blob:null/ and data: URLs, where the
     // origin does not contain information to match against the process lock,
-    // but using the whole URL can result in a process lock match.
+    // but using the whole URL can result in a process lock match.  Note that
+    // the origin being committed in `url_info.origin` will not actually be
+    // used when computing `expected_process_lock` below in many cases; see
+    // https://crbug.com/1320402.
     const auto expected_process_lock =
         ProcessLock::Create(isolation_context, url_info);
     const ProcessLock& actual_process_lock = GetProcessLock(child_id);
@@ -1504,7 +1508,7 @@
     return CanCommitStatus::CANNOT_COMMIT_URL;
   }
 
-  if (!CanAccessDataForOrigin(child_id, url_info.origin))
+  if (!CanAccessDataForOrigin(child_id, *url_info.origin))
     return CanCommitStatus::CANNOT_COMMIT_ORIGIN;
 
   // Ensure that the origin derived from |url| is consistent with |origin|.
@@ -1513,7 +1517,7 @@
   const auto url_tuple_or_precursor_tuple =
       url_origin.GetTupleOrPrecursorTupleIfOpaque();
   const auto origin_tuple_or_precursor_tuple =
-      url_info.origin.GetTupleOrPrecursorTupleIfOpaque();
+      url_info.origin->GetTupleOrPrecursorTupleIfOpaque();
 
   if (url_tuple_or_precursor_tuple.IsValid() &&
       origin_tuple_or_precursor_tuple.IsValid() &&
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index ea2a45b7..dfa07ec5 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -3037,7 +3037,6 @@
             UrlInfo::OriginIsolationRequest::kOriginAgentCluster |
             UrlInfo::OriginIsolationRequest::kRequiresOriginKeyedProcess);
     UrlInfo url_info(UrlInfoInit(foo.GetURL())
-                         .WithOrigin(foo)
                          .WithOriginIsolationRequest(origin_isolation_request));
     scoped_refptr<SiteInstanceImpl> foo_instance =
         SiteInstanceImpl::CreateForUrlInfo(&context, url_info,
@@ -3094,7 +3093,7 @@
     p->AddFutureIsolatedOrigins({url::Origin::Create(GURL("https://foo.com"))},
                                 IsolatedOriginSource::TEST, &context);
 
-    UrlInfo url_info(UrlInfoInit(foo.GetURL()).WithOrigin(foo));
+    UrlInfo url_info(UrlInfoInit(foo.GetURL()));
     scoped_refptr<SiteInstanceImpl> foo_instance =
         SiteInstanceImpl::CreateForUrlInfo(&context, url_info,
                                            /*is_guest=*/false);
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl.cc b/content/browser/first_party_sets/first_party_sets_handler_impl.cc
index 71a2542..6a1117f5 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl.cc
@@ -74,7 +74,8 @@
 // static
 FirstPartySetsHandlerImpl* FirstPartySetsHandlerImpl::GetInstance() {
   static base::NoDestructor<FirstPartySetsHandlerImpl> instance(
-      GetContentClient()->browser()->IsFirstPartySetsEnabled());
+      GetContentClient()->browser()->IsFirstPartySetsEnabled(),
+      GetContentClient()->browser()->WillProvidePublicFirstPartySets());
   return instance.get();
 }
 
@@ -89,8 +90,12 @@
       policy, /*out_sets=*/nullptr);
 }
 
-FirstPartySetsHandlerImpl::FirstPartySetsHandlerImpl(bool enabled)
-    : enabled_(enabled) {
+FirstPartySetsHandlerImpl::FirstPartySetsHandlerImpl(
+    bool enabled,
+    bool embedder_will_provide_public_sets)
+    : enabled_(enabled),
+      embedder_will_provide_public_sets_(enabled &&
+                                         embedder_will_provide_public_sets) {
   sets_loader_ = std::make_unique<FirstPartySetsLoader>(
       base::BindOnce(&FirstPartySetsHandlerImpl::SetCompleteSets,
                      // base::Unretained(this) is safe here because
@@ -115,10 +120,14 @@
   on_sets_ready_ = std::move(on_sets_ready);
   SetPersistedSets(user_data_dir);
 
-  if (!IsEnabled())
-    SetCompleteSets({});
-  else
+  if (IsEnabled()) {
     sets_loader_->SetManuallySpecifiedSet(flag_value);
+    if (!embedder_will_provide_public_sets_) {
+      sets_loader_->SetComponentSets(base::File());
+    }
+  } else {
+    SetCompleteSets({});
+  }
 }
 
 bool FirstPartySetsHandlerImpl::IsEnabled() const {
@@ -128,16 +137,16 @@
 
 void FirstPartySetsHandlerImpl::SetPublicFirstPartySets(base::File sets_file) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!IsEnabled()) {
-    sets_loader_->DisposeFile(std::move(sets_file));
-    return;
-  }
+  DCHECK(enabled_);
+  DCHECK(embedder_will_provide_public_sets_);
   sets_loader_->SetComponentSets(std::move(sets_file));
 }
 
 void FirstPartySetsHandlerImpl::ResetForTesting() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   enabled_ = GetContentClient()->browser()->IsFirstPartySetsEnabled();
+  embedder_will_provide_public_sets_ =
+      GetContentClient()->browser()->WillProvidePublicFirstPartySets();
 
   // Initializes the `sets_loader_` member with a callback to SetCompleteSets
   // and the result of content::GetFirstPartySetsOverrides.
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl.h b/content/browser/first_party_sets/first_party_sets_handler_impl.h
index 1e15b04a..f1a6d4d 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl.h
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl.h
@@ -78,6 +78,11 @@
     enabled_ = enabled;
   }
 
+  void SetEmbedderWillProvidePublicSetsForTesting(bool will_provide) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    embedder_will_provide_public_sets_ = enabled_ && will_provide;
+  }
+
   // Compares the map `old_sets` to `current_sets` and returns the set of sites
   // that: 1) were in `old_sets` but are no longer in `current_sets`, i.e. leave
   // the FPSs; or, 2) mapped to a different owner site.
@@ -92,7 +97,8 @@
  private:
   friend class base::NoDestructor<FirstPartySetsHandlerImpl>;
 
-  explicit FirstPartySetsHandlerImpl(bool enabled);
+  FirstPartySetsHandlerImpl(bool enabled,
+                            bool embedder_will_provide_public_sets);
 
   // This method reads the persisted First-Party Sets from the file under
   // `user_data_dir`.
@@ -137,6 +143,7 @@
   base::FilePath persisted_sets_path_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   bool enabled_ GUARDED_BY_CONTEXT(sequence_checker_);
+  bool embedder_will_provide_public_sets_ GUARDED_BY_CONTEXT(sequence_checker_);
 
   // We use a OnceCallback to ensure we only pass along the sets once
   // during Chrome's lifetime (modulo reconfiguring the network service).
diff --git a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
index 0c0eeda6..3e92801e 100644
--- a/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
+++ b/content/browser/first_party_sets/first_party_sets_handler_impl_unittest.cc
@@ -367,14 +367,6 @@
             FAIL();  // Should not be called.
           }));
 
-  // Set required inputs to be able to receive the merged sets from
-  // FirstPartySetsLoader.
-  const std::string input =
-      "{\"owner\": \"https://example.test\",\"members\": "
-      "[\"https://aaaa.test\"]}";
-  ASSERT_TRUE(base::JSONReader::Read(input));
-  SetPublicFirstPartySetsAndWait(input);
-
   env().RunUntilIdle();
 
   // TODO(shuuran@chromium.org): test site state is cleared.
@@ -397,9 +389,6 @@
             FAIL();  // Should not be called.
           }));
 
-  SetPublicFirstPartySetsAndWait(R"({"owner": "https://example.test", )"
-                                 R"("members": ["https://member.test"]})");
-
   EXPECT_EQ(
       FirstPartySetsHandlerImpl::GetInstance()->GetSetsIfEnabledAndReady(),
       absl::nullopt);
@@ -413,11 +402,6 @@
 };
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest, PersistedSetsNotReady) {
-  const std::string input = R"({"owner": "https://foo.test", )"
-                            R"("members": ["https://member2.test"]})";
-  ASSERT_TRUE(base::JSONReader::Read(input));
-  SetPublicFirstPartySetsAndWait(input);
-
   // Empty `user_data_dir` will fail loading persisted sets.
   FirstPartySetsHandlerImpl::GetInstance()->Init(
       /*user_data_dir=*/{},
@@ -431,6 +415,8 @@
 }
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest, PublicFirstPartySetsNotReady) {
+  FirstPartySetsHandlerImpl::GetInstance()
+      ->SetEmbedderWillProvidePublicSetsForTesting(true);
   ASSERT_TRUE(base::WriteFile(persisted_sets_path_, "{}"));
 
   // Persisted sets are expected to be loaded with the provided path.
@@ -447,6 +433,8 @@
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest,
        Successful_PersistedSetsFileNotExist) {
+  FirstPartySetsHandlerImpl::GetInstance()
+      ->SetEmbedderWillProvidePublicSetsForTesting(true);
   const std::string input = R"({"owner": "https://foo.test", )"
                             R"("members": ["https://member2.test"]})";
   ASSERT_TRUE(base::JSONReader::Read(input));
@@ -479,6 +467,8 @@
 }
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest, Successful_PersistedSetsEmpty) {
+  FirstPartySetsHandlerImpl::GetInstance()
+      ->SetEmbedderWillProvidePublicSetsForTesting(true);
   ASSERT_TRUE(base::WriteFile(persisted_sets_path_, "{}"));
 
   const std::string input = R"({"owner": "https://foo.test", )"
@@ -514,6 +504,8 @@
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest,
        GetSetsIfEnabledAndReady_AfterSetsReady) {
+  FirstPartySetsHandlerImpl::GetInstance()
+      ->SetEmbedderWillProvidePublicSetsForTesting(true);
   ASSERT_TRUE(base::WriteFile(persisted_sets_path_, "{}"));
 
   const std::string input = R"({"owner": "https://example.test", )"
@@ -549,6 +541,8 @@
 
 TEST_F(FirstPartySetsHandlerImplEnabledTest,
        GetSetsIfEnabledAndReady_BeforeSetsReady) {
+  FirstPartySetsHandlerImpl::GetInstance()
+      ->SetEmbedderWillProvidePublicSetsForTesting(true);
   ASSERT_TRUE(base::WriteFile(persisted_sets_path_, "{}"));
 
   // Call GetSetsIfEnabledAndReady before the sets are ready.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 2b130ae..11e2a00a 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -254,7 +254,6 @@
     switches::kEnableLogging,
     switches::kEnableDeJelly,
     switches::kDeJellyScreenWidth,
-    switches::kDocumentTransitionSlowdownFactor,
     switches::kDoubleBufferCompositing,
     switches::kHeadless,
     switches::kLoggingLevel,
diff --git a/content/browser/interest_group/auction_runner.cc b/content/browser/interest_group/auction_runner.cc
index 1782a320..a49475a3 100644
--- a/content/browser/interest_group/auction_runner.cc
+++ b/content/browser/interest_group/auction_runner.cc
@@ -980,21 +980,6 @@
     OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage);
     return;
   }
-  // Component Auctions must receive a `component_auction_modified_bid_params`,
-  // and top-level Auctions must not.
-  if (component_auction_modified_bid_params.is_null() != (parent_ == nullptr)) {
-    mojo::ReportBadMessage("Invalid component_auction_modified_bid_params");
-    OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage);
-    return;
-  }
-  // If a component seller modified, the new bid must also be valid.
-  if (component_auction_modified_bid_params &&
-      component_auction_modified_bid_params->has_bid &&
-      !IsValidBid(component_auction_modified_bid_params->bid)) {
-    mojo::ReportBadMessage("Invalid component_auction_modified_bid_params bid");
-    OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage);
-    return;
-  }
   errors_.insert(errors_.end(), errors.begin(), errors.end());
 
   // Use separate fields for component and top-level seller reports, so both can
@@ -1017,6 +1002,23 @@
     return;
   }
 
+  // If they accept a bid / return a positive score, component auction
+  // SellerWorklets must return a `component_auction_modified_bid_params`, and
+  // top-level auctions must not.
+  if (component_auction_modified_bid_params.is_null() != (parent_ == nullptr)) {
+    mojo::ReportBadMessage("Invalid component_auction_modified_bid_params");
+    OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage);
+    return;
+  }
+  // If a component seller modified the bid, the new bid must also be valid.
+  if (component_auction_modified_bid_params &&
+      component_auction_modified_bid_params->has_bid &&
+      !IsValidBid(component_auction_modified_bid_params->bid)) {
+    mojo::ReportBadMessage("Invalid component_auction_modified_bid_params bid");
+    OnBiddingAndScoringComplete(AuctionResult::kBadMojoMessage);
+    return;
+  }
+
   bool is_top_bid = false;
   const url::Origin& owner = bid->interest_group->owner;
 
diff --git a/content/browser/interest_group/auction_runner_unittest.cc b/content/browser/interest_group/auction_runner_unittest.cc
index 95a4e9d..26995cf 100644
--- a/content/browser/interest_group/auction_runner_unittest.cc
+++ b/content/browser/interest_group/auction_runner_unittest.cc
@@ -3019,6 +3019,66 @@
                   /*expected_sellers=*/3);
 }
 
+// Test case where a single component auction accepts one bid and rejects
+// another. This is a regression test for https://crbug.com/1321941, where a
+// rejected bid from a component auction would be treated as a security error,
+// and result in bidding in the component auction being aborted, and all
+// previous bids being thrown out.
+TEST_F(AuctionRunnerTest, ComponentAuctionAcceptsBidRejectsBid) {
+  // Script used by the winning bidder. It makes the lower bid.
+  const char kBidder1Script[] = R"(
+      function generateBid(interestGroup, auctionSignals, perBuyerSignals,
+                           trustedBiddingSignals, browserSignals) {
+        return {bid: 1, render: interestGroup.ads[0].renderUrl,
+                allowComponentAuction: true};
+      }
+
+    function reportWin() {}
+  )";
+
+  // Script used by the losing bidder. It makes the higher bid.
+  const char kBidder2Script[] = R"(
+      function generateBid(interestGroup, auctionSignals, perBuyerSignals,
+                           trustedBiddingSignals, browserSignals) {
+        return {bid: 2, render: interestGroup.ads[0].renderUrl,
+                allowComponentAuction: true};
+      }
+  )";
+
+  // Script used for both sellers. It rejects bids over 1.
+  const std::string kSellerScript = R"(
+    function scoreAd(adMetadata, bid, auctionConfig, browserSignals) {
+      if (bid > 1)
+        return {desirability: 0, allowComponentAuction: true};
+      return {desirability: bid, allowComponentAuction: true};
+    }
+
+    function reportResult() {}
+  )";
+
+  // Set up a component auction using the normal helper function, but then
+  // overwrite the scripts.
+  SetUpComponentAuctionAndResponses(/*bidder1_seller=*/kComponentSeller1,
+                                    /*bidder2_seller=*/kComponentSeller1,
+                                    /*bid_from_component_auction_wins=*/false);
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder1Url,
+                                         kBidder1Script);
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kBidder2Url,
+                                         kBidder2Script);
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_, kSellerUrl,
+                                         kSellerScript);
+  auction_worklet::AddJavascriptResponse(&url_loader_factory_,
+                                         kComponentSeller1Url, kSellerScript);
+
+  RunStandardAuction();
+  EXPECT_THAT(result_.errors, testing::ElementsAre());
+
+  EXPECT_EQ("https://ad1.com/", result_.ad_url);
+  CheckHistograms(AuctionRunner::AuctionResult::kSuccess,
+                  /*expected_interest_groups=*/2, /*expected_owners=*/2,
+                  /*expected_sellers=*/2);
+}
+
 // A component auction with one component that has two buyers. In this auction,
 // the top-level auction would score kBidder2 higher (since it bids more), but
 // kBidder1 wins this auction, because the component auctions use a different
diff --git a/content/browser/locks/lock_manager.cc b/content/browser/locks/lock_manager.cc
index 047135f..531cce2 100644
--- a/content/browser/locks/lock_manager.cc
+++ b/content/browser/locks/lock_manager.cc
@@ -22,6 +22,7 @@
 #include "ipc/ipc_message.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using blink::mojom::LockMode;
 
@@ -283,7 +284,7 @@
       for (const auto& lock : request_queue) {
         std::vector<blink::mojom::LockInfoPtr>& target =
             lock.is_granted() ? held : requests;
-        target.emplace_back(base::in_place, lock.name(), lock.mode(),
+        target.emplace_back(absl::in_place, lock.name(), lock.mode(),
                             lock.client_id());
       }
     }
diff --git a/content/browser/media/audio_input_stream_broker_unittest.cc b/content/browser/media/audio_input_stream_broker_unittest.cc
index fc6d650..f5cc987 100644
--- a/content/browser/media/audio_input_stream_broker_unittest.cc
+++ b/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -21,6 +21,7 @@
 #include "services/audio/public/cpp/fake_stream_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using ::testing::InSequence;
 using ::testing::Mock;
@@ -231,7 +232,7 @@
   base::SyncSocket socket1, socket2;
   base::SyncSocket::CreatePair(&socket1, &socket2);
   std::move(stream_request_data.created_callback)
-      .Run({base::in_place,
+      .Run({absl::in_place,
             base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
             mojo::PlatformHandle(socket1.Take())},
            kInitiallyMuted, base::UnguessableToken::Create());
diff --git a/content/browser/media/audio_loopback_stream_broker_unittest.cc b/content/browser/media/audio_loopback_stream_broker_unittest.cc
index a775e79..54311bd 100644
--- a/content/browser/media/audio_loopback_stream_broker_unittest.cc
+++ b/content/browser/media/audio_loopback_stream_broker_unittest.cc
@@ -21,6 +21,7 @@
 #include "services/audio/public/cpp/fake_stream_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using ::testing::_;
 using ::testing::Test;
@@ -227,7 +228,7 @@
   base::SyncSocket socket1, socket2;
   base::SyncSocket::CreatePair(&socket1, &socket2);
   std::move(stream_request_data.created_callback)
-      .Run({base::in_place,
+      .Run({absl::in_place,
             base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
             mojo::PlatformHandle(socket1.Take())});
 
@@ -257,7 +258,7 @@
   base::SyncSocket socket1, socket2;
   base::SyncSocket::CreatePair(&socket1, &socket2);
   std::move(stream_request_data.created_callback)
-      .Run({base::in_place,
+      .Run({absl::in_place,
             base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
             mojo::PlatformHandle(socket1.Take())});
 
@@ -287,7 +288,7 @@
   base::SyncSocket socket1, socket2;
   base::SyncSocket::CreatePair(&socket1, &socket2);
   std::move(stream_request_data.created_callback)
-      .Run({base::in_place,
+      .Run({absl::in_place,
             base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
             mojo::PlatformHandle(socket1.Take())});
 
diff --git a/content/browser/media/audio_output_stream_broker_unittest.cc b/content/browser/media/audio_output_stream_broker_unittest.cc
index fa62e1d..c00a467 100644
--- a/content/browser/media/audio_output_stream_broker_unittest.cc
+++ b/content/browser/media/audio_output_stream_broker_unittest.cc
@@ -25,6 +25,7 @@
 #include "services/audio/public/cpp/fake_stream_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using ::testing::Test;
 using ::testing::Mock;
@@ -212,7 +213,7 @@
   base::SyncSocket socket1, socket2;
   base::SyncSocket::CreatePair(&socket1, &socket2);
   std::move(stream_request_data.created_callback)
-      .Run({base::in_place, base::UnsafeSharedMemoryRegion::Create(kShMemSize),
+      .Run({absl::in_place, base::UnsafeSharedMemoryRegion::Create(kShMemSize),
             mojo::PlatformHandle(socket1.Take())});
 
   EXPECT_CALL(env.provider_client, OnCreated());
diff --git a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc
index 733ca0b4..a4989f1b 100644
--- a/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc
+++ b/content/browser/renderer_host/dwrite_font_proxy_impl_win.cc
@@ -31,6 +31,7 @@
 #include "content/public/common/content_features.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/font_unique_name_lookup/font_unique_name_table.pb.h"
 #include "third_party/blink/public/common/font_unique_name_lookup/icu_fold_case_util.h"
 #include "third_party/skia/include/core/SkFontMgr.h"
@@ -214,7 +215,7 @@
     }
     CHECK_EQ(L'\0', name[length - 1]);
 
-    family_names.emplace_back(base::in_place, base::WideToUTF16(locale.data()),
+    family_names.emplace_back(absl::in_place, base::WideToUTF16(locale.data()),
                               base::WideToUTF16(name.data()));
   }
   std::move(callback).Run(std::move(family_names));
diff --git a/content/browser/renderer_host/frame_tree_browsertest.cc b/content/browser/renderer_host/frame_tree_browsertest.cc
index a534c30..a00d4de 100644
--- a/content/browser/renderer_host/frame_tree_browsertest.cc
+++ b/content/browser/renderer_host/frame_tree_browsertest.cc
@@ -2334,8 +2334,8 @@
 // Tests successfully going back to a page with a fenced frame.
 IN_PROC_BROWSER_TEST_P(FencedFrameTreeBrowserTest,
                        GoBackToPageWithFencedFrame) {
-  GURL main_url(https_server()->GetURL(
-      "a.test", "/fenced_frames/basic_fenced_frame_src.html"));
+  GURL main_url(
+      https_server()->GetURL("a.test", "/fenced_frames/opaque_ads.html"));
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
   // It is safe to obtain the root frame tree node here, as it doesn't change.
@@ -2371,7 +2371,7 @@
   // Navigate the fenced frame. It should do a replace navigation and therefore
   // the `controller().GetEntryCount()` stays at 1.
   GURL fenced_frame_url_2(
-      https_server()->GetURL("a.test", "/fenced_frames/title1.html"));
+      https_server()->GetURL("c.test", "/fenced_frames/title1.html"));
   std::string script = JsReplace("location.assign($1);", fenced_frame_url_2);
   UpdateHistoryOrReloadFromFencedFrameTreeAndWaitForFinishedLoad(fenced_frame,
                                                                  script);
@@ -2420,6 +2420,41 @@
     EXPECT_EQ(fenced_frame_url_1,
               fenced_frame->current_frame_host()->GetLastCommittedURL());
   }
+
+  // Reloading a page with a fenced frame should work. Ensure that the main
+  // navigation happens as well as the navigation within the fenced frame.
+  // A page with a fenced frame, when reloaded, will cause the fenced frame
+  // to navigate to its initial URL.
+  TestNavigationObserver reload_observer(web_contents());
+  EXPECT_TRUE(ExecJs(root, "window.location.reload();"));
+  reload_observer.Wait();
+  EXPECT_EQ(2, root->navigator().controller().GetEntryCount());
+  EXPECT_TRUE(reload_observer.last_navigation_succeeded());
+  fenced_frame = GetFencedFrameRootNode(root->child_at(0));
+  EXPECT_EQ(fenced_frame_url_1, fenced_frame->current_url());
+
+  // Now let's try to use unfencedTop and come back to the page with the fenced
+  // frame.
+  TestFrameNavigationObserver observer(root);
+  EXPECT_TRUE(ExecJs(fenced_frame, JsReplace("window.open($1, '_unfencedTop');",
+                                             new_main_url)));
+  observer.Wait();
+  EXPECT_EQ(2, root->navigator().controller().GetEntryCount());
+  EXPECT_EQ(new_main_url, root->current_frame_host()->GetLastCommittedURL());
+
+  // Go back.
+  {
+    TestNavigationObserver back_load_observer(shell()->web_contents());
+    EXPECT_TRUE(ExecJs(root, "history.back();"));
+    back_load_observer.Wait();
+  }
+  EXPECT_EQ(2, root->navigator().controller().GetEntryCount());
+  EXPECT_EQ(main_url, root->current_frame_host()->GetLastCommittedURL());
+  EXPECT_EQ(1U, root->child_count());
+  fenced_frame = GetFencedFrameRootNode(root->child_at(0));
+  EXPECT_TRUE(fenced_frame->IsFencedFrameRoot());
+  EXPECT_TRUE(fenced_frame->IsInFencedFrameTree());
+  EXPECT_EQ(fenced_frame_url_1, fenced_frame->current_url());
 }
 
 // Simulates the crash in crbug.com/1317642 by disabling BFCache and going back
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index 2a6bc417..2410289 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -3158,22 +3158,40 @@
     }
   }
 
-  // TODO(crbug.com/1172042): Remove WebBundle-specific code here.
+  UrlInfoInit url_info_init(GetURL());
+  url_info_init.WithOriginIsolationRequest(isolation_request)
+      .WithWebExposedIsolationInfo(web_exposed_isolation_info)
+      .WithIsPdf(is_pdf_)
+      .WithSandbox(is_origin_restricted_sandbox);
+
   if (GetWebBundleURL().is_valid()) {
-    return UrlInfo(UrlInfoInit(GetURL())
-                       .WithOriginIsolationRequest(isolation_request)
-                       .WithOrigin(url::Origin::Resolve(
-                           GetURL(), url::Origin::Create(GetWebBundleURL())))
-                       .WithWebExposedIsolationInfo(web_exposed_isolation_info)
-                       .WithIsPdf(is_pdf_)
-                       .WithSandbox(is_origin_restricted_sandbox));
+    // Web Bundle navigations should use the origin of the bundle rather than
+    // the target URL.
+    //
+    // TODO(crbug.com/1172042): Remove WebBundle-specific code here.
+    url_info_init.WithOrigin(
+        url::Origin::Resolve(GetURL(), url::Origin::Create(GetWebBundleURL())));
+  } else if (IsLoadDataWithBaseURL()) {
+    // LoadDataWithBaseURL() navigations also need to explicitly set the origin
+    // to the origin of the base URL.  This ensures that the process for this
+    // navigation will eventually be locked to the right origin (i.e., origin of
+    // the base URL rather than the data: URL).
+    //
+    // Note that while LoadDataWithBaseURL() is supported in <webview> tags on
+    // desktop platforms and on Android Webview, only <webview> tags currently
+    // utilize this special case when running in site-isolated mode. Android
+    // Webview doesn't currently lock processes for LoadDataWithBaseURL()
+    // navigations.
+    url_info_init.WithOrigin(
+        url::Origin::Create(common_params().base_url_for_data_url));
+  } else {
+    // Overriding the origin for a URL is dangerous and only allowed in very
+    // narrow cases which are handled explicitly above.  Please think very
+    // carefully about any new cases that need to do this.
+    DCHECK(!url_info_init.origin().has_value());
   }
 
-  return UrlInfo(UrlInfoInit(GetURL())
-                     .WithOriginIsolationRequest(isolation_request)
-                     .WithWebExposedIsolationInfo(web_exposed_isolation_info)
-                     .WithIsPdf(is_pdf_)
-                     .WithSandbox(is_origin_restricted_sandbox));
+  return UrlInfo(url_info_init);
 }
 
 const GURL& NavigationRequest::GetOriginalRequestURL() {
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc
index 6e53e78c..cfc5263 100644
--- a/content/browser/renderer_host/navigator.cc
+++ b/content/browser/renderer_host/navigator.cc
@@ -433,14 +433,21 @@
 
   // If `url` is one that is allowed in WebUI renderer process, ensure that its
   // origin is either opaque or its process lock matches the RFH process lock.
+  // As an example, the origin may be opaque if a WebUI navigation resulted in
+  // an error page.
+  //
+  // TODO(alexmos): Currently, `is_allowed_in_web_ui_renderer` is unexpectedly
+  // true for about:blank and renderer debug URLs, even when they commit with
+  // an origin that is not allowed into a WebUI renderer.  For now, these cases
+  // are also skipped via the origin opaqueness check, but
+  // `is_allowed_in_web_ui_renderer` should be strengthened to not be true in
+  // this case so that the checks above also apply.  See
+  // https://crbug.com/1320402.
   if (is_allowed_in_web_ui_renderer) {
-    url::Origin url_origin =
-        url::Origin::Create(url.DeprecatedGetOriginAsURL());
-
     // Verify `site_info`'s process lock matches the RFH's process lock, if one
     // is in place.
     if (should_lock_process) {
-      if (!url_origin.opaque() &&
+      if (!url::Origin::Create(url).opaque() &&
           process_lock != ProcessLock::FromSiteInfo(site_info)) {
         return false;
       }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index ccc45f6..86bcc11 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2028,14 +2028,11 @@
 }
 
 void RenderProcessHostImpl::BindQuotaManagerHost(
-    int render_frame_id,
-    const url::Origin& origin,
+    const blink::StorageKey& storage_key,
     mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // TODO(crbug.com/1215208): Pass the StorageKey from the function arguments,
-  // once migrated.
   storage_partition_impl_->GetQuotaContext()->BindQuotaManagerHost(
-      GetID(), render_frame_id, blink::StorageKey(origin), std::move(receiver));
+      GetID(), MSG_ROUTING_NONE, storage_key, std::move(receiver));
 }
 
 void RenderProcessHostImpl::CreateLockManager(
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 0e6a74e..c680411 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -615,11 +615,11 @@
           receiver) override;
 
   // Binds |receiver| to a QuotaManagerHost instance indirectly owned by the
-  // StoragePartition associated with the render process host. Used by frames
-  // and workers via BrowserInterfaceBroker.
+  // StoragePartition associated with the render process host. Used by workers
+  // via BrowserInterfaceBroker. Frames should call out to QuotaContext directly
+  // to pass in the correct frame id as well.
   void BindQuotaManagerHost(
-      int render_frame_id,
-      const url::Origin& origin,
+      const blink::StorageKey& storage_key,
       mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) override;
 
   // Binds |receiver| to the LockManager owned by |storage_partition_impl_|.
diff --git a/content/browser/site_info.cc b/content/browser/site_info.cc
index dfca737..45713abc 100644
--- a/content/browser/site_info.cc
+++ b/content/browser/site_info.cc
@@ -773,23 +773,28 @@
                        real_url)
                  : real_url;
 
-  // Navigations to uuid-in-package: URLs served from Web Bundles [1] require
-  // special care to use the origin of the bundle rather than the
-  // uuid-in-package: URL, which lacks any origin information.
+  // Figure out the origin to use for computing the site URL. In most cases,
+  // this should just be `url`'s origin. However, there are some exceptions
+  // where an alternate origin must be used. Namely, for navigations to URLs
+  // served from Web Bundles [1], this should be the origin of the web bundle
+  // rather than the uuid-in-package: URL, which lacks any origin information.
+  // For LoadDataWithBaseURL navigations, this should be the origin of the base
+  // URL rather than the data URL. In these cases, we should use the alternate
+  // origin which will be passed through UrlInfo, ensuring to use its precursor
+  // if the origin is opaque (as will be the case for Web Bundles) to still
+  // compute a meaningful site URL.
+  //
   // [1] bit.ly/subresource-web-bundles-doc
-  // TODO(acolwell): Update this so we can use url::Origin::Resolve() for all
-  // cases.
   url::Origin origin;
-  if (url.SchemeIs(url::kUuidInPackageScheme) &&
-      real_url_info.origin.opaque()) {
-    auto precursor = real_url_info.origin.GetTupleOrPrecursorTupleIfOpaque();
+  bool scheme_allows_origin_override =
+      url.SchemeIs(url::kUuidInPackageScheme) || url.SchemeIs(url::kDataScheme);
+  if (real_url_info.origin.has_value() && scheme_allows_origin_override) {
+    auto precursor = real_url_info.origin->GetTupleOrPrecursorTupleIfOpaque();
     if (precursor.IsValid()) {
-      // Use the precursor as the origin. This should be the origin of the
-      // bundle.
       origin = url::Origin::CreateFromNormalizedTuple(
           precursor.scheme(), precursor.host(), precursor.port());
     } else {
-      origin = url::Origin::Resolve(url, real_url_info.origin);
+      origin = url::Origin::Resolve(url, real_url_info.origin.value());
     }
   } else {
     origin = url::Origin::Create(url);
diff --git a/content/browser/url_info.cc b/content/browser/url_info.cc
index 2d5a34e0..d989329 100644
--- a/content/browser/url_info.cc
+++ b/content/browser/url_info.cc
@@ -28,9 +28,8 @@
 UrlInfo UrlInfo::CreateForTesting(
     const GURL& url_in,
     absl::optional<StoragePartitionConfig> storage_partition_config) {
-  return UrlInfo(UrlInfoInit(url_in)
-                     .WithOrigin(url::Origin::Create(url_in))
-                     .WithStoragePartitionConfig(storage_partition_config));
+  return UrlInfo(
+      UrlInfoInit(url_in).WithStoragePartitionConfig(storage_partition_config));
 }
 
 bool UrlInfo::IsIsolated() const {
@@ -41,8 +40,7 @@
 
 UrlInfoInit::UrlInfoInit(UrlInfoInit&) = default;
 
-UrlInfoInit::UrlInfoInit(const GURL& url)
-    : url_(url), origin_(url::Origin::Create(url)) {}
+UrlInfoInit::UrlInfoInit(const GURL& url) : url_(url) {}
 
 UrlInfoInit::UrlInfoInit(const UrlInfo& base)
     : url_(base.url),
diff --git a/content/browser/url_info.h b/content/browser/url_info.h
index 1404bab..7ea11a8 100644
--- a/content/browser/url_info.h
+++ b/content/browser/url_info.h
@@ -111,10 +111,19 @@
   OriginIsolationRequest origin_isolation_request =
       OriginIsolationRequest::kNone;
 
-  // If |url| represents a resource inside another resource (e.g. a resource
-  // with a urn: URL in WebBundle), origin of the original resource. Otherwise,
-  // this is just the origin of |url|.
-  url::Origin origin;
+  // This allows overriding the origin of |url| for process assignment purposes
+  // in certain very special cases. Namely, if |url| represents a resource
+  // inside another resource (e.g. a resource with a urn: URL in WebBundle),
+  // this will be the origin of the original resource. If the navigation to
+  // |url| is performed via the loadDataWithBaseURL API (e.g., in a <webview>
+  // tag or on Android Webview), this will be the base origin provided via that
+  // API. Otherwise, this will be nullopt.
+  //
+  // TODO(alexmos): Currently, this is also used to hold the origin committed
+  // by the renderer at DidCommitNavigation() time, for use in commit-time URL
+  // and origin checks that require a UrlInfo.  Investigate whether there's a
+  // cleaner way to organize these checks.  See https://crbug.com/1320402.
+  absl::optional<url::Origin> origin;
 
   // If url is being loaded in a frame that is in a origin-restricted sandboxed,
   // then this flag will be true.
@@ -168,6 +177,8 @@
       absl::optional<WebExposedIsolationInfo> web_exposed_isolation_info);
   UrlInfoInit& WithIsPdf(bool is_pdf);
 
+  const absl::optional<url::Origin>& origin() { return origin_; }
+
  private:
   UrlInfoInit(UrlInfoInit&);
 
@@ -176,7 +187,7 @@
   GURL url_;
   UrlInfo::OriginIsolationRequest origin_isolation_request_ =
       UrlInfo::OriginIsolationRequest::kNone;
-  url::Origin origin_;
+  absl::optional<url::Origin> origin_;
   bool is_sandboxed_ = false;
   absl::optional<StoragePartitionConfig> storage_partition_config_;
   absl::optional<WebExposedIsolationInfo> web_exposed_isolation_info_;
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 4a41cd5..a678392 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -1326,6 +1326,10 @@
   return base::FeatureList::IsEnabled(features::kFirstPartySets);
 }
 
+bool ContentBrowserClient::WillProvidePublicFirstPartySets() {
+  return false;
+}
+
 base::Value::Dict ContentBrowserClient::GetFirstPartySetsOverrides() {
   return base::Value::Dict();
 }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 14e88bc..7e22f3e 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -2224,6 +2224,16 @@
   // should not change in a single browser session.
   virtual bool IsFirstPartySetsEnabled();
 
+  // Returns true iff the embedder will provide a list of First-Party Sets via
+  // content::FirstPartySetsHandler::SetPublicFirstPartySets during startup, at
+  // some point. If `IsFirstPartySetsEnabled()` returns false, this method will
+  // still be called, but its return value will be ignored.
+  //
+  // If this method returns false but `IsFirstPartySetsEnabled()` returns true
+  // (e.g. in tests), an empty list will be used instead of waiting for the
+  // embedder to call content::FirstPartySetsHandler::SetPublicFirstPartySets.
+  virtual bool WillProvidePublicFirstPartySets();
+
   // Returns a base::Value::Dict containing the value of the First-Party Sets
   // Overrides enterprise policy.
   // If the policy was not present or it was invalid, this returns an empty
diff --git a/content/public/browser/first_party_sets_handler.h b/content/public/browser/first_party_sets_handler.h
index 8bd6271..3ff5dea 100644
--- a/content/public/browser/first_party_sets_handler.h
+++ b/content/public/browser/first_party_sets_handler.h
@@ -72,7 +72,9 @@
   //
   // Embedder should call this method as early as possible during browser
   // startup if First-Party Sets are enabled, since no First-Party Sets queries
-  // are answered until initialization is complete.
+  // are answered until initialization is complete. Must not be called if
+  // `ContentBrowserClient::WillProvidePublicFirstPartySets` returns false or
+  // `ContentBrowserClient::IsFrstpartySetsEnabled` returns false.
   virtual void SetPublicFirstPartySets(base::File sets_file) = 0;
 
   // Resets the state on the instance for testing.
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index 19e28e3..fc33c59 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -589,8 +589,7 @@
       mojo::PendingReceiver<blink::mojom::PeriodicBackgroundSyncService>
           receiver) = 0;
   virtual void BindQuotaManagerHost(
-      int render_frame_id,
-      const url::Origin& origin,
+      const blink::StorageKey& storage_key,
       mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) = 0;
   virtual void CreateLockManager(
       const blink::StorageKey& storage_key,
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn
index ba0ddff..741c3b0 100644
--- a/content/public/test/android/BUILD.gn
+++ b/content/public/test/android/BUILD.gn
@@ -9,7 +9,6 @@
 android_library("android_test_message_pump_support_java") {
   testonly = true
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
diff --git a/content/public/test/browser_task_environment.h b/content/public/test/browser_task_environment.h
index ccced6512..4d14a6a 100644
--- a/content/public/test/browser_task_environment.h
+++ b/content/public/test/browser_task_environment.h
@@ -100,7 +100,7 @@
 //     template <typename... TaskEnvironmentTraits>
 //     explicit FooBase(TaskEnvironmentTraits&&... traits)
 //         : task_environment_(
-//               base::in_place,
+//               absl::in_place,
 //               std::forward<TaskEnvironmentTraits>(traits)...) {}
 //
 //     // Alternatively a subclass may pass this tag to ask this FooBase not to
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h
index b103681..ffcd438 100644
--- a/content/public/test/mock_render_process_host.h
+++ b/content/public/test/mock_render_process_host.h
@@ -218,8 +218,7 @@
       mojo::PendingReceiver<media::mojom::VideoDecodePerfHistory> receiver)
       override {}
   void BindQuotaManagerHost(
-      int render_frame_id,
-      const url::Origin& origin,
+      const blink::StorageKey& storage_key,
       mojo::PendingReceiver<blink::mojom::QuotaManagerHost> receiver) override {
   }
   void CreateLockManager(
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index dcde808..f21f3b5 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -195,7 +195,6 @@
       ":content_shell_apk_java",
       ":content_shell_assets",
       ":content_shell_java",
-      "//base:base_java",
       "//base:base_java_test_support",
       "//build/android:build_java",
       "//components/crash/android:java",
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc
index ff1c1753..a04b658 100644
--- a/content/shell/browser/shell_browser_main_parts.cc
+++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -183,8 +183,6 @@
   net::NetModule::SetResourceProvider(PlatformResourceProvider);
   ShellDevToolsManagerDelegate::StartHttpHandler(browser_context_.get());
   InitializeMessageLoopContext();
-  // The First-Party Sets feature always expects to be initialized
-  FirstPartySetsHandler::GetInstance()->SetPublicFirstPartySets(base::File());
   return 0;
 }
 
diff --git a/content/test/data/fenced_frames/opaque_ads.html b/content/test/data/fenced_frames/opaque_ads.html
index 1f365a7..baac518e 100644
--- a/content/test/data/fenced_frames/opaque_ads.html
+++ b/content/test/data/fenced_frames/opaque_ads.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html>
 <body>
-  <fencedframe mode=opaque-ads></fencedframe>
+  <fencedframe mode=opaque-ads src="title1.html"></fencedframe>
 </body>
 </html>
diff --git a/content/test/dwrite_font_fake_sender_win.cc b/content/test/dwrite_font_fake_sender_win.cc
index fde56d9..5085716 100644
--- a/content/test/dwrite_font_fake_sender_win.cc
+++ b/content/test/dwrite_font_fake_sender_win.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/strings/string_util.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace content {
 
@@ -101,7 +102,7 @@
   std::vector<blink::mojom::DWriteStringPairPtr> family_names;
   if (family_index < fonts_.size()) {
     for (const auto& name : fonts_[family_index].family_names_) {
-      family_names.emplace_back(base::in_place, name.first, name.second);
+      family_names.emplace_back(absl::in_place, name.first, name.second);
     }
   }
   std::move(callback).Run(std::move(family_names));
diff --git a/device/BUILD.gn b/device/BUILD.gn
index b837b97..87cd20c 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -457,7 +457,6 @@
       "$google_play_services_package:google_play_services_base_java",
       "$google_play_services_package:google_play_services_basement_java",
       "$google_play_services_package:google_play_services_location_java",
-      "//base:base_java",
       "//base:base_java_test_support",
       "//base:base_junit_test_support",
       "//build/android:build_java",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 2fc577b4..337047a67 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -20,7 +20,7 @@
       "/DELAYLOAD:setupapi.dll",
     ]
   }
-  if ((is_linux || is_chromeos) && is_chromecast) {
+  if ((is_linux || is_chromeos) && is_castos) {
     defines = [ "USE_CAST_BLUETOOTH_ADAPTER" ]
   }
 }
@@ -532,7 +532,7 @@
     # force_cast_bluetooth is used to compile with both cast & BlueZ, by
     # omitting the stubs that would otherwise be added in.
     if (!use_bluez || force_cast_bluetooth) {
-      if (is_chromecast && (is_linux || is_chromeos)) {
+      if (is_castos && (is_linux || is_chromeos)) {
         sources += [
           "cast/bluetooth_adapter_cast.cc",
           "cast/bluetooth_adapter_cast.h",
diff --git a/device/bluetooth/cast_bluetooth.gni b/device/bluetooth/cast_bluetooth.gni
index 30574c0..b65f8a0 100644
--- a/device/bluetooth/cast_bluetooth.gni
+++ b/device/bluetooth/cast_bluetooth.gni
@@ -2,5 +2,5 @@
 
 declare_args() {
   force_cast_bluetooth = false
-  use_bluez = (is_linux || is_chromeos) && !is_chromecast
+  use_bluez = (is_linux || is_chromeos) && !is_castos
 }
diff --git a/docs/security/faq.md b/docs/security/faq.md
index 522e1422..0e8fdbd 100644
--- a/docs/security/faq.md
+++ b/docs/security/faq.md
@@ -2,14 +2,21 @@
 
 [TOC]
 
+## Process
+
+<a name="TOC-Which-bugs-are-valid-for-rewards-under-the-Chrome-Vulnerability-Rewards-program-"></a>
+### Which bugs are valid for rewards under the Chrome Vulnerability Rewards program?
+
+Please see [the VRP FAQ page](vrp-faq.md).
+
 <a name="TOC-Why-are-security-bugs-hidden-in-the-Chromium-issue-tracker-"></a>
-## Why are security bugs hidden in the Chromium issue tracker?
+### Why are security bugs hidden in the Chromium issue tracker?
 
 We must balance a commitment to openness with a commitment to avoiding
 unnecessary risk for users of widely-used open source libraries.
 
 <a name="TOC-Can-you-please-un-hide-old-security-bugs-"></a>
-## Can you please un-hide old security bugs?
+### Can you please un-hide old security bugs?
 
 Our goal is to open security bugs to the public once the bug is fixed and the
 fix has been shipped to a majority of users. However, many vulnerabilities
@@ -24,7 +31,7 @@
 the vulnerability report (e.g. username and password pairs).
 
 <a name="TOC-Can-I-get-advance-notice-about-security-bugs-"></a>
-## Can I get advance notice about security bugs?
+### Can I get advance notice about security bugs?
 
 Vendors of products based on Chromium, distributors of operating systems that
 bundle Chromium, and individuals and organizations that significantly contribute
@@ -41,7 +48,7 @@
 strive to fix vulnerabilities quickly and release often.
 
 <a name="TOC-Can-I-see-these-security-bugs-so-that-I-can-back-port-the-fixes-to-my-downstream-project-"></a>
-## Can I see these security bugs so that I can back-port the fixes to my downstream project?
+### Can I see these security bugs so that I can back-port the fixes to my downstream project?
 
 Many developers of other projects use V8, Chromium, and sub-components of
 Chromium in their own projects. This is great! We are glad that Chromium and V8
@@ -59,25 +66,16 @@
 track the latest stable branches, and we support only the latest stable branch.
 
 <a name="TOC-Severity-Guidelines"></a>
-## How does the Chrome team determine severity of security bugs?
+### How does the Chrome team determine severity of security bugs?
 
 See the [severity guidelines](severity-guidelines.md) for more information.
 Only security issues are considered under the security vulnerability rewards
 program. Other types of bugs, which we call "functional bugs", are not.
 
-<a name="TOC-Are-privacy-issues-considered-security-bugs-"></a>
-## Are privacy issues considered security bugs?
-
-No. The Chrome Privacy team treats privacy issues, such as leaking information
-from Incognito, fingerprinting, and bugs related to deleting browsing data as
-functional bugs.
-
-Privacy issues are not considered under the security vulnerability rewards
-program; the [severity guidelines](severity-guidelines.md) outline the types of
-bugs that are considered security vulnerabilities in more detail.
+## Threat Model
 
 <a name="TOC-Timing-Attacks"></a>
-## Are timing attacks considered security vulnerabilities?
+### Are timing attacks considered security vulnerabilities?
 
 Some timing attacks are considered security vulnerabilities, and some are
 considered privacy vulnerabilities. Timing attacks vary significantly in terms
@@ -114,8 +112,150 @@
 applications are installed; the attack was mitigated by introducing randomness
 in the execution time of the affected API.
 
+<a name="TOC-What-if-a-Chrome-component-breaks-an-OS-security-boundary-"></a>
+### What if a Chrome component breaks an OS security boundary?
+
+If Chrome or any of its components (e.g. updater) can be abused to
+perform a local privilege escalation, then it may be treated as a
+valid security vulnerability.
+
+Running any Chrome component with higher privileges than intended is
+not a security bug and we do not recommend running Chrome as an
+Administrator on Windows, or as root on POSIX.
+
+<a name="TOC-Why-isn-t-passive-browser-fingerprinting-including-passive-cookies-in-Chrome-s-threat-model-"></a>
+<a name="TOC-What-is-Chrome-s-threat-model-for-fingerprinting-"></a>
+### What is Chrome's threat model for fingerprinting?
+
+> **Update, August 2019:** Please note that this answer has changed. We have
+> updated our threat model to include fingerprinting.
+
+Although [we do not consider fingerprinting issues to be *security
+vulnerabilities*](#TOC-Are-privacy-issues-considered-security-bugs-), we do now
+consider them to be privacy bugs that we will try to resolve. We distinguish two
+forms of fingerprinting.
+
+* **Passive fingerprinting** refers to fingerprinting techniques that do not
+require a JavaScript API call to achieve. This includes (but is not limited to)
+mechanisms like [ETag
+cookies](https://en.wikipedia.org/wiki/HTTP_ETag#Tracking_using_ETags) and [HSTS
+cookies](https://security.stackexchange.com/questions/79518/what-are-hsts-super-cookies).
+* **Active fingerprinting** refers to fingerprinting techniques that do require
+a JavaScript API call to achieve. Examples include most of the techniques in
+[EFF's Panopticlick proof of concept](https://panopticlick.eff.org).
+
+For passive fingerprinting, our ultimate goal is (to the extent possible) to
+reduce the information content available to below the threshold for usefulness.
+
+For active fingerprinting, our ultimate goal is to establish a [privacy
+budget](https://github.com/bslassey/privacy-budget) and to keep web origins
+below the budget (such as by rejecting some API calls when the origin exceeds
+its budget). To avoid breaking rich web applications that people want to use,
+Chrome may increase an origin's budget when it detects that a person is using
+the origin heavily. As with passive fingerprinting, our goal is to set the
+default budget below the threshold of usefulness for fingerprinting.
+
+These are both long-term goals. As of this writing (August 2019) we do not
+expect that Chrome will immediately achieve them.
+
+For background on fingerprinting and the difficulty of stopping it, see [Arvind
+Narayanan's site](https://33bits.wordpress.com/about/) and [Peter Eckersley's
+discussion of the information theory behind
+Panopticlick](https://www.eff.org/deeplinks/2010/01/primer-information-theory-and-privacy).
+There is also [a pretty good analysis of in-browser fingerprinting
+vectors](https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms).
+
+<a name="TOC-I-found-a-phishing-or-malware-site-not-blocked-by-Safe-Browsing.-Is-this-a-security-vulnerability-"></a>
+### I found a phishing or malware site not blocked by Safe Browsing. Is this a security vulnerability?
+
+Malicious sites not yet blocked by Safe Browsing can be reported via
+[https://www.google.com/safebrowsing/report_phish/](https://www.google.com/safebrowsing/report_phish/).
+Safe Browsing is primarily a blocklist of known-unsafe sites; the feature warns
+the user if they attempt to navigate to a site known to deliver phishing or
+malware content. You can learn more about this feature in these references:
+
+*    [https://developers.google.com/safe-browsing/](https://developers.google.com/safe-browsing/)
+*    [https://www.google.com/transparencyreport/safebrowsing/](https://www.google.com/transparencyreport/safebrowsing/)
+
+In general, it is not considered a security bug if a given malicious site is not
+blocked by the Safe Browsing feature, unless the site is on the blocklist but is
+allowed to load anyway. For instance, if a site found a way to navigate through
+the blocking red warning page without user interaction, that would be a security
+bug. A malicious site may exploit a security vulnerability (for instance,
+spoofing the URL in the **Location Bar**). This would be tracked as a security
+vulnerability in the relevant feature, not Safe Browsing itself.
+
+<a name="TOC-I-can-download-a-file-with-an-unsafe-extension-and-it-is-not-classified-as-dangerous-"></a>
+### I can download a file with an unsafe extension and it is not classified as dangerous - is this a security bug?
+
+Chrome tries to warn users before they open files that might modify their
+system. What counts as a dangerous file will vary depending on the operating
+system Chrome is running on, the default set of file handlers, Chrome settings,
+Enterprise policy and verdicts on both the site and the file from [Safe
+Browsing](https://code.google.com/apis/safebrowsing/). Because of this it will
+often be okay for a user to download and run a file. However, if you can clearly
+demonstrate how to bypass one of these protections then we’d like to hear about
+it. You can see if a Safe Browsing check happened by opening
+chrome://safe-browsing before starting the download.
+
+<a name="TOC-I-can-download-a-file-with-an-unsafe-extension-but-a-different-extension-or-file-type-is-shown-to-the-user-"></a>
+### I can download a file with an unsafe extension but a different extension or file type is shown to the user - is this a security bug?
+<a name="TOC-Extensions-for-downloaded-files-are-not-shown-in-a-file-dialog-"></a>
+### Extensions for downloaded files are not shown in a file dialog - is this a security bug?
+<a name="TOC-The-wrong-description-for-a-file-type-is-added-by-Chrome-"></a>
+### The wrong description for a file type is added by Chrome - is this a security bug?
+
+Chrome tries to let users know what they will be saving and downloading before
+they do so. Often operating systems will obscure a file’s type or extension and
+there is little we can do about that. Chrome shows information to help users
+make these decisions, both in Chrome-owned UI and in information that Chrome
+passes to OS-owned UI. If this information can be manipulated from a web site to
+mislead a user, then we’d like to hear about it.
+[Example](https://crbug.com/1137247).
+
+<a name="TOC-I-can-download-a-file-and-OS-indicators-for-its-provenance-are-not-applied-"></a>
+### I can download a file and OS indicators for its provenance are not applied - is this a security bug?
+
+Chrome attempts to label files downloaded from the internet with metadata using
+operating system APIs where these are available – for instance applying the Mark
+of the Web on Windows. This is often not possible (for instance on non-NTFS file
+systems on Windows, or for files inside downloaded archives) or disabled by
+policy. If a web site can cause Chrome to download a file without Chrome then
+adding this metadata as usual, we’d like to hear about it.
+
+<a name="TOC-I-can-cause-a-hard-or-soft-link-to-be-written-to-a-directory-bypassing-normal-OS-blocks-"></a>
+### I can cause a hard or soft link to be written to a directory bypassing normal OS blocks - is this a security bug?
+
+Chrome should not allow filesystem links to be created by initiating a download.
+[Example](https://crbug.com/1140417). [Example](https://crbug.com/1137247#c12).
+
+<a name="TOC-I-can-hijack-a-user-gesture-and-trick-a-user-into-accepting-a-permission-or-downloading-a-file-"></a>
+### I can hijack a user gesture and trick a user into accepting a permission or downloading a file - is this a security bug?
+
+Chrome tries to design its prompts to select safe defaults. If a prompt can
+accidentally be accepted without the user having an opportunity to make a
+decision about the prompt then we’d like to know. Examples might include poor
+defaults so that a user holding down an enter key might accept a dialog they
+would want to dismiss. [Example](https://crbug.com/854455#c11).
+
+Note that a user navigating to a download will cause a file to be
+[downloaded](https://crbug.com/1114592).
+
+## Areas outside Chrome's Threat Model
+
+<a name="TOC-Are-privacy-issues-considered-security-bugs-"></a>
+### Are privacy issues considered security bugs?
+
+No. The Chrome Privacy team treats privacy issues, such as leaking information
+from Incognito, fingerprinting, and bugs related to deleting browsing data as
+functional bugs.
+
+Privacy issues are not considered under the security vulnerability rewards
+program; the [severity guidelines](severity-guidelines.md) outline the types of
+bugs that are considered security vulnerabilities in more detail.
+
 <a name="TOC-What-are-the-security-and-privacy-guarantees-of-Incognito-mode-"></a>
-## What are the security and privacy guarantees of Incognito mode?
+### What are the security and privacy guarantees of Incognito mode?
 
 Bugs in Incognito mode are tracked as privacy bugs, not security bugs.
 
@@ -129,8 +269,15 @@
 state in non-volatile storage. However, Incognito windows will be able to access
 some previously-stored state, such as browsing history.
 
+<a name="TOC-Are-XSS-filter-bypasses-considered-security-bugs-"></a>
+### Are XSS filter bypasses considered security bugs?
+
+No. Chromium once contained a reflected XSS filter called the [XSSAuditor](https://www.chromium.org/developers/design-documents/xss-auditor)
+that was a best-effort second line of defense against reflected XSS flaws found
+in web sites. The XSS Auditor was [removed in Chrome 78](https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/TuYw-EZhO9g/blGViehIAwAJ).
+
 <a name="TOC-Are-denial-of-service-issues-considered-security-bugs-"></a>
-## Are denial of service issues considered security bugs?
+### Are denial of service issues considered security bugs?
 
 No. Denial of Service (DoS) issues are treated as **abuse** or **stability**
 issues rather than security vulnerabilities.
@@ -145,26 +292,8 @@
 the [severity guidelines](severity-guidelines.md) outline the types of bugs that
 are considered security vulnerabilities in more detail.
 
-<a name="TOC-Are-XSS-filter-bypasses-considered-security-bugs-"></a>
-## Are XSS filter bypasses considered security bugs?
-
-No. Chromium once contained a reflected XSS filter called the [XSSAuditor](https://www.chromium.org/developers/design-documents/xss-auditor)
-that was a best-effort second line of defense against reflected XSS flaws found
-in web sites. The XSS Auditor was [removed in Chrome 78](https://groups.google.com/a/chromium.org/forum/#!msg/blink-dev/TuYw-EZhO9g/blGViehIAwAJ).
-
-<a name="TOC-What-if-a-Chrome-component-breaks-an-OS-security-boundary-"></a>
-## What if a Chrome component breaks an OS security boundary?
-
-If Chrome or any of its components (e.g. updater) can be abused to
-perform a local privilege escalation, then it may be treated as a
-valid security vulnerability.
-
-Running any Chrome component with higher privileges than intended is
-not a security bug and we do not recommend running Chrome as an
-Administrator on Windows, or as root on POSIX.
-
 <a name="TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-"></a>
-## Why aren't physically-local attacks in Chrome's threat model?
+### Why aren't physically-local attacks in Chrome's threat model?
 
 People sometimes report that they can compromise Chrome by installing a
 malicious DLL in a place where Chrome will load it, by hooking APIs (e.g. [Issue
@@ -218,7 +347,7 @@
      already been compromised as described above.
 
 <a name="TOC-Why-aren-t-compromised-infected-machines-in-Chrome-s-threat-model-"></a>
-## Why aren't compromised/infected machines in Chrome's threat model?
+### Why aren't compromised/infected machines in Chrome's threat model?
 
 Although the attacker may now be remote, the consequences are essentially the
 same as with physically-local attacks. The attacker's code, when it runs as
@@ -229,27 +358,8 @@
 Other cases covered by this section include leaving a debugger port open to
 the world, remote shells, and so forth.
 
-<a name="TOC-What-about-unmasking-of-passwords-with-the-developer-tools-"></a>
-## What about unmasking of passwords with the developer tools?
-
-One of the most frequent reports we receive is password disclosure using the
-Inspect Element feature (see [Issue 126398](https://crbug.com/126398) for an
-example). People reason that "If I can see the password, it must be a bug."
-However, this is just one of the [physically-local attacks described in the
-previous
-section](#TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-),
-and all of those points apply here as well.
-
-The reason the password is masked is only to prevent disclosure via
-"shoulder-surfing" (i.e. the passive viewing of your screen by nearby persons),
-not because it is a secret unknown to the browser. The browser knows the
-password at many layers, including JavaScript, developer tools, process memory,
-and so on. When you are physically local to the computer, and only when you are
-physically local to the computer, there are, and always will be, tools for
-extracting the password from any of these places.
-
 <a name="TOC-Does-entering-JavaScript:-URLs-in-the-URL-bar-or-running-script-in-the-developer-tools-mean-there-s-an-XSS-vulnerability-"></a>
-## Does entering JavaScript: URLs in the URL bar or running script in the developer tools mean there's an XSS vulnerability?
+### Does entering JavaScript: URLs in the URL bar or running script in the developer tools mean there's an XSS vulnerability?
 
 [No](https://crbug.com/81697). Chrome does not attempt to prevent the user from
 knowingly running script against loaded documents, either by entering script in
@@ -261,76 +371,117 @@
 bar or the DevTools console.
 
 <a name="TOC-Does-executing-JavaScript-from-a-bookmark-mean-there-s-an-XSS-vulnerability-"></a>
-## Does executing JavaScript from a bookmark mean there's an XSS vulnerability?
+### Does executing JavaScript from a bookmark mean there's an XSS vulnerability?
 
 No. Chromium allows users to create bookmarks to JavaScript URLs that will run
 on the currently-loaded page when the user clicks the bookmark; these are called
 [bookmarklets](https://en.wikipedia.org/wiki/Bookmarklet).
 
 <a name="TOC-Does-executing-JavaScript-in-a-PDF-file-mean-there-s-an-XSS-vulnerability-"></a>
-## Does executing JavaScript in a PDF file mean there's an XSS vulnerability?
+### Does executing JavaScript in a PDF file mean there's an XSS vulnerability?
 
 No. PDF files have the ability to run JavaScript, usually to facilitate field
 validation during form fill-out. Note that the set of bindings provided to
 the PDF are more limited than those provided by the DOM to HTML documents (e.g.
 no document.cookie).
 
-<a name="TOC-Is-Chrome-s-support-for-userinfo-in-HTTP-URLs-e.g.-http:-user:password-example.com-considered-a-vulnerability-"></a>
-## Is Chrome's support for userinfo in HTTP URLs (e.g. http://user:password@example.com) considered a vulnerability?
+<a name="TOC-Are-PDF-files-static-content-in-Chromium-"></a>
+### Are PDF files static content in Chromium?
 
-[Not at this time](https://crbug.com/626951). Chrome supports HTTP and HTTPS
-URIs with username and password information embedded within them for
-compatibility with sites that require this feature. Notably, Chrome will
-suppress display of the username and password information after navigation in
-the URL box to limit the effectiveness of spoofing attacks that may try to
-mislead the user. For instance, navigating to
-`http://trustedsite.com@evil.example.com` will show an address of
-`http://evil.example.com` after the page loads.
+No. PDF files have some powerful capabilities including invoking printing or
+posting form data. To mitigate abuse of these capabiliies, such as beaconing
+upon document open, we require interaction with the document (a "user gesture")
+before allowing their use.
 
-<a name="TOC-Why-isn-t-passive-browser-fingerprinting-including-passive-cookies-in-Chrome-s-threat-model-"></a>
-<a name="TOC-What-is-Chrome-s-threat-model-for-fingerprinting-"></a>
-## What is Chrome's threat model for fingerprinting?
+<a name="TOC-What-about-URL-spoofs-using-Internationalized-Domain-Names-IDN-"></a>
+### What about URL spoofs using Internationalized Domain Names (IDN)?
 
-> **Update, August 2019:** Please note that this answer has changed. We have
-> updated our threat model to include fingerprinting.
+We try to balance the needs of our international userbase while protecting users
+against confusable homograph attacks. Despite this, there are a list of known
+IDN display issues we are still working on.
 
-Although [we do not consider fingerprinting issues to be *security
-vulnerabilities*](#TOC-Are-privacy-issues-considered-security-bugs-), we do now
-consider them to be privacy bugs that we will try to resolve. We distinguish two
-forms of fingerprinting.
+*    Please see [this document](https://docs.google.com/document/d/1_xJz3J9kkAPwk3pma6K3X12SyPTyyaJDSCxTfF8Y5sU)
+for a list of known issues and how we handle them.
+*    [This document](https://chromium.googlesource.com/chromium/src/+/main/docs/idn.md)
+describes Chrome's IDN policy in detail.
 
-* **Passive fingerprinting** refers to fingerprinting techniques that do not
-require a JavaScript API call to achieve. This includes (but is not limited to)
-mechanisms like [ETag
-cookies](https://en.wikipedia.org/wiki/HTTP_ETag#Tracking_using_ETags) and [HSTS
-cookies](https://security.stackexchange.com/questions/79518/what-are-hsts-super-cookies).
-* **Active fingerprinting** refers to fingerprinting techniques that do require
-a JavaScript API call to achieve. Examples include most of the techniques in
-[EFF's Panopticlick proof of concept](https://panopticlick.eff.org).
+<a name="TOC-Chrome-silently-syncs-extensions-across-devices.-Is-this-a-security-vulnerability-"></a>
+### Chrome silently syncs extensions across devices. Is this a security vulnerability?
 
-For passive fingerprinting, our ultimate goal is (to the extent possible) to
-reduce the information content available to below the threshold for usefulness.
+This topic has been moved to the [Extensions Security FAQ](https://chromium.googlesource.com/chromium/src/+/main/extensions/docs/security_faq.md).
 
-For active fingerprinting, our ultimate goal is to establish a [privacy
-budget](https://github.com/bslassey/privacy-budget) and to keep web origins
-below the budget (such as by rejecting some API calls when the origin exceeds
-its budget). To avoid breaking rich web applications that people want to use,
-Chrome may increase an origin's budget when it detects that a person is using
-the origin heavily. As with passive fingerprinting, our goal is to set the
-default budget below the threshold of usefulness for fingerprinting.
+<a name="TOC-Why-arent-null-pointer-dereferences-considered-security-bugs-"></a>
+### Why aren't null pointer dereferences considered security bugs?
 
-These are both long-term goals. As of this writing (August 2019) we do not
-expect that Chrome will immediately achieve them.
+Null pointer dereferences with consistent, small, fixed offsets are not considered
+security bugs. A read or write to the NULL page results in a non-exploitable crash.
+If the offset is larger than a page, or if there's uncertainty about whether the
+offset is controllable, it is considered a security bug.
 
-For background on fingerprinting and the difficulty of stopping it, see [Arvind
-Narayanan's site](https://33bits.wordpress.com/about/) and [Peter Eckersley's
-discussion of the information theory behind
-Panopticlick](https://www.eff.org/deeplinks/2010/01/primer-information-theory-and-privacy).
-There is also [a pretty good analysis of in-browser fingerprinting
-vectors](https://dev.chromium.org/Home/chromium-security/client-identification-mechanisms).
+<a name="TOC-Are-stack-overflows-considered-security-bugs-"></a>
+### Are stack overflows considered security bugs?
+
+No. Guard pages mean that stack overflows are considered unexploitable, and
+are regarded as [denial of service bugs](#TOC-Are-denial-of-service-issues-considered-security-bugs-).
+The only exception is if an attacker can jump over the guard pages allocated by
+the operating system and avoid accessing them, e.g.:
+
+*    A frame with a very large stack allocation.
+*    C variable length array with an attacker-controlled size.
+*    A call to `alloca()` with an attacker-controlled size.
+
+<a name="TOC-Are-enterprise-admins-considered-privileged-"></a>
+### Are enterprise admins considered privileged?
+
+Chrome [can't guard against local
+attacks](#TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-).
+Enterprise administrators often have full control over the device. Does Chrome
+assume that enterprise administrators are as privileged and powerful as other
+local users? It depends:
+
+* On a fully managed machine, for example a [domain-joined Windows
+  machine](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/join-a-computer-to-a-domain),
+  a device managed via a Mobile Device Management product, or a device with
+  Chrome managed via machine-level [Chrome Browser Cloud
+  Management](https://support.google.com/chrome/?p=cloud_management),
+  the administrator effectively has privileges to view and mutate any state on
+  the device. Chrome [policy implementations](../enterprise/add_new_policy.md)
+  should still guide enterprise admins to the most user-respectful defaults
+  and policy description text should clearly describe the nature of the
+  capabilities and the user impact of them being granted.
+* On an unmanaged machine, Chrome profiles [can be managed via cloud
+  policy](https://support.google.com/chrome/?p=manage_profiles)
+  if users sign into Chrome using a managed account. These policies are called
+  *user policies*. In this scenario, the Chrome enterprise administrator should
+  have privileges only to *view and mutate state within the profile that they
+  administer*. Any access outside that profile requires end-user consent.
+
+Chrome administrators can force-install Chrome extensions without permissions
+prompts, so the same restrictions must apply to the Chrome extension APIs.
+
+Chrome has a long history of policy support with many hundreds of policies. We
+recognize that there may exist policies or policy combinations that can provide
+capabilities outside of the guidance provided here. In cases of clear violation
+of user expectations, we will attempt to remedy these policies and we will apply
+the guidance laid out in this document to any newly added policies.
+
+<a name="TOC-Can-I-use-EMET-to-help-protect-Chrome-against-attack-on-Microsoft-Windows-"></a>
+### Can I use EMET to help protect Chrome against attack on Microsoft Windows?
+
+There are [known compatibility
+problems](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/chromium-and-emet)
+between Microsoft's EMET anti-exploit toolkit and some versions of Chrome. These
+can prevent Chrome from running in some configurations. Moreover, the Chrome
+security team does not recommend the use of EMET with Chrome because its most
+important security benefits are redundant with or superseded by built-in attack
+mitigations within the browser. For users, the very marginal security benefit is
+not usually a good trade-off for the compatibility issues and performance
+degradation the toolkit can cause.
+
+## Certificates & Connection Indicators
 
 <a name="TOC-Where-are-the-security-indicators-located-in-the-browser-window-"></a>
-## Where are the security indicators located in the browser window?
+### Where are the security indicators located in the browser window?
 
 The topmost portion of the browser window, consisting of the **Omnibox** (or
 **Location Bar**), navigation icons, menu icon, and other indicator icons, is
@@ -363,7 +514,7 @@
 imitated by the page itself since the page is confined to the viewport.
 
 <a name="TOC-Why-does-Chrome-show-a-green-lock-even-if-my-HTTPS-connection-is-being-proxied-"></a>
-## Why does Chrome show a green lock, even if my HTTPS connection is being proxied?
+### Why does Chrome show a green lock, even if my HTTPS connection is being proxied?
 
 Some types of software intercept HTTPS connections. Examples include anti-virus
 software, corporate network monitoring tools, and school censorship software. In
@@ -380,7 +531,7 @@
 Chrome's threat model?](#TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-).)
 
 <a name="TOC-Why-can-t-I-select-Proceed-Anyway-on-some-HTTPS-error-screens-"></a>
-## Why can’t I select Proceed Anyway on some HTTPS error screens?
+### Why can’t I select Proceed Anyway on some HTTPS error screens?
 
 A key guarantee of HTTPS is that Chrome can be relatively certain that it is
 connecting to the true web server and not an impostor. Some sites request an
@@ -400,7 +551,7 @@
 that the current server is not the true server.
 
 <a name="TOC-How-does-key-pinning-interact-with-local-proxies-and-filters-"></a>
-## How does key pinning interact with local proxies and filters?
+### How does key pinning interact with local proxies and filters?
 
 To enable certificate chain validation, Chrome has access to two stores of trust
 anchors (i.e. certificates that are empowered as issuers). One trust anchor
@@ -436,7 +587,7 @@
 connection will fail as it should.
 
 <a name="TOC-When-is-key-pinning-enabled-"></a>
-## When is key pinning enabled?
+### When is key pinning enabled?
 
 Key pinning is enabled for Chrome-branded, non-mobile builds when the local
 clock is within ten weeks of the embedded build timestamp. Key pinning is a
@@ -461,7 +612,7 @@
 pinning is active the load will _fail_ with a pinning error.
 
 <a name="TOC-How-does-certificate-transparency-interact-with-local-proxies-and-filters-"></a>
-## How does Certificate Transparency interact with local proxies and filters?
+### How does Certificate Transparency interact with local proxies and filters?
 
 Just as [pinning only applies to publicly-trusted trust
 anchors](#TOC-How-does-key-pinning-interact-with-local-proxies-and-filters-),
@@ -469,21 +620,8 @@
 anchors. Thus private trust anchors, such as for enterprise middle-boxes and AV
 proxies, do not need to be publicly logged in a CT log.
 
-<a name="TOC-Can-I-use-EMET-to-help-protect-Chrome-against-attack-on-Microsoft-Windows-"></a>
-## Can I use EMET to help protect Chrome against attack on Microsoft Windows?
-
-There are [known compatibility
-problems](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/chromium-and-emet)
-between Microsoft's EMET anti-exploit toolkit and some versions of Chrome. These
-can prevent Chrome from running in some configurations. Moreover, the Chrome
-security team does not recommend the use of EMET with Chrome because its most
-important security benefits are redundant with or superseded by built-in attack
-mitigations within the browser. For users, the very marginal security benefit is
-not usually a good trade-off for the compatibility issues and performance
-degradation the toolkit can cause.
-
 <a name="TOC-Why-are-some-web-platform-features-only-available-in-HTTPS-page-loads-"></a>
-## Why are some web platform features only available in HTTPS page-loads?
+### Why are some web platform features only available in HTTPS page-loads?
 
 The full answer is here: we [Prefer Secure Origins For Powerful New
 Features](https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features).
@@ -503,7 +641,7 @@
 could have modified the code, if it was not transported securely.)
 
 <a name="TOC-Which-origins-are-secure-"></a>
-## Which origins are "secure"?
+### Which origins are "secure"?
 
 Secure origins are those that match at least one of the following (scheme, host,
 port) patterns:
@@ -524,7 +662,7 @@
 for more details.
 
 <a name="TOC-What-s-the-story-with-certificate-revocation-"></a>
-## What's the story with certificate revocation?
+### What's the story with certificate revocation?
 
 Chrome's primary mechanism for checking the revocation status of HTTPS
 certificates is
@@ -561,8 +699,41 @@
 See also [Issue 361820](https://crbug.com/361820) for more discussion of the
 user-facing UX.
 
+## Passwords & Local Data
+
+<a name="TOC-What-about-unmasking-of-passwords-with-the-developer-tools-"></a>
+### What about unmasking of passwords with the developer tools?
+
+One of the most frequent reports we receive is password disclosure using the
+Inspect Element feature (see [Issue 126398](https://crbug.com/126398) for an
+example). People reason that "If I can see the password, it must be a bug."
+However, this is just one of the [physically-local attacks described in the
+previous
+section](#TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-),
+and all of those points apply here as well.
+
+The reason the password is masked is only to prevent disclosure via
+"shoulder-surfing" (i.e. the passive viewing of your screen by nearby persons),
+not because it is a secret unknown to the browser. The browser knows the
+password at many layers, including JavaScript, developer tools, process memory,
+and so on. When you are physically local to the computer, and only when you are
+physically local to the computer, there are, and always will be, tools for
+extracting the password from any of these places.
+
+<a name="TOC-Is-Chrome-s-support-for-userinfo-in-HTTP-URLs-e.g.-http:-user:password-example.com-considered-a-vulnerability-"></a>
+### Is Chrome's support for userinfo in HTTP URLs (e.g. http://user:password@example.com) considered a vulnerability?
+
+[Not at this time](https://crbug.com/626951). Chrome supports HTTP and HTTPS
+URIs with username and password information embedded within them for
+compatibility with sites that require this feature. Notably, Chrome will
+suppress display of the username and password information after navigation in
+the URL box to limit the effectiveness of spoofing attacks that may try to
+mislead the user. For instance, navigating to
+`http://trustedsite.com@evil.example.com` will show an address of
+`http://evil.example.com` after the page loads.
+
 <a name="TOC-Why-does-the-Password-Manager-ignore-autocomplete-off-for-password-fields-"></a>
-## Why does the Password Manager ignore `autocomplete='off'` for password fields?
+### Why does the Password Manager ignore `autocomplete='off'` for password fields?
 
 Ignoring `autocomplete='off'` for password fields allows the password manager to
 give more power to users to manage their credentials on websites. It is the
@@ -576,7 +747,7 @@
 announcement](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/zhhj7hCip5c).
 
 <a name="TOC-Signout-of-Chrome"></a>
-## Signing out of Chrome does not delete previously-synced data?
+### Signing out of Chrome does not delete previously-synced data?
 
 If you have signed into Chrome and subsequently sign out of Chrome, previously
 saved passwords and other data are not deleted from your device unless you
@@ -588,7 +759,7 @@
 on each previously-syncing device unless manually removed.
 
 <a name="TOC-Why-doesn-t-the-Password-Manager-save-my-Google-password-if-I-am-using-Chrome-Sync-"></a>
-## Why doesn't the Password Manager save my Google password if I am using Chrome Sync?
+### Why doesn't the Password Manager save my Google password if I am using Chrome Sync?
 
 In its default mode, Chrome Sync uses your Google password to protect all the
 other passwords in the Chrome Password Manager.
@@ -610,7 +781,7 @@
 than the one you are syncing with.
 
 <a name="TOC-Does-the-Password-Manager-store-my-passwords-encrypted-on-disk-"></a>
-## Does the Password Manager store my passwords encrypted on disk?
+### Does the Password Manager store my passwords encrypted on disk?
 
 Chrome generally tries to use the operating system's user storage mechanism
 wherever possible and stores them encrypted on disk, but it is platform
@@ -638,7 +809,7 @@
      [Issue 520437](https://crbug.com/520437) to follow this migration.
 
 <a name="TOC-If-theres-a-way-to-see-stored-passwords-without-entering-a-password--is-this-a-security-bug-"></a>
-## If there's a way to see stored passwords without entering a password, is this a security bug?
+### If there's a way to see stored passwords without entering a password, is this a security bug?
 
 No. If an attacker has control of your login on your device, they can get to
 your passwords by inspecting Chrome disk files or memory. (See
@@ -651,174 +822,15 @@
 they’re screen sharing. We don’t do this on all platforms because we consider
 such risks greater on some than on others.
 
-<a name="TOC-I-found-a-phishing-or-malware-site-not-blocked-by-Safe-Browsing.-Is-this-a-security-vulnerability-"></a>
-## I found a phishing or malware site not blocked by Safe Browsing. Is this a security vulnerability?
-
-Malicious sites not yet blocked by Safe Browsing can be reported via
-[https://www.google.com/safebrowsing/report_phish/](https://www.google.com/safebrowsing/report_phish/).
-Safe Browsing is primarily a blocklist of known-unsafe sites; the feature warns
-the user if they attempt to navigate to a site known to deliver phishing or
-malware content. You can learn more about this feature in these references:
-
-*    [https://developers.google.com/safe-browsing/](https://developers.google.com/safe-browsing/)
-*    [https://www.google.com/transparencyreport/safebrowsing/](https://www.google.com/transparencyreport/safebrowsing/)
-
-In general, it is not considered a security bug if a given malicious site is not
-blocked by the Safe Browsing feature, unless the site is on the blocklist but is
-allowed to load anyway. For instance, if a site found a way to navigate through
-the blocking red warning page without user interaction, that would be a security
-bug. A malicious site may exploit a security vulnerability (for instance,
-spoofing the URL in the **Location Bar**). This would be tracked as a security
-vulnerability in the relevant feature, not Safe Browsing itself.
-
-<a name="TOC-I-can-download-a-file-with-an-unsafe-extension-and-it-is-not-classified-as-dangerous-"></a>
-## I can download a file with an unsafe extension and it is not classified as dangerous - is this a security bug?
-
-Chrome tries to warn users before they open files that might modify their
-system. What counts as a dangerous file will vary depending on the operating
-system Chrome is running on, the default set of file handlers, Chrome settings,
-Enterprise policy and verdicts on both the site and the file from [Safe
-Browsing](https://code.google.com/apis/safebrowsing/). Because of this it will
-often be okay for a user to download and run a file. However, if you can clearly
-demonstrate how to bypass one of these protections then we’d like to hear about
-it. You can see if a Safe Browsing check happened by opening
-chrome://safe-browsing before starting the download.
-
-<a name="TOC-I-can-download-a-file-with-an-unsafe-extension-but-a-different-extension-or-file-type-is-shown-to-the-user-"></a>
-## I can download a file with an unsafe extension but a different extension or file type is shown to the user - is this a security bug?
-<a name="TOC-Extensions-for-downloaded-files-are-not-shown-in-a-file-dialog-"></a>
-## Extensions for downloaded files are not shown in a file dialog - is this a security bug?
-<a name="TOC-The-wrong-description-for-a-file-type-is-added-by-Chrome-"></a>
-## The wrong description for a file type is added by Chrome - is this a security bug?
-
-Chrome tries to let users know what they will be saving and downloading before
-they do so. Often operating systems will obscure a file’s type or extension and
-there is little we can do about that. Chrome shows information to help users
-make these decisions, both in Chrome-owned UI and in information that Chrome
-passes to OS-owned UI. If this information can be manipulated from a web site to
-mislead a user, then we’d like to hear about it.
-[Example](https://crbug.com/1137247).
-
-<a name="TOC-I-can-download-a-file-and-OS-indicators-for-its-provenance-are-not-applied-"></a>
-## I can download a file and OS indicators for its provenance are not applied - is this a security bug?
-
-Chrome attempts to label files downloaded from the internet with metadata using
-operating system APIs where these are available – for instance applying the Mark
-of the Web on Windows. This is often not possible (for instance on non-NTFS file
-systems on Windows, or for files inside downloaded archives) or disabled by
-policy. If a web site can cause Chrome to download a file without Chrome then
-adding this metadata as usual, we’d like to hear about it.
-
-<a name="TOC-I-can-cause-a-hard-or-soft-link-to-be-written-to-a-directory-bypassing-normal-OS-blocks-"></a>
-## I can cause a hard or soft link to be written to a directory bypassing normal OS blocks - is this a security bug?
-
-Chrome should not allow filesystem links to be created by initiating a download.
-[Example](https://crbug.com/1140417). [Example](https://crbug.com/1137247#c12).
-
-<a name="TOC-I-can-hijack-a-user-gesture-and-trick-a-user-into-accepting-a-permission-or-downloading-a-file-"></a>
-## I can hijack a user gesture and trick a user into accepting a permission or downloading a file - is this a security bug?
-
-Chrome tries to design its prompts to select safe defaults. If a prompt can
-accidentally be accepted without the user having an opportunity to make a
-decision about the prompt then we’d like to know. Examples might include poor
-defaults so that a user holding down an enter key might accept a dialog they
-would want to dismiss. [Example](https://crbug.com/854455#c11).
-
-Note that a user navigating to a download will cause a file to be
-[downloaded](https://crbug.com/1114592).
+## Other
 
 <a name="TOC-What-is-the-security-story-for-Service-Workers-"></a>
-## What is the security story for Service Workers?
+### What is the security story for Service Workers?
 
 See our dedicated [Service Worker Security
 FAQ](https://chromium.googlesource.com/chromium/src/+/main/docs/security/service-worker-security-faq.md).
 
 <a name="TOC-What-is-the-security-story-for-Extensions-"></a>
-## What is the security story for Extensions?
+### What is the security story for Extensions?
 
 See our dedicated [Extensions Security FAQ](https://chromium.googlesource.com/chromium/src/+/main/extensions/docs/security_faq.md).
-
-<a name="TOC-What-about-URL-spoofs-using-Internationalized-Domain-Names-IDN-"></a>
-## What about URL spoofs using Internationalized Domain Names (IDN)?
-
-We try to balance the needs of our international userbase while protecting users
-against confusable homograph attacks. Despite this, there are a list of known
-IDN display issues we are still working on.
-
-*    Please see [this document](https://docs.google.com/document/d/1_xJz3J9kkAPwk3pma6K3X12SyPTyyaJDSCxTfF8Y5sU)
-for a list of known issues and how we handle them.
-*    [This document](https://chromium.googlesource.com/chromium/src/+/main/docs/idn.md)
-describes Chrome's IDN policy in detail.
-
-<a name="TOC-Chrome-silently-syncs-extensions-across-devices.-Is-this-a-security-vulnerability-"></a>
-## Chrome silently syncs extensions across devices. Is this a security vulnerability?
-
-This topic has been moved to the [Extensions Security FAQ](https://chromium.googlesource.com/chromium/src/+/main/extensions/docs/security_faq.md).
-
-<a name="TOC-Are-PDF-files-static-content-in-Chromium-"></a>
-## Are PDF files static content in Chromium?
-
-No. PDF files have some powerful capabilities including invoking printing or
-posting form data. To mitigate abuse of these capabiliies, such as beaconing
-upon document open, we require interaction with the document (a "user gesture")
-before allowing their use.
-
-<a name="TOC-Why-arent-null-pointer-dereferences-considered-security-bugs-"></a>
-## Why aren't null pointer dereferences considered security bugs?
-
-Null pointer dereferences with consistent, small, fixed offsets are not considered
-security bugs. A read or write to the NULL page results in a non-exploitable crash.
-If the offset is larger than a page, or if there's uncertainty about whether the
-offset is controllable, it is considered a security bug.
-
-<a name="TOC-Are-stack-overflows-considered-security-bugs-"></a>
-## Are stack overflows considered security bugs?
-
-No. Guard pages mean that stack overflows are considered unexploitable, and
-are regarded as [denial of service bugs](#TOC-Are-denial-of-service-issues-considered-security-bugs-).
-The only exception is if an attacker can jump over the guard pages allocated by
-the operating system and avoid accessing them, e.g.:
-
-*    A frame with a very large stack allocation.
-*    C variable length array with an attacker-controlled size.
-*    A call to `alloca()` with an attacker-controlled size.
-
-<a name="TOC-Are-enterprise-admins-considered-privileged-"></a>
-## Are enterprise admins considered privileged?
-
-Chrome [can't guard against local
-attacks](#TOC-Why-aren-t-physically-local-attacks-in-Chrome-s-threat-model-).
-Enterprise administrators often have full control over the device. Does Chrome
-assume that enterprise administrators are as privileged and powerful as other
-local users? It depends:
-
-* On a fully managed machine, for example a [domain-joined Windows
-  machine](https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/join-a-computer-to-a-domain),
-  a device managed via a Mobile Device Management product, or a device with
-  Chrome managed via machine-level [Chrome Browser Cloud
-  Management](https://support.google.com/chrome/?p=cloud_management),
-  the administrator effectively has privileges to view and mutate any state on
-  the device. Chrome [policy implementations](../enterprise/add_new_policy.md)
-  should still guide enterprise admins to the most user-respectful defaults
-  and policy description text should clearly describe the nature of the
-  capabilities and the user impact of them being granted.
-* On an unmanaged machine, Chrome profiles [can be managed via cloud
-  policy](https://support.google.com/chrome/?p=manage_profiles)
-  if users sign into Chrome using a managed account. These policies are called
-  *user policies*. In this scenario, the Chrome enterprise administrator should
-  have privileges only to *view and mutate state within the profile that they
-  administer*. Any access outside that profile requires end-user consent.
-
-Chrome administrators can force-install Chrome extensions without permissions
-prompts, so the same restrictions must apply to the Chrome extension APIs.
-
-Chrome has a long history of policy support with many hundreds of policies. We
-recognize that there may exist policies or policy combinations that can provide
-capabilities outside of the guidance provided here. In cases of clear violation
-of user expectations, we will attempt to remedy these policies and we will apply
-the guidance laid out in this document to any newly added policies.
-
-<a name="TOC-Which-bugs-are-valid-for-rewards-under-the-Chrome-Vulnerability-Rewards-program-"></a>
-## Which bugs are valid for rewards under the Chrome Vulnerability Rewards program?
-
-Please see [the VRP FAQ page](vrp-faq.md).
diff --git a/docs/updater/functional_spec.md b/docs/updater/functional_spec.md
index 63ae153..f59c233 100644
--- a/docs/updater/functional_spec.md
+++ b/docs/updater/functional_spec.md
@@ -230,6 +230,15 @@
 
 Refer to chrome/updater/protos/omaha\_settings.proto for more details.
 
+#### UI
+TODO(crbug.com/1035895): Document UI.
+
+##### Help Button
+If the installation fails, the updater shows an error message with a "Help"
+button. Clicking the help button opens a web page in the user's default browser.
+The page is opened with a query string:
+`?product={AppId}&errorcode={ErrorCode}`.
+
 #### Dynamic Install Parameters
 
 ##### `needsadmin`
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc
index 45a25a3..97b155a 100644
--- a/extensions/browser/content_verifier.cc
+++ b/extensions/browser/content_verifier.cc
@@ -139,17 +139,6 @@
       std::move(image_paths), std::move(background_or_content_paths),
       std::move(indexed_ruleset_paths), extension->version(), source_type);
 }
-
-// Returns all locales.
-std::set<std::string> GetAllLocaleCandidates() {
-  std::set<std::string> all_locales;
-  // TODO(asargent) - see if we can cache this list longer to avoid
-  // having to fetch it more than once for a given run of the
-  // browser. Maybe it can never change at runtime? (Or if it can, maybe
-  // there is an event we can listen for to know to drop our cache).
-  extension_l10n_util::GetAllLocales(&all_locales);
-  return all_locales;
-}
 }  // namespace
 
 struct ContentVerifier::CacheKey {
@@ -725,7 +714,7 @@
   const std::set<CanonicalRelativePath>& indexed_ruleset_paths =
       *(data->canonical_indexed_ruleset_paths);
 
-  absl::optional<std::set<std::string>> all_locale_candidates;
+  std::set<std::string> all_locale_candidates;
 
   const CanonicalRelativePath manifest_file =
       content_verifier_utils::CanonicalizeRelativePath(
@@ -762,8 +751,14 @@
 
     const base::FilePath canonical_path(canonical_path_value.value());
     if (locales_relative_dir.IsParent(canonical_path)) {
-      if (!all_locale_candidates)
-        all_locale_candidates = GetAllLocaleCandidates();
+      // TODO(asargent) - see if we can cache this list longer to avoid
+      // having to fetch it more than once for a given run of the
+      // browser. Maybe it can never change at runtime? (Or if it can, maybe
+      // there is an event we can listen for to know to drop our cache).
+      if (all_locale_candidates.empty()) {
+        extension_l10n_util::GetAllLocales(&all_locale_candidates);
+        DCHECK(!all_locale_candidates.empty());
+      }
 
       // Since message catalogs get transcoded during installation, we want
       // to skip those paths. See if this path looks like
@@ -771,7 +766,7 @@
       if (canonical_path.BaseName() == messages_file &&
           canonical_path.DirName().DirName() == locales_relative_dir &&
           ContainsStringIgnoreCaseASCII(
-              *all_locale_candidates,
+              all_locale_candidates,
               canonical_path.DirName().BaseName().MaybeAsASCII())) {
         continue;
       }
diff --git a/infra/config/generated/builders/ci/Fuchsia ARM64/properties.json b/infra/config/generated/builders/ci/Fuchsia ARM64/properties.json
index 21fcce96..e6eb4e06 100644
--- a/infra/config/generated/builders/ci/Fuchsia ARM64/properties.json
+++ b/infra/config/generated/builders/ci/Fuchsia ARM64/properties.json
@@ -1,4 +1,53 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Fuchsia ARM64",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_arm64",
+                  "fuchsia_arm64_host"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "Fuchsia ARM64",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "fuchsia_arm64",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "jobs": 500,
diff --git a/infra/config/generated/builders/ci/Fuchsia x64/properties.json b/infra/config/generated/builders/ci/Fuchsia x64/properties.json
index 21fcce96..3e0b193 100644
--- a/infra/config/generated/builders/ci/Fuchsia x64/properties.json
+++ b/infra/config/generated/builders/ci/Fuchsia x64/properties.json
@@ -1,4 +1,52 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Fuchsia x64",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "Fuchsia x64",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "fuchsia_x64",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "jobs": 500,
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
index b47a8e3..0867f66 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
@@ -51,11 +51,10 @@
       ]
     }
   },
-  "$build/goma": {
-    "enable_ats": true,
-    "rpc_extra_params": "?prod",
-    "server_host": "goma.chromium.org",
-    "use_luci_auth": true
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 500,
+    "metrics_project": "chromium-reclient-metrics"
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git a/infra/config/generated/builders/ci/fuchsia-arm64-cast/properties.json b/infra/config/generated/builders/ci/fuchsia-arm64-cast/properties.json
index 21fcce96..1465811 100644
--- a/infra/config/generated/builders/ci/fuchsia-arm64-cast/properties.json
+++ b/infra/config/generated/builders/ci/fuchsia-arm64-cast/properties.json
@@ -1,4 +1,52 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-arm64-cast",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_arm64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-arm64-cast",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "fuchsia-arm64-cast",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "jobs": 500,
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-cast/properties.json b/infra/config/generated/builders/ci/fuchsia-x64-cast/properties.json
index 21fcce96..8ca93d0e 100644
--- a/infra/config/generated/builders/ci/fuchsia-x64-cast/properties.json
+++ b/infra/config/generated/builders/ci/fuchsia-x64-cast/properties.json
@@ -1,4 +1,52 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-x64-cast",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-x64-cast",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "fuchsia-x64-cast",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "jobs": 500,
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-dbg/properties.json b/infra/config/generated/builders/ci/fuchsia-x64-dbg/properties.json
index e859202..3ceef15 100644
--- a/infra/config/generated/builders/ci/fuchsia-x64-dbg/properties.json
+++ b/infra/config/generated/builders/ci/fuchsia-x64-dbg/properties.json
@@ -1,4 +1,53 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-x64-dbg",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Debug",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-x64-dbg",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "fuchsia-compile-x64-dbg",
+          "group": "tryserver.chromium.linux"
+        }
+      ]
+    }
+  },
   "$build/reclient": {
     "instance": "rbe-chromium-trusted",
     "jobs": 500,
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
index a2dcb4f..5cd437b 100644
--- a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
+++ b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
@@ -1,4 +1,61 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "linux-chromeos-inverse-fieldtrials-fyi-rel",
+          "group": "tryserver.chromium.chromiumos"
+        },
+        {
+          "builder": "linux-chromeos-rel",
+          "group": "tryserver.chromium.chromiumos"
+        },
+        {
+          "builder": "linux-chromeos-rel-rts",
+          "group": "tryserver.chromium.chromiumos"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/ci/win7-updater-tester-dbg/properties.json b/infra/config/generated/builders/ci/win7-updater-tester-dbg/properties.json
deleted file mode 100644
index 0d6f98c..0000000
--- a/infra/config/generated/builders/ci/win7-updater-tester-dbg/properties.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.updater",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/fuchsia-arm64-cast/properties.json b/infra/config/generated/builders/try/fuchsia-arm64-cast/properties.json
index 19e0479..9317a13 100644
--- a/infra/config/generated/builders/try/fuchsia-arm64-cast/properties.json
+++ b/infra/config/generated/builders/try/fuchsia-arm64-cast/properties.json
@@ -1,4 +1,46 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-arm64-cast",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_arm64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-arm64-cast",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/fuchsia-compile-x64-dbg/properties.json b/infra/config/generated/builders/try/fuchsia-compile-x64-dbg/properties.json
index 19e0479..2090f306 100644
--- a/infra/config/generated/builders/try/fuchsia-compile-x64-dbg/properties.json
+++ b/infra/config/generated/builders/try/fuchsia-compile-x64-dbg/properties.json
@@ -1,4 +1,48 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-x64-dbg",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Debug",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64",
+                  "enable_reclient"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-x64-dbg",
+          "project": "chromium"
+        }
+      ],
+      "is_compile_only": true
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast/properties.json b/infra/config/generated/builders/try/fuchsia-x64-cast/properties.json
index 19e0479..be58a79c 100644
--- a/infra/config/generated/builders/try/fuchsia-x64-cast/properties.json
+++ b/infra/config/generated/builders/try/fuchsia-x64-cast/properties.json
@@ -1,4 +1,46 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "fuchsia-x64-cast",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "fuchsia-x64-cast",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/fuchsia_arm64/properties.json b/infra/config/generated/builders/try/fuchsia_arm64/properties.json
index 19e0479..39eaa1c8 100644
--- a/infra/config/generated/builders/try/fuchsia_arm64/properties.json
+++ b/infra/config/generated/builders/try/fuchsia_arm64/properties.json
@@ -1,4 +1,47 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Fuchsia ARM64",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_arm64",
+                  "fuchsia_arm64_host"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "Fuchsia ARM64",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/fuchsia_x64/properties.json b/infra/config/generated/builders/try/fuchsia_x64/properties.json
index 19e0479..958c2961 100644
--- a/infra/config/generated/builders/try/fuchsia_x64/properties.json
+++ b/infra/config/generated/builders/try/fuchsia_x64/properties.json
@@ -1,4 +1,46 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "Fuchsia x64",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-linux-archive",
+              "builder_group": "chromium.linux",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_bits": 64,
+                "target_platform": "fuchsia"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "fuchsia_x64"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "Fuchsia x64",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/linux-chromeos-inverse-fieldtrials-fyi-rel/properties.json b/infra/config/generated/builders/try/linux-chromeos-inverse-fieldtrials-fyi-rel/properties.json
index 4aada5e..a2117b8 100644
--- a/infra/config/generated/builders/try/linux-chromeos-inverse-fieldtrials-fyi-rel/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-inverse-fieldtrials-fyi-rel/properties.json
@@ -1,4 +1,47 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/goma": {
     "enable_ats": true,
     "rpc_extra_params": "?prod",
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
index 220d491..d5eb125 100644
--- a/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
@@ -1,4 +1,47 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/code_coverage": {
     "coverage_test_types": [
       "unit",
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json
index 95ed5c5..3a84399 100644
--- a/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-rel-rts/properties.json
@@ -1,4 +1,50 @@
 {
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ],
+      "rts_config": {
+        "condition": "ALWAYS"
+      }
+    }
+  },
   "$build/code_coverage": {
     "coverage_test_types": [
       "unit",
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
index 5684a091..9aa2b40 100644
--- a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
@@ -3,6 +3,49 @@
     "compilator": "linux-chromeos-rel-compilator",
     "compilator_watcher_git_revision": "7809a690bbd935bcb3b4d922e24cabe168aaabc8"
   },
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "linux-chromeos-rel",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "build_gs_bucket": "chromium-chromiumos-archive",
+              "builder_group": "chromium.chromiumos",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "intel",
+                "target_bits": 64
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "use_clang_coverage",
+                  "chromeos"
+                ],
+                "config": "chromium"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "linux-chromeos-rel",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
   "$build/code_coverage": {
     "coverage_test_types": [
       "unit",
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index f8bdd3d..ad00147 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -43375,85 +43375,6 @@
       }
     }
     builders {
-      name: "win7-updater-tester-dbg"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:8"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-18.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:0"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/win7-updater-tester-dbg/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.updater",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      execution_timeout_secs: 10800
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://[^/]*blink_web_tests/.+"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-    }
-    builders {
       name: "win7-updater-tester-dbg-uac"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -68141,7 +68062,7 @@
       }
       experiments {
         key: "remove_src_checkout_experiment"
-        value: 50
+        value: 100
       }
       resultdb {
         enable: true
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index e93489e4..690a927 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -12001,11 +12001,6 @@
     short_name: "10"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/win7-updater-tester-dbg"
-    category: "debug|win (64)"
-    short_name: "7"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/win10-updater-tester-dbg-uac"
     category: "debug|win (64)"
     short_name: "UAC10"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 058f318..6147ade 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -7090,20 +7090,6 @@
   }
 }
 job {
-  id: "win7-updater-tester-dbg"
-  realm: "ci"
-  acls {
-    role: TRIGGERER
-    granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-  }
-  acl_sets: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "win7-updater-tester-dbg"
-  }
-}
-job {
   id: "win7-updater-tester-dbg-uac"
   realm: "ci"
   acls {
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index ffd13d2..cf76660 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -175,7 +175,6 @@
         values: "win10-updater-tester-rel"
         values: "win7(32)-updater-tester-dbg"
         values: "win7(32)-updater-tester-rel"
-        values: "win7-updater-tester-dbg"
         values: "win7-updater-tester-dbg-uac"
         values: "win7-updater-tester-rel"
       }
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
index 5fbf6173..801c3d9 100644
--- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -210,6 +210,9 @@
         short_name = "cfi",
     ),
     main_console_view = "main",
+    goma_backend = None,
+    reclient_jobs = rbe_jobs.HIGH_JOBS_FOR_CI,
+    reclient_instance = rbe_instance.DEFAULT,
 )
 
 ci.builder(
@@ -595,6 +598,25 @@
 ci.builder(
     name = "linux-chromeos-rel",
     branch_selector = branches.CROS_LTS_MILESTONE,
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "use_clang_coverage",
+                "chromeos",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_arch = builder_config.target_arch.INTEL,
+            target_bits = 64,
+        ),
+        build_gs_bucket = "chromium-chromiumos-archive",
+    ),
     console_view_entry = consoles.console_view_entry(
         category = "default",
         short_name = "rel",
diff --git a/infra/config/subprojects/chromium/ci/chromium.linux.star b/infra/config/subprojects/chromium/ci/chromium.linux.star
index c9eeba9a..c3fb3a9 100644
--- a/infra/config/subprojects/chromium/ci/chromium.linux.star
+++ b/infra/config/subprojects/chromium/ci/chromium.linux.star
@@ -146,6 +146,25 @@
     ],
     cq_mirrors_console_view = "mirrors",
     notifies = ["cr-fuchsia"],
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "fuchsia_arm64",
+                "fuchsia_arm64_host",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.FUCHSIA,
+        ),
+        build_gs_bucket = "chromium-linux-archive",
+    ),
     goma_backend = goma.backend.RBE_PROD,
     goma_jobs = goma.jobs.MANY_JOBS_FOR_CI,
     reclient_instance = None,
@@ -168,6 +187,24 @@
     ],
     cq_mirrors_console_view = "mirrors",
     notifies = ["cr-fuchsia"],
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "fuchsia_x64",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.FUCHSIA,
+        ),
+        build_gs_bucket = "chromium-linux-archive",
+    ),
     goma_backend = goma.backend.RBE_PROD,
     goma_jobs = goma.jobs.MANY_JOBS_FOR_CI,
     reclient_instance = None,
@@ -347,6 +384,24 @@
     # failure.
     tree_closing = False,
     notifies = ["cr-fuchsia", "close-on-any-step-failure"],
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "fuchsia_arm64",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.FUCHSIA,
+        ),
+        build_gs_bucket = "chromium-linux-archive",
+    ),
     goma_backend = goma.backend.RBE_PROD,
     goma_jobs = goma.jobs.MANY_JOBS_FOR_CI,
     reclient_instance = None,
@@ -382,6 +437,24 @@
     # failure.
     tree_closing = False,
     notifies = ["cr-fuchsia", "close-on-any-step-failure"],
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "fuchsia_x64",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.FUCHSIA,
+        ),
+        build_gs_bucket = "chromium-linux-archive",
+    ),
     goma_backend = goma.backend.RBE_PROD,
     goma_jobs = goma.jobs.MANY_JOBS_FOR_CI,
     reclient_instance = None,
@@ -402,6 +475,25 @@
         ),
     ],
     notifies = ["cr-fuchsia"],
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "fuchsia_x64",
+                "enable_reclient",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.DEBUG,
+            target_bits = 64,
+            target_platform = builder_config.target_platform.FUCHSIA,
+        ),
+        build_gs_bucket = "chromium-linux-archive",
+    ),
 )
 
 ci.builder(
diff --git a/infra/config/subprojects/chromium/ci/chromium.updater.star b/infra/config/subprojects/chromium/ci/chromium.updater.star
index c2ae347..522bf9b7 100644
--- a/infra/config/subprojects/chromium/ci/chromium.updater.star
+++ b/infra/config/subprojects/chromium/ci/chromium.updater.star
@@ -238,15 +238,6 @@
 )
 
 ci.thin_tester(
-    name = "win7-updater-tester-dbg",
-    console_view_entry = consoles.console_view_entry(
-        category = "debug|win (64)",
-        short_name = "7",
-    ),
-    triggered_by = ["win-updater-builder-dbg"],
-)
-
-ci.thin_tester(
     name = "win7-updater-tester-dbg-uac",
     console_view_entry = consoles.console_view_entry(
         category = "debug|win (64)",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index 106bfd8..f678b22a 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -146,10 +146,14 @@
 
 try_.builder(
     name = "linux-chromeos-inverse-fieldtrials-fyi-rel",
+    mirrors = builder_config.copy_from("try/linux-chromeos-rel"),
 )
 
 try_.orchestrator_builder(
     name = "linux-chromeos-rel",
+    mirrors = [
+        "ci/linux-chromeos-rel",
+    ],
     compilator = "linux-chromeos-rel-compilator",
     branch_selector = branches.CROS_LTS_MILESTONE,
     main_list_view = "try",
@@ -243,6 +247,14 @@
 
 try_.builder(
     name = "linux-chromeos-rel-rts",
+    mirrors = [
+        "ci/linux-chromeos-rel",
+    ],
+    try_settings = builder_config.try_settings(
+        rts_config = builder_config.rts_config(
+            condition = builder_config.rts_condition.ALWAYS,
+        ),
+    ),
     builderless = False,
     use_clang_coverage = True,
     coverage_test_types = ["unit", "overall"],
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index bec0b74..1300c82d 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -102,6 +102,9 @@
             ".+/[+]/chromecast/.+",
         ],
     ),
+    mirrors = [
+        "ci/fuchsia-arm64-cast",
+    ],
 )
 
 try_.builder(
@@ -113,6 +116,13 @@
             ".+/[+]/media/fuchsia/.+",
         ],
     ),
+    mirrors = [
+        "ci/fuchsia-x64-dbg",
+    ],
+    try_settings = builder_config.try_settings(
+        include_all_triggered_testers = True,
+        is_compile_only = True,
+    ),
 )
 
 try_.builder(
@@ -134,6 +144,9 @@
     builderless = not settings.is_main,
     main_list_view = "try",
     tryjob = try_.job(),
+    mirrors = [
+        "ci/fuchsia-x64-cast",
+    ],
 )
 
 try_.builder(
@@ -142,6 +155,9 @@
     builderless = not settings.is_main,
     main_list_view = "try",
     tryjob = try_.job(),
+    mirrors = [
+        "ci/Fuchsia ARM64",
+    ],
 )
 
 try_.builder(
@@ -150,6 +166,9 @@
     builderless = not settings.is_main,
     main_list_view = "try",
     tryjob = try_.job(),
+    mirrors = [
+        "ci/Fuchsia x64",
+    ],
 )
 
 try_.builder(
@@ -330,7 +349,7 @@
     coverage_test_types = ["unit", "overall"],
     tryjob = try_.job(),
     experiments = {
-        "remove_src_checkout_experiment": 50,
+        "remove_src_checkout_experiment": 100,
     },
 )
 
diff --git a/ios/chrome/browser/discover_feed/BUILD.gn b/ios/chrome/browser/discover_feed/BUILD.gn
index 6000519b..fb8cb1b8 100644
--- a/ios/chrome/browser/discover_feed/BUILD.gn
+++ b/ios/chrome/browser/discover_feed/BUILD.gn
@@ -18,11 +18,13 @@
     "feed_model_configuration.mm",
   ]
   deps = [
-    "//base",
     "//components/keyed_service/core",
     "//ios/public/provider/chrome/browser/signin:signin_sso_api",
   ]
-  public_deps = [ ":constants" ]
+  public_deps = [
+    ":constants",
+    "//base",
+  ]
   frameworks = [ "UIKit.framework" ]
 }
 
diff --git a/ios/chrome/browser/favicon/BUILD.gn b/ios/chrome/browser/favicon/BUILD.gn
index 3e9412e..193217d 100644
--- a/ios/chrome/browser/favicon/BUILD.gn
+++ b/ios/chrome/browser/favicon/BUILD.gn
@@ -21,14 +21,10 @@
     "large_icon_cache.h",
   ]
   deps = [
-    "//base",
     "//components/favicon/core",
     "//components/favicon/core:history_implementation",
-    "//components/favicon_base",
     "//components/image_fetcher/core",
     "//components/image_fetcher/ios",
-    "//components/keyed_service/core",
-    "//components/keyed_service/ios",
     "//components/resources",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
@@ -41,6 +37,12 @@
     "//ui/base",
     "//url",
   ]
+  public_deps = [
+    "//base",
+    "//components/favicon_base",
+    "//components/keyed_service/core",
+    "//components/keyed_service/ios",
+  ]
 }
 
 source_set("unit_tests") {
diff --git a/ios/chrome/browser/follow/BUILD.gn b/ios/chrome/browser/follow/BUILD.gn
index 2c073cf..db154f63 100644
--- a/ios/chrome/browser/follow/BUILD.gn
+++ b/ios/chrome/browser/follow/BUILD.gn
@@ -20,6 +20,28 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+source_set("utils") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "follow_util.h",
+    "follow_util.mm",
+  ]
+  deps = [
+    ":enums",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/ntp:features",
+    "//ios/chrome/browser/signin",
+    "//ios/web/public",
+    "//url",
+  ]
+}
+
+source_set("enums") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [ "follow_action_state.h" ]
+  deps = []
+}
+
 source_set("tab_helper") {
   sources = [
     "follow_iph_presenter.h",
diff --git a/ios/chrome/browser/ui/follow/follow_action_state.h b/ios/chrome/browser/follow/follow_action_state.h
similarity index 66%
rename from ios/chrome/browser/ui/follow/follow_action_state.h
rename to ios/chrome/browser/follow/follow_action_state.h
index ab5091b..b3ec92ed 100644
--- a/ios/chrome/browser/ui/follow/follow_action_state.h
+++ b/ios/chrome/browser/follow/follow_action_state.h
@@ -1,9 +1,9 @@
-// Copyright 2021 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.
 
-#ifndef IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_ACTION_STATE_H_
-#define IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_ACTION_STATE_H_
+#ifndef IOS_CHROME_BROWSER_FOLLOW_FOLLOW_ACTION_STATE_H_
+#define IOS_CHROME_BROWSER_FOLLOW_FOLLOW_ACTION_STATE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -18,4 +18,4 @@
   FollowActionStateEnabled,
 };
 
-#endif  // IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_ACTION_STATE_H_
+#endif  // IOS_CHROME_BROWSER_FOLLOW_FOLLOW_ACTION_STATE_H_
diff --git a/ios/chrome/browser/follow/follow_util.h b/ios/chrome/browser/follow/follow_util.h
new file mode 100644
index 0000000..baf70d4
--- /dev/null
+++ b/ios/chrome/browser/follow/follow_util.h
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_FOLLOW_FOLLOW_UTIL_H_
+#define IOS_CHROME_BROWSER_FOLLOW_FOLLOW_UTIL_H_
+
+#import "ios/chrome/browser/follow/follow_action_state.h"
+
+namespace web {
+class WebState;
+}
+
+// Returns the Follow action state for |webState|.
+FollowActionState GetFollowActionState(web::WebState* webState);
+
+#endif  // IOS_CHROME_BROWSER_FOLLOW_FOLLOW_UTIL_H_
diff --git a/ios/chrome/browser/ui/follow/follow_util.mm b/ios/chrome/browser/follow/follow_util.mm
similarity index 83%
rename from ios/chrome/browser/ui/follow/follow_util.mm
rename to ios/chrome/browser/follow/follow_util.mm
index 7a58e1e..c846da5 100644
--- a/ios/chrome/browser/ui/follow/follow_util.mm
+++ b/ios/chrome/browser/follow/follow_util.mm
@@ -1,8 +1,8 @@
-// Copyright 2021 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.
 
-#import "ios/chrome/browser/ui/follow/follow_util.h"
+#import "ios/chrome/browser/follow/follow_util.h"
 
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/ntp/features.h"
@@ -16,8 +16,7 @@
 #error "This file requires ARC support."
 #endif
 
-FollowActionState GetFollowActionState(web::WebState* webState,
-                                       ChromeBrowserState* browserState) {
+FollowActionState GetFollowActionState(web::WebState* webState) {
   // This method should be called only if the feature flag has been enabled.
   DCHECK(IsWebChannelsEnabled());
 
@@ -25,6 +24,8 @@
     return FollowActionStateHidden;
   }
   const GURL& URL = webState->GetLastCommittedURL();
+  ChromeBrowserState* browserState =
+      ChromeBrowserState::FromBrowserState(webState->GetBrowserState());
   // Show the follow action when:
   // 1. The page url is valid;
   // 2. Users are not on NTP or Chrome internal pages;
diff --git a/ios/chrome/browser/ui/follow/BUILD.gn b/ios/chrome/browser/ui/follow/BUILD.gn
index 57d898c..119df632 100644
--- a/ios/chrome/browser/ui/follow/BUILD.gn
+++ b/ios/chrome/browser/ui/follow/BUILD.gn
@@ -67,25 +67,3 @@
     "//ui/base",
   ]
 }
-
-source_set("utils") {
-  configs += [ "//build/config/compiler:enable_arc" ]
-  sources = [
-    "follow_util.h",
-    "follow_util.mm",
-  ]
-  deps = [
-    ":enums",
-    "//ios/chrome/browser/browser_state",
-    "//ios/chrome/browser/ntp:features",
-    "//ios/chrome/browser/signin",
-    "//ios/web/public",
-    "//url",
-  ]
-}
-
-source_set("enums") {
-  configs += [ "//build/config/compiler:enable_arc" ]
-  sources = [ "follow_action_state.h" ]
-  deps = []
-}
diff --git a/ios/chrome/browser/ui/follow/follow_util.h b/ios/chrome/browser/ui/follow/follow_util.h
deleted file mode 100644
index b1f48f6..0000000
--- a/ios/chrome/browser/ui/follow/follow_util.h
+++ /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.
-
-#ifndef IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_UTIL_H_
-#define IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_UTIL_H_
-
-#import "ios/chrome/browser/ui/follow/follow_action_state.h"
-
-namespace web {
-class WebState;
-}
-
-class ChromeBrowserState;
-
-// Returns the Follow action state for |webState| and |browserState|.
-FollowActionState GetFollowActionState(web::WebState* webState,
-                                       ChromeBrowserState* browserState);
-
-#endif  // IOS_CHROME_BROWSER_UI_FOLLOW_FOLLOW_UTIL_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
index e6ba867..cbd0c642e 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_egtest.mm
@@ -548,7 +548,9 @@
     EARL_GREY_TEST_SKIPPED(@"SwiftUI is too hard to test before iOS 15.")
   }
 }
-- (void)testNotSwitchButtonOnCurrentTab {
+
+// TODO(crbug.com/1322120): Reenable this test.
+- (void)MAYBE_testNotSwitchButtonOnCurrentTab {
   if (@available(iOS 15, *)) {
     [super MAYBE_testNotSwitchButtonOnCurrentTab];
   } else {
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn
index 5f668ce..bd22670 100644
--- a/ios/chrome/browser/ui/popup_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -61,6 +61,8 @@
     "//ios/chrome/browser/browser_state_metrics",
     "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/find_in_page",
+    "//ios/chrome/browser/follow:enums",
+    "//ios/chrome/browser/follow:utils",
     "//ios/chrome/browser/main:public",
     "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/overlays",
@@ -81,8 +83,6 @@
     "//ios/chrome/browser/ui/content_suggestions/cells:constants",
     "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
     "//ios/chrome/browser/ui/default_promo:utils",
-    "//ios/chrome/browser/ui/follow:enums",
-    "//ios/chrome/browser/ui/follow:utils",
     "//ios/chrome/browser/ui/icons:action_icons",
     "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/list_model",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
index 176adcf..c76b74a 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -52,6 +52,7 @@
     "//ios/chrome/browser:chrome_url_constants",
     "//ios/chrome/browser/find_in_page",
     "//ios/chrome/browser/follow",
+    "//ios/chrome/browser/follow:enums",
     "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/overlays",
     "//ios/chrome/browser/policy",
@@ -64,7 +65,6 @@
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/default_promo:utils",
     "//ios/chrome/browser/ui/follow",
-    "//ios/chrome/browser/ui/follow:enums",
     "//ios/chrome/browser/ui/popup_menu:constants",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/web",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
index 7381c44..d737536 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
@@ -7,8 +7,8 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/chrome/browser/follow/follow_action_state.h"
 #import "ios/chrome/browser/ui/browser_container/browser_container_consumer.h"
-#import "ios/chrome/browser/ui/follow/follow_action_state.h"
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h"
 
 namespace bookmarks {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index 1ce7aacf..4a397c7 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -12,6 +12,8 @@
 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/feature_engagement/tracker_factory.h"
+#import "ios/chrome/browser/follow/follow_action_state.h"
+#import "ios/chrome/browser/follow/follow_util.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter.h"
@@ -24,8 +26,6 @@
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/find_in_page_commands.h"
 #import "ios/chrome/browser/ui/commands/popup_menu_commands.h"
-#import "ios/chrome/browser/ui/follow/follow_action_state.h"
-#import "ios/chrome/browser/ui/follow/follow_util.h"
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/feature_flags.h"
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h"
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h"
@@ -292,8 +292,7 @@
 
       if (IsWebChannelsEnabled()) {
         self.overflowMenuMediator.followActionState = GetFollowActionState(
-            self.browser->GetWebStateList()->GetActiveWebState(),
-            self.browser->GetBrowserState());
+            self.browser->GetWebStateList()->GetActiveWebState());
         ios::GetChromeBrowserProvider()
             .GetFollowProvider()
             ->SetFollowEventDelegate(self.browser);
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/BUILD.gn b/ios/chrome/browser/ui/settings/privacy/safe_browsing/BUILD.gn
index 6fd0b45..6cf3ad31 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/BUILD.gn
@@ -32,6 +32,7 @@
     "//components/password_manager/core/common",
     "//components/prefs",
     "//components/safe_browsing/core/common:safe_browsing_prefs",
+    "//components/signin/public/identity_manager/objc",
     "//components/strings:components_strings_grit",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser:application_context",
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_consumer.h b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_consumer.h
index 9f10ab9..1d9b677 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_consumer.h
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_consumer.h
@@ -13,6 +13,9 @@
 // Consumer protocol for Safe Browsing Standard Protection view.
 @protocol SafeBrowsingStandardProtectionConsumer
 
+// Reload cells for items. Does nothing if the model is not loaded yet.
+- (void)reloadCellsForItems;
+
 // Initializes item array for |safeBrowsingStandardProtectionItems|.
 - (void)setSafeBrowsingStandardProtectionItems:
     (NSArray<TableViewItem*>*)safeBrowsingStandardProtectionItems;
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_coordinator.mm b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_coordinator.mm
index c8e49509..bff3a6b6 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_coordinator.mm
@@ -10,6 +10,7 @@
 #import "ios/chrome/browser/main/browser.h"
 #include "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
+#include "ios/chrome/browser/signin/identity_manager_factory.h"
 #import "ios/chrome/browser/ui/authentication/authentication_flow.h"
 #import "ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.h"
 #import "ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_view_controller.h"
@@ -52,6 +53,8 @@
       initWithUserPrefService:self.browser->GetBrowserState()->GetPrefs()
              localPrefService:GetApplicationContext()->GetLocalState()
                   authService:AuthenticationServiceFactory::GetForBrowserState(
+                                  self.browser->GetBrowserState())
+              identityManager:IdentityManagerFactory::GetForBrowserState(
                                   self.browser->GetBrowserState())];
   self.mediator.consumer = self.viewController;
   self.viewController.modelDelegate = self.mediator;
@@ -60,6 +63,10 @@
                                            animated:YES];
 }
 
+- (void)stop {
+  [self.mediator disconnect];
+}
+
 #pragma mark - SafeBrowsingStandardProtectionViewControllerPresentationDelegate
 
 - (void)safeBrowsingStandardProtectionViewControllerDidRemove:
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.h b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.h
index fad6e7f..b26d6d1 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.h
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.h
@@ -13,6 +13,10 @@
 class AuthenticationService;
 class PrefService;
 
+namespace signin {
+class IdentityManager;
+}
+
 // Mediator for the Google services settings.
 @interface SafeBrowsingStandardProtectionMediator
     : NSObject <SafeBrowsingStandardProtectionViewControllerDelegate>
@@ -24,13 +28,19 @@
 // |userPrefService|: preference service from the browser state.
 // |localPrefService|: preference service from the application context.
 // |authService|: authentication service from browser state.
+// |identityManager|: identity manager from browser state.
 - (instancetype)initWithUserPrefService:(PrefService*)userPrefService
                        localPrefService:(PrefService*)localPrefService
                             authService:(AuthenticationService*)authService
+                        identityManager:
+                            (signin::IdentityManager*)identityManager
     NS_DESIGNATED_INITIALIZER;
 
 - (instancetype)init NS_UNAVAILABLE;
 
+// Disconnects observers.
+- (void)disconnect;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PRIVACY_SAFE_BROWSING_SAFE_BROWSING_STANDARD_PROTECTION_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.mm b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.mm
index 7927eb2c..8c835549 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.mm
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_mediator.mm
@@ -10,13 +10,14 @@
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
-#import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/ui/list_model/list_model.h"
 #import "ios/chrome/browser/ui/settings/cells/safe_browsing_header_item.h"
 #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_constants.h"
 #import "ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_consumer.h"
+#import "ios/chrome/browser/ui/settings/utils/observable_boolean.h"
 #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h"
 #import "ios/chrome/browser/ui/table_view/cells/table_view_info_button_item.h"
 #import "ios/chrome/browser/ui/table_view/cells/table_view_switch_item.h"
@@ -38,10 +39,16 @@
   ItemTypeMetricIcon,
   ItemTypePasswordLeakCheckSwitch,
   ItemTypeSafeBrowsingExtendedReporting,
+  ItemTypeSafeBrowsingManagedExtendedReporting,
 };
 }  // namespace
 
-@interface SafeBrowsingStandardProtectionMediator ()
+@interface SafeBrowsingStandardProtectionMediator () <
+    BooleanObserver,
+    IdentityManagerObserverBridgeDelegate> {
+  std::unique_ptr<signin::IdentityManagerObserverBridge>
+      _identityManagerObserver;
+}
 
 // User pref service used to check if a specific pref is managed by enterprise
 // policies.
@@ -99,7 +106,9 @@
 
 - (instancetype)initWithUserPrefService:(PrefService*)userPrefService
                        localPrefService:(PrefService*)localPrefService
-                            authService:(AuthenticationService*)authService {
+                            authService:(AuthenticationService*)authService
+                        identityManager:
+                            (signin::IdentityManager*)identityManager {
   self = [super init];
   if (self) {
     DCHECK(userPrefService);
@@ -107,23 +116,35 @@
     _userPrefService = userPrefService;
     _localPrefService = localPrefService;
     _authService = authService;
+    _identityManagerObserver =
+        std::make_unique<signin::IdentityManagerObserverBridge>(identityManager,
+                                                                self);
+
     _safeBrowsingEnhancedProtectionPreference = [[PrefBackedBoolean alloc]
         initWithPrefService:userPrefService
                    prefName:prefs::kSafeBrowsingEnhanced];
+    _safeBrowsingEnhancedProtectionPreference.observer = self;
     _safeBrowsingStandardProtectionPreference = [[PrefBackedBoolean alloc]
         initWithPrefService:userPrefService
                    prefName:prefs::kSafeBrowsingEnabled];
+    _safeBrowsingStandardProtectionPreference.observer = self;
     _safeBrowsingExtendedReportingPreference = [[PrefBackedBoolean alloc]
         initWithPrefService:userPrefService
                    prefName:prefs::kSafeBrowsingScoutReportingEnabled];
+    _safeBrowsingExtendedReportingPreference.observer = self;
     _passwordLeakCheckPreference = [[PrefBackedBoolean alloc]
         initWithPrefService:userPrefService
                    prefName:password_manager::prefs::
                                 kPasswordLeakDetectionEnabled];
+    _passwordLeakCheckPreference.observer = self;
   }
   return self;
 }
 
+- (void)disconnect {
+  _identityManagerObserver = nil;
+}
+
 #pragma mark - Properties
 
 - (ItemArray)safeBrowsingStandardProtectionItems {
@@ -131,8 +152,9 @@
     NSMutableArray* items = [NSMutableArray array];
     if (self.userPrefService->IsManagedPreference(
             prefs::kSafeBrowsingEnabled)) {
-      TableViewInfoButtonItem* safeBrowsingStandardProtectionManagedItem = [self
-          tableViewInfoButtonItemType:ItemTypeSafeBrowsingExtendedReporting
+      TableViewInfoButtonItem* safeBrowsingManagedExtendedReportingItem = [self
+          tableViewInfoButtonItemType:
+              ItemTypeSafeBrowsingManagedExtendedReporting
                          textStringID:
                              IDS_IOS_SAFE_BROWSING_STANDARD_PROTECTION_EXTENDED_REPORTING_TITLE
                        detailStringID:
@@ -140,9 +162,9 @@
                                status:
                                    self.safeBrowsingStandardProtectionPreference
                                        .value];
-      [items addObject:safeBrowsingStandardProtectionManagedItem];
+      [items addObject:safeBrowsingManagedExtendedReportingItem];
     } else {
-      SyncSwitchItem* safeBrowsingStandardProtectionItem = [self
+      SyncSwitchItem* safeBrowsingExtendedReportingItem = [self
           switchItemWithItemType:ItemTypeSafeBrowsingExtendedReporting
                     textStringID:
                         IDS_IOS_SAFE_BROWSING_STANDARD_PROTECTION_EXTENDED_REPORTING_TITLE
@@ -151,9 +173,9 @@
                     defaultState:safe_browsing::IsExtendedReportingEnabled(
                                      *self.userPrefService)
                          enabled:self.inSafeBrowsingStandardProtection];
-      safeBrowsingStandardProtectionItem.accessibilityIdentifier =
+      safeBrowsingExtendedReportingItem.accessibilityIdentifier =
           kSafeBrowsingExtendedReportingCellId;
-      [items addObject:safeBrowsingStandardProtectionItem];
+      [items addObject:safeBrowsingExtendedReportingItem];
     }
     [items addObject:self.passwordLeakCheckItem];
 
@@ -198,22 +220,10 @@
         initWithType:ItemTypePasswordLeakCheckSwitch];
     passwordLeakCheckItem.text = l10n_util::GetNSString(
         IDS_IOS_SAFE_BROWSING_STANDARD_PROTECTION_LEAK_CHECK_TITLE);
-    passwordLeakCheckItem.detailText = l10n_util::GetNSString(
-        IDS_IOS_SAFE_BROWSING_STANDARD_PROTECTION_LEAK_CHECK_SUMMARY);
-    passwordLeakCheckItem.on = [self passwordLeakCheckItemOnState];
-    if (self.safeBrowsingStandardProtectionPreference.value &&
-        self.passwordLeakCheckPreference.value &&
-        ![self isPasswordLeakCheckEnabled]) {
-      // If the user is signed out and the sync preference is enabled, this
-      // informs that it will be turned on on sign in. Also disables the button.
-      passwordLeakCheckItem.detailText =
-          l10n_util::GetNSString(IDS_IOS_LEAK_CHECK_SIGNED_OUT_ENABLED_DESC);
-      passwordLeakCheckItem.on = NO;
-    }
     passwordLeakCheckItem.accessibilityIdentifier =
         kSafeBrowsingStandardProtectionPasswordLeakCellId;
-    passwordLeakCheckItem.enabled = self.inSafeBrowsingStandardProtection &&
-                                    [self isPasswordLeakCheckEnabled];
+    [self configureLeakCheckItem:passwordLeakCheckItem];
+
     _passwordLeakCheckItem = passwordLeakCheckItem;
   }
   return _passwordLeakCheckItem;
@@ -294,6 +304,36 @@
   return switchItem;
 }
 
+// Updates switches' on and enabled status.
+- (void)updateSafeBrowsingStandardProtectionModel {
+  for (TableViewItem* item in self.safeBrowsingStandardProtectionItems) {
+    ItemType type = static_cast<ItemType>(item.type);
+    switch (type) {
+      case ItemTypePasswordLeakCheckSwitch:
+        [self configureLeakCheckItem:item];
+        break;
+      case ItemTypeSafeBrowsingExtendedReporting: {
+        SyncSwitchItem* syncSwitchItem =
+            base::mac::ObjCCastStrict<SyncSwitchItem>(item);
+        syncSwitchItem.on =
+            safe_browsing::IsExtendedReportingEnabled(*self.userPrefService);
+        syncSwitchItem.enabled = self.inSafeBrowsingStandardProtection;
+        break;
+      }
+      case ItemTypeSafeBrowsingManagedExtendedReporting:
+        base::mac::ObjCCastStrict<TableViewInfoButtonItem>(item).statusText =
+            self.safeBrowsingExtendedReportingPreference.value
+                ? l10n_util::GetNSString(IDS_IOS_SETTING_ON)
+                : l10n_util::GetNSString(IDS_IOS_SETTING_OFF);
+        break;
+      default:
+        break;
+    }
+  }
+
+  [self.consumer reloadCellsForItems];
+}
+
 // Returns a boolean indicating whether leak detection feature is enabled.
 - (BOOL)isPasswordLeakCheckEnabled {
   return self.authService->HasPrimaryIdentity(signin::ConsentLevel::kSignin) ||
@@ -305,10 +345,32 @@
 // based on the sync preference, the sign in status, and if the user has
 // selected Standard Protection as the Safe Browsing option.
 - (BOOL)passwordLeakCheckItemOnState {
-  return self.safeBrowsingEnhancedProtectionPreference.value ||
-         (self.safeBrowsingStandardProtectionPreference.value &&
-          self.passwordLeakCheckPreference.value &&
-          [self isPasswordLeakCheckEnabled]);
+  return [self isPasswordLeakCheckEnabled] &&
+         (self.safeBrowsingEnhancedProtectionPreference.value ||
+          (self.safeBrowsingStandardProtectionPreference.value &&
+           self.passwordLeakCheckPreference.value));
+}
+
+// Updates the detail text and on state of the leak check item based on the
+// state.
+- (void)configureLeakCheckItem:(TableViewItem*)item {
+  TableViewSwitchItem* leakCheckItem =
+      base::mac::ObjCCastStrict<TableViewSwitchItem>(item);
+  leakCheckItem.enabled = self.inSafeBrowsingStandardProtection &&
+                          [self isPasswordLeakCheckEnabled];
+  leakCheckItem.on = [self passwordLeakCheckItemOnState];
+
+  if (self.passwordLeakCheckPreference.value &&
+      ![self isPasswordLeakCheckEnabled] &&
+      self.safeBrowsingStandardProtectionPreference.value) {
+    // If the user is signed out and the sync preference is enabled, this
+    // informs that it will be turned on on sign in.
+    leakCheckItem.detailText =
+        l10n_util::GetNSString(IDS_IOS_LEAK_CHECK_SIGNED_OUT_ENABLED_DESC);
+    return;
+  }
+  leakCheckItem.detailText = l10n_util::GetNSString(
+      IDS_IOS_SAFE_BROWSING_STANDARD_PROTECTION_LEAK_CHECK_SUMMARY);
 }
 
 #pragma mark - SafeBrowsingStandardProtectionViewControllerDelegate
@@ -331,4 +393,18 @@
   }
 }
 
+#pragma mark - BooleanObserver
+
+- (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean {
+  [self updateSafeBrowsingStandardProtectionModel];
+}
+
+#pragma mark - IdentityManagerObserverBridgeDelegate
+
+// Used to update model when signing in/out is completed.
+- (void)onPrimaryAccountChanged:
+    (const signin::PrimaryAccountChangeEvent&)event {
+  [self updateSafeBrowsingStandardProtectionModel];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_view_controller.mm
index dfdd201..31a10c1 100644
--- a/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/privacy/safe_browsing/safe_browsing_standard_protection_view_controller.mm
@@ -148,6 +148,15 @@
 
 #pragma mark - SafeBrowsingStandardProtectionConsumer
 
+- (void)reloadCellsForItems {
+  if (!self.tableViewModel) {
+    // No need to reconfigure since the model has not been loaded yet.
+    return;
+  }
+  [self reloadCellsForItems:self.safeBrowsingStandardProtectionItems
+           withRowAnimation:UITableViewRowAnimationAutomatic];
+}
+
 - (void)setSafeBrowsingStandardProtectionItems:
     (ItemArray)safeBrowsingStandardProtectionItems {
   _safeBrowsingStandardProtectionItems = safeBrowsingStandardProtectionItems;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/features.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/features.mm
index f851b0c..22837e747 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/features.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/features.mm
@@ -8,8 +8,7 @@
 #error "This file requires ARC support."
 #endif
 
-const base::Feature kTabsSearch{"TabsSearch",
-                                base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTabsSearch{"TabsSearch", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kTabsSearchRegularResultsSuggestedActions{
     "TabsSearchRegularResultsSuggestedActions",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_page_control.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_page_control.mm
index 41a1798..0ba02879 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_page_control.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_page_control.mm
@@ -59,6 +59,7 @@
 // constrainst for the guides have been applied.
 
 namespace {
+
 // Height and width of the slider.
 const CGFloat kSliderHeight = 40.0;
 const CGFloat kSliderWidth = 78.0;
@@ -109,17 +110,27 @@
   return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
 }
 
-// Convenience method that composes an asset name and returns the correct image
-// (in template rendering mode) based on the segment name (one of "regular",
-// "incognito, "remote") and whether the selected state image is needed or not.
-UIImage* ImageForSegment(NSString* segment, BOOL selected) {
-  NSString* asset =
-      [NSString stringWithFormat:@"page_control_%@_tabs%@", segment,
-                                 selected ? @"_selected" : @""];
-  return [[UIImage imageNamed:asset]
-      imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
+// Image names for the different icon state.
+NSString* kImagePageControlRegularSelected =
+    @"page_control_regular_tabs_selected";
+NSString* kImagePageControlRegularNotSelected = @"page_control_regular_tabs";
+NSString* kImagePageControlIncognitoSelected =
+    @"page_control_incognito_tabs_selected";
+NSString* kImagePageControlIncognitoNotSelected =
+    @"page_control_incognito_tabs";
+NSString* kImagePageControlRemoteSelected =
+    @"page_control_remote_tabs_selected";
+NSString* kImagePageControlRemoteNotSelected = @"page_control_remote_tabs";
+
+// Returns an UIImageView for the given imgageName.
+UIImageView* ImageViewForImageNamed(NSString* imageName) {
+  return [[UIImageView alloc]
+      initWithImage:
+          [[UIImage imageNamed:imageName]
+              imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
 }
-}
+
+}  // namespace
 
 // View class used for the background of this control; it draws the grey
 // rectangles with clear separators.
@@ -143,13 +154,13 @@
 @property(nonatomic, weak) UIView* selectedImageView;
 // The labels for the incognito and regular sections, in regular and selected
 // variants.
-@property(nonatomic, weak) UIView* incognitoIcon;
+@property(nonatomic, weak) UIView* incognitoNotSelectedIcon;
 @property(nonatomic, weak) UIView* incognitoSelectedIcon;
-@property(nonatomic, weak) UIView* regularIcon;
+@property(nonatomic, weak) UIView* regularNotSelectedIcon;
 @property(nonatomic, weak) UIView* regularSelectedIcon;
 @property(nonatomic, weak) UILabel* regularLabel;
 @property(nonatomic, weak) UILabel* regularSelectedLabel;
-@property(nonatomic, weak) UIView* remoteIcon;
+@property(nonatomic, weak) UIView* remoteNotSelectedIcon;
 @property(nonatomic, weak) UIView* remoteSelectedIcon;
 
 // Standard pointer interactions provided UIKit require views on which to attach
@@ -381,18 +392,21 @@
 
   // Position the section images, labels and hover views, which depend on the
   // layout guides.
-  self.incognitoIcon.center = [self centerOfSegment:TabGridPageIncognitoTabs];
+  self.incognitoNotSelectedIcon.center =
+      [self centerOfSegment:TabGridPageIncognitoTabs];
   self.incognitoSelectedIcon.center =
       [self centerOfSegment:TabGridPageIncognitoTabs];
 
-  self.regularIcon.center = [self centerOfSegment:TabGridPageRegularTabs];
+  self.regularNotSelectedIcon.center =
+      [self centerOfSegment:TabGridPageRegularTabs];
   self.regularSelectedIcon.center =
       [self centerOfSegment:TabGridPageRegularTabs];
   self.regularLabel.center = [self centerOfSegment:TabGridPageRegularTabs];
   self.regularSelectedLabel.center =
       [self centerOfSegment:TabGridPageRegularTabs];
 
-  self.remoteIcon.center = [self centerOfSegment:TabGridPageRemoteTabs];
+  self.remoteNotSelectedIcon.center =
+      [self centerOfSegment:TabGridPageRemoteTabs];
   self.remoteSelectedIcon.center = [self centerOfSegment:TabGridPageRemoteTabs];
 
   self.incognitoHoverView.center =
@@ -457,6 +471,44 @@
 
 #pragma mark - Private
 
+// Configures and Adds icon to the tab grid page control for the given tab.
+- (void)addTabsIcon:(TabGridPage)tab {
+  UIImageView* iconSelected;
+  UIImageView* iconNotSelected;
+  switch (tab) {
+    case TabGridPageRegularTabs: {
+      iconSelected = ImageViewForImageNamed(kImagePageControlRegularSelected);
+      iconNotSelected =
+          ImageViewForImageNamed(kImagePageControlRegularNotSelected);
+      self.regularSelectedIcon = iconSelected;
+      self.regularNotSelectedIcon = iconNotSelected;
+      break;
+    }
+    case TabGridPageIncognitoTabs: {
+      iconSelected = ImageViewForImageNamed(kImagePageControlIncognitoSelected);
+      iconNotSelected =
+          ImageViewForImageNamed(kImagePageControlIncognitoNotSelected);
+      self.incognitoSelectedIcon = iconSelected;
+      self.incognitoNotSelectedIcon = iconNotSelected;
+      break;
+    }
+    case TabGridPageRemoteTabs: {
+      iconSelected = ImageViewForImageNamed(kImagePageControlRemoteSelected);
+      iconNotSelected =
+          ImageViewForImageNamed(kImagePageControlRemoteNotSelected);
+      self.remoteSelectedIcon = iconSelected;
+      self.remoteNotSelectedIcon = iconNotSelected;
+      break;
+    }
+  }
+
+  iconNotSelected.tintColor = UIColorFromRGB(kSliderColor);
+  iconSelected.tintColor = UIColorFromRGB(kSelectedColor);
+
+  [self insertSubview:iconNotSelected belowSubview:self.sliderView];
+  [self.selectedImageView addSubview:iconSelected];
+}
+
 // Sets up all of the subviews for this control, as well as the layout guides
 // used to position the section content.
 - (void)setupViews {
@@ -521,17 +573,10 @@
   [self.sliderView addSubview:selectedImageView];
   self.selectedImageView = selectedImageView;
 
-  // Icons and labels for the regular tabs.
-  UIImageView* regularIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"regular", NO)];
-  regularIcon.tintColor = UIColorFromRGB(kSliderColor);
-  [self insertSubview:regularIcon belowSubview:self.sliderView];
-  self.regularIcon = regularIcon;
-  UIImageView* regularSelectedIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"regular", YES)];
-  regularSelectedIcon.tintColor = UIColorFromRGB(kSelectedColor);
-  [self.selectedImageView addSubview:regularSelectedIcon];
-  self.regularSelectedIcon = regularSelectedIcon;
+  [self addTabsIcon:TabGridPageRegularTabs];
+  [self addTabsIcon:TabGridPageIncognitoTabs];
+  [self addTabsIcon:TabGridPageRemoteTabs];
+
   UILabel* regularLabel = [self labelSelected:NO];
   [self insertSubview:regularLabel belowSubview:self.sliderView];
   self.regularLabel = regularLabel;
@@ -539,30 +584,6 @@
   [self.selectedImageView addSubview:regularSelectedLabel];
   self.regularSelectedLabel = regularSelectedLabel;
 
-  // Icons for the incognito tabs section.
-  UIImageView* incognitoIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"incognito", NO)];
-  incognitoIcon.tintColor = UIColorFromRGB(kSliderColor);
-  [self insertSubview:incognitoIcon belowSubview:self.sliderView];
-  self.incognitoIcon = incognitoIcon;
-  UIImageView* incognitoSelectedIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"incognito", YES)];
-  incognitoSelectedIcon.tintColor = UIColorFromRGB(kSelectedColor);
-  [self.selectedImageView addSubview:incognitoSelectedIcon];
-  self.incognitoSelectedIcon = incognitoSelectedIcon;
-
-  // Icons for the remote tabs section.
-  UIImageView* remoteIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"remote", NO)];
-  remoteIcon.tintColor = UIColorFromRGB(kSliderColor);
-  [self insertSubview:remoteIcon belowSubview:self.sliderView];
-  self.remoteIcon = remoteIcon;
-  UIImageView* remoteSelectedIcon =
-      [[UIImageView alloc] initWithImage:ImageForSegment(@"remote", YES)];
-  remoteSelectedIcon.tintColor = UIColorFromRGB(kSelectedColor);
-  [self.selectedImageView addSubview:remoteSelectedIcon];
-  self.remoteSelectedIcon = remoteSelectedIcon;
-
   CGRect segmentRect = CGRectMake(0, 0, kSegmentWidth, kOverallHeight);
   UIView* incognitoHoverView = [[UIView alloc] initWithFrame:segmentRect];
   UIView* regularHoverView = [[UIView alloc] initWithFrame:segmentRect];
diff --git a/ios/chrome/test/swift_interop/classes/polymorphism.h b/ios/chrome/test/swift_interop/classes/polymorphism.h
index 333ef09..961466f 100644
--- a/ios/chrome/test/swift_interop/classes/polymorphism.h
+++ b/ios/chrome/test/swift_interop/classes/polymorphism.h
@@ -15,6 +15,7 @@
 
   // Virtual or not, this cannot be called on inherited classes unless it
   // is redefined in their declaration.
+  // https://github.com/apple/swift/issues/55192
   bool HasSides() { return true; }
 
  protected:
@@ -38,6 +39,7 @@
 
   // Even though these should not be necessary, they are. Without them, calling
   // these methods on a Square object results in a compiler error.
+  // https://github.com/apple/swift/issues/55192
   virtual int Area() { return width_ * height_; }
   virtual int NumberOfSides() { return 4; }
 };
diff --git a/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift b/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift
index 958ee664..1260554c 100644
--- a/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift
+++ b/ios/chrome/test/swift_interop/classes/polymorphism_xctest.swift
@@ -23,6 +23,10 @@
     #endif
   }
 
+  // The primary bug for inherited methods not working is
+  // https://github.com/apple/swift/issues/55192. That covers several of
+  // these tests.
+
   func testInheritedMethods_noCompile() throws {
     // Test calling a public method defined in the public base class.
     // DOESN'T COMPILE: value of type 'Rectangle' has no member 'HasSides'
diff --git a/ios/chrome/test/swift_interop/namespace/namespace_xctest.swift b/ios/chrome/test/swift_interop/namespace/namespace_xctest.swift
index 9dbff2f..f1d85ed 100644
--- a/ios/chrome/test/swift_interop/namespace/namespace_xctest.swift
+++ b/ios/chrome/test/swift_interop/namespace/namespace_xctest.swift
@@ -61,7 +61,7 @@
 
     // Test the enum class in a namespace.
     // CRASHES in XCTAssertNotEqual()
-    // In theory, this is fixed by https://github.com/apple/swift/pull/42494.
+    // In progress CL: https://github.com/apple/swift/pull/42494.
     // let moreFood = sameName.SameNameEnum.watermelon;
     // XCTAssertNotEqual(moreFood, sameName.SameNameEnum.orange, "something broke")
   }
diff --git a/ios/chrome/test/swift_interop/pointer/object_passing_xctest.swift b/ios/chrome/test/swift_interop/pointer/object_passing_xctest.swift
index 818cec5..2b05e03 100644
--- a/ios/chrome/test/swift_interop/pointer/object_passing_xctest.swift
+++ b/ios/chrome/test/swift_interop/pointer/object_passing_xctest.swift
@@ -8,13 +8,16 @@
 class ObjectPassingTest: XCTestCase {
 
   func testReferenceParameters() throws {
-    #if swift(>=5.6)
+    #if swift(>=5.7)
       let a = Object(10)
       let b = Object(20)
-      let passer = ObjectPassing()
     #else
       var a = Object(10)
       var b = Object(20)
+    #endif
+    #if swift(>=5.6)
+      let passer = ObjectPassing()
+    #else
       var passer = ObjectPassing()
     #endif
     XCTAssertEqual(a.GetValue(), 10)
diff --git a/ios/chrome/test/swift_interop/pointer/unique_ptr.h b/ios/chrome/test/swift_interop/pointer/unique_ptr.h
index d797b0a..8c0102f 100644
--- a/ios/chrome/test/swift_interop/pointer/unique_ptr.h
+++ b/ios/chrome/test/swift_interop/pointer/unique_ptr.h
@@ -10,6 +10,7 @@
 // As of Xcode 13.3, any C++ classes that contain a std::unique_ptr<T>
 // fails to emit the definition to Swift, and use of the object in Swift
 // results in an error: "cannot find 'T' in scope".
+// https://github.com/apple/swift/issues/58639
 #define SWIFT_INTEROP_UNIQUE_PTR_WORKS 0
 
 class Value {
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 c98ae40..ab8d592 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 @@
-dea0a0f011d0cd6027b0cb5d9b704e14cd492de2
\ No newline at end of file
+ebe91136ad8bb00d8bc0b64ae80bba8c533a3f78
\ 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 daf5618f..0172056 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 @@
-5536c32c35df0e9642cb182da5c37070ac73cdc7
\ No newline at end of file
+15523e0295a28c6c68dae87ccaa6dd5614683887
\ 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 b6c657cd..73548e01 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 @@
-a45c958d9077f28df8f399cef3ceddcf24d61b6a
\ No newline at end of file
+1e960a5745c0785420c5c6e70761ab6cbfc8105a
\ 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 16e3016a..825b3cc 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 @@
-eed0a3a9cf38c7d6dea11e2e137734023de3e284
\ No newline at end of file
+5de11bc6ed6194e613a54b82fe1aa0124603a661
\ 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 bbdd225..abb93db 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 @@
-709d29f7bb32e327e29e19c897d8ef99d4868bd2
\ No newline at end of file
+33403a211b23be4631022a7c2bf2545a8a6a4ca0
\ 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 b605a3b..80ff7b2 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 @@
-6be3d48dcc24ae0f90a9d5af5fe99c937f8ea695
\ No newline at end of file
+cfcc61c10490a75dc3023a62a78d67ea32101f1b
\ 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 11df668..160d44c 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 @@
-fa7d9ae13132518a4cc83814ba8183eb8419c413
\ No newline at end of file
+d452062b6a994cdf3325b810fec1d87c3506d09b
\ 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 4672119..6bcd0c7 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 @@
-e72e13fbcc4d2995a3c3a2686889a5e971838e0f
\ No newline at end of file
+6e8758220c9fd5f572abd835b96e69487c0eac3d
\ 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 41379fa..b9c21aa 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 @@
-2fe4709db61d6cd62ee853194af75f110d5d5be8
\ No newline at end of file
+29f48b9c2205238494680427dc03470bb1c7075c
\ 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 83b38ba7..25c5a999 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 @@
-d512604e10744cb763ab0bba5f70abbf2c099064
\ No newline at end of file
+0f666007092a9ae200f179b0739f23d43db98316
\ No newline at end of file
diff --git a/ios/public/provider/chrome/browser/BUILD.gn b/ios/public/provider/chrome/browser/BUILD.gn
index 786e03d7..55cd0d13 100644
--- a/ios/public/provider/chrome/browser/BUILD.gn
+++ b/ios/public/provider/chrome/browser/BUILD.gn
@@ -11,13 +11,13 @@
     "chrome_browser_provider.mm",
   ]
   deps = [
-    "//base",
     "//components/metrics",
     "//ios/public/provider/chrome/browser/signin",
     "//ios/web/public",
     "//ios/web/public/js_messaging",
     "//url",
   ]
+  public_deps = [ "//base" ]
   frameworks = [ "CoreLocation.framework" ]
 }
 
diff --git a/ios/public/provider/chrome/browser/discover_feed/BUILD.gn b/ios/public/provider/chrome/browser/discover_feed/BUILD.gn
index 2452edf..0de3db2 100644
--- a/ios/public/provider/chrome/browser/discover_feed/BUILD.gn
+++ b/ios/public/provider/chrome/browser/discover_feed/BUILD.gn
@@ -5,5 +5,5 @@
 source_set("discover_feed_api") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [ "discover_feed_api.h" ]
-  deps = [ "//ios/chrome/browser/discover_feed" ]
+  public_deps = [ "//ios/chrome/browser/discover_feed" ]
 }
diff --git a/ios/public/provider/chrome/browser/omaha/BUILD.gn b/ios/public/provider/chrome/browser/omaha/BUILD.gn
index 070a4e8..6e57b80 100644
--- a/ios/public/provider/chrome/browser/omaha/BUILD.gn
+++ b/ios/public/provider/chrome/browser/omaha/BUILD.gn
@@ -5,7 +5,7 @@
 source_set("omaha_api") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [ "omaha_api.h" ]
-  deps = [
+  public_deps = [
     "//base",
     "//url",
   ]
diff --git a/ios/web/public/navigation/BUILD.gn b/ios/web/public/navigation/BUILD.gn
index 900225b..f6e1400 100644
--- a/ios/web/public/navigation/BUILD.gn
+++ b/ios/web/public/navigation/BUILD.gn
@@ -6,12 +6,15 @@
   deps = [
     "//ios/web/common:user_agent",
     "//ios/web/public/ui",
+  ]
+
+  public_deps = [
+    ":referrer",
+    "//base",
     "//ui/base",
     "//url",
   ]
 
-  public_deps = [ ":referrer" ]
-
   sources = [
     "browser_url_rewriter.h",
     "navigation_context.h",
diff --git a/media/audio/audio_encoders_unittest.cc b/media/audio/audio_encoders_unittest.cc
index 1eea43a..8db7f1e2 100644
--- a/media/audio/audio_encoders_unittest.cc
+++ b/media/audio/audio_encoders_unittest.cc
@@ -31,7 +31,7 @@
 #define HAS_AAC_ENCODER 1
 #endif
 
-#if BUILDFLAG(IS_MAC)
+#if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
 #include "media/filters/mac/audio_toolbox_audio_encoder.h"
 #define HAS_AAC_ENCODER 1
 #endif
@@ -171,7 +171,7 @@
       frames_per_buffer_ = kAacFramesPerBuffer;
       buffer_duration_ = AudioTimestampHelper::FramesToTime(
           frames_per_buffer_, options_.sample_rate);
-#elif BUILDFLAG(IS_MAC)
+#elif HAS_AAC_ENCODER && BUILDFLAG(IS_MAC)
       encoder_ = std::make_unique<AudioToolboxAudioEncoder>();
       frames_per_buffer_ = kAacFramesPerBuffer;
       buffer_duration_ = AudioTimestampHelper::FramesToTime(
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
index 8133014..39533246 100644
--- a/media/base/supported_types.cc
+++ b/media/base/supported_types.cc
@@ -208,6 +208,14 @@
 #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   return GetSupplementalProfileCache()->IsProfileSupported(type.profile);
+#elif BUILDFLAG(IS_MAC)
+  if (__builtin_available(macOS 11.0, *))
+    return base::FeatureList::IsEnabled(kVideoToolboxHEVCDecoding) &&
+           (type.profile == HEVCPROFILE_MAIN ||
+            type.profile == HEVCPROFILE_MAIN10 ||
+            type.profile == HEVCPROFILE_MAIN_STILL_PICTURE ||
+            type.profile == HEVCPROFILE_REXT);
+  return false;
 #elif BUILDFLAG(IS_ANDROID)
   // Technically android 5.0 mandates support for only HEVC main profile,
   // however some platforms (like chromecast) have had more profiles supported
diff --git a/media/fuchsia/common/vmo_buffer_writer_queue.cc b/media/fuchsia/common/vmo_buffer_writer_queue.cc
index b983e00..272f548 100644
--- a/media/fuchsia/common/vmo_buffer_writer_queue.cc
+++ b/media/fuchsia/common/vmo_buffer_writer_queue.cc
@@ -13,33 +13,29 @@
 
 namespace media {
 
-struct VmoBufferWriterQueue::PendingBuffer {
-  PendingBuffer(scoped_refptr<DecoderBuffer> buffer) : buffer(buffer) {
-    DCHECK(buffer);
-  }
-  ~PendingBuffer() = default;
+VmoBufferWriterQueue::PendingBuffer::PendingBuffer(
+    scoped_refptr<DecoderBuffer> buffer)
+    : buffer(buffer) {
+  DCHECK(buffer);
+}
 
-  PendingBuffer(PendingBuffer&& other) = default;
-  PendingBuffer& operator=(PendingBuffer&& other) = default;
+VmoBufferWriterQueue::PendingBuffer::~PendingBuffer() = default;
 
-  const uint8_t* data() const { return buffer->data() + buffer_pos; }
-  size_t bytes_left() const { return buffer->data_size() - buffer_pos; }
-  void AdvanceCurrentPos(size_t bytes) {
-    DCHECK_LE(bytes, bytes_left());
-    buffer_pos += bytes;
-  }
+VmoBufferWriterQueue::PendingBuffer::PendingBuffer(PendingBuffer&& other) =
+    default;
 
-  scoped_refptr<DecoderBuffer> buffer;
-  size_t buffer_pos = 0;
+const uint8_t* VmoBufferWriterQueue::PendingBuffer::data() const {
+  return buffer->data() + buffer_pos;
+}
 
-  // Set to true when the consumer has finished processing the buffer and it can
-  // be released.
-  bool is_complete = false;
+size_t VmoBufferWriterQueue::PendingBuffer::bytes_left() const {
+  return buffer->data_size() - buffer_pos;
+}
 
-  // Index of the last buffer in the sysmem buffer collection that was used to
-  // send this input buffer. Should be set only when |bytes_left()==0|.
-  absl::optional<size_t> tail_sysmem_buffer_index;
-};
+void VmoBufferWriterQueue::PendingBuffer::AdvanceCurrentPos(size_t bytes) {
+  DCHECK_LE(bytes, bytes_left());
+  buffer_pos += bytes;
+}
 
 VmoBufferWriterQueue::VmoBufferWriterQueue() {
   DETACH_FROM_THREAD(thread_checker_);
diff --git a/media/fuchsia/common/vmo_buffer_writer_queue.h b/media/fuchsia/common/vmo_buffer_writer_queue.h
index d8c701d..2969297 100644
--- a/media/fuchsia/common/vmo_buffer_writer_queue.h
+++ b/media/fuchsia/common/vmo_buffer_writer_queue.h
@@ -82,7 +82,29 @@
   bool IsBlocked() const;
 
  private:
-  struct PendingBuffer;
+  struct PendingBuffer {
+    PendingBuffer(scoped_refptr<DecoderBuffer> buffer);
+    ~PendingBuffer();
+
+    PendingBuffer(PendingBuffer&& other);
+    PendingBuffer& operator=(PendingBuffer&& other) = default;
+
+    const uint8_t* data() const;
+    size_t bytes_left() const;
+    void AdvanceCurrentPos(size_t bytes);
+
+    scoped_refptr<DecoderBuffer> buffer;
+    size_t buffer_pos = 0;
+
+    // Set to true when the consumer has finished processing the buffer and it
+    // can be released.
+    bool is_complete = false;
+
+    // Index of the last buffer in the sysmem buffer collection that was used to
+    // send this input buffer. Should be set only when |bytes_left()==0|.
+    absl::optional<size_t> tail_sysmem_buffer_index;
+  };
+
   class SysmemBuffer;
 
   // Pumps pending buffers to SendPacketCB.
diff --git a/media/gpu/android/ndk_video_encode_accelerator.cc b/media/gpu/android/ndk_video_encode_accelerator.cc
index 8c3b3fa8..15e70e5 100644
--- a/media/gpu/android/ndk_video_encode_accelerator.cc
+++ b/media/gpu/android/ndk_video_encode_accelerator.cc
@@ -55,11 +55,12 @@
 }
 
 MediaFormatPtr CreateVideoFormat(const std::string& mime,
-                                 gfx::Size frame_size,
-                                 Bitrate bitrate,
+                                 const VideoEncodeAccelerator::Config& config,
                                  int framerate,
-                                 int iframe_interval,
                                  PixelFormat format) {
+  const int iframe_interval = config.gop_length.value_or(kDefaultGOPLength);
+  const gfx::Size& frame_size = config.input_visible_size;
+  const Bitrate& bitrate = config.bitrate;
   MediaFormatPtr result(AMediaFormat_new());
   AMediaFormat_setString(result.get(), AMEDIAFORMAT_KEY_MIME, mime.c_str());
   AMediaFormat_setInt32(result.get(), AMEDIAFORMAT_KEY_WIDTH,
@@ -71,6 +72,8 @@
   AMediaFormat_setInt32(result.get(), AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
                         iframe_interval);
   AMediaFormat_setInt32(result.get(), AMEDIAFORMAT_KEY_COLOR_FORMAT, format);
+  if (config.require_low_delay)
+    AMediaFormat_setInt32(result.get(), AMEDIAFORMAT_KEY_LATENCY, 1);
 
   constexpr int32_t BITRATE_MODE_VBR = 1;
   constexpr int32_t BITRATE_MODE_CBR = 2;
@@ -228,9 +231,8 @@
     return false;
   }
   effective_framerate_ = config.initial_framerate.value_or(kDefaultFramerate);
-  auto media_format = CreateVideoFormat(
-      mime, config.input_visible_size, config.bitrate, effective_framerate_,
-      config.gop_length.value_or(kDefaultGOPLength), format.value());
+  auto media_format =
+      CreateVideoFormat(mime, config, effective_framerate_, format.value());
 
   media_codec_.reset(AMediaCodec_createEncoderByType(mime.c_str()));
   if (!media_codec_) {
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index 91c0d9a..a2abeca8 100644
--- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -83,9 +83,8 @@
     VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE2,
 
     // These are only supported on macOS 11+.
-    // TODO(crbug.com/1300786): add HEVCPROFILE_MAIN_STILL_PICTURE,
-    // and HEVCPROFILE_REXT since VT has already supported these profiles
-    HEVCPROFILE_MAIN, HEVCPROFILE_MAIN10,
+    HEVCPROFILE_MAIN, HEVCPROFILE_MAIN10, HEVCPROFILE_MAIN_STILL_PICTURE,
+    HEVCPROFILE_REXT,
 
     // TODO(sandersd): Hi10p fails during
     // CMVideoFormatDescriptionCreateFromH264ParameterSets with
@@ -760,6 +759,8 @@
 #if BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
     case HEVCPROFILE_MAIN:
     case HEVCPROFILE_MAIN10:
+    case HEVCPROFILE_MAIN_STILL_PICTURE:
+    case HEVCPROFILE_REXT:
       codec_ = VideoCodec::kHEVC;
       break;
 #endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
@@ -842,7 +843,8 @@
   const bool require_hardware = config_.profile == VP9PROFILE_PROFILE0 ||
                                 config_.profile == VP9PROFILE_PROFILE2;
   const bool is_hbd = config_.profile == VP9PROFILE_PROFILE2 ||
-                      config_.profile == HEVCPROFILE_MAIN10;
+                      config_.profile == HEVCPROFILE_MAIN10 ||
+                      config_.profile == HEVCPROFILE_REXT;
   if (!CreateVideoToolboxSession(format_, require_hardware, is_hbd, &callback_,
                                  &session_, &configured_size_)) {
     NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
@@ -2052,7 +2054,8 @@
       // TODO(https://crbug.com/1233228): The UV planes of P010 frames cannot
       // be represented in the current gfx::BufferFormat.
       if (config_.profile != VP9PROFILE_PROFILE2 &&
-          config_.profile != HEVCPROFILE_MAIN10)
+          config_.profile != HEVCPROFILE_MAIN10 &&
+          config_.profile != HEVCPROFILE_REXT)
         picture_format_ = PIXEL_FORMAT_NV12;
     }
 
@@ -2083,7 +2086,8 @@
 
   const gfx::BufferFormat buffer_format =
       config_.profile == VP9PROFILE_PROFILE2 ||
-              config_.profile == HEVCPROFILE_MAIN10
+              config_.profile == HEVCPROFILE_MAIN10 ||
+              config_.profile == HEVCPROFILE_REXT
           ? gfx::BufferFormat::P010
           : gfx::BufferFormat::YUV_420_BIPLANAR;
   gfx::ColorSpace color_space = GetImageBufferColorSpace(frame.image);
@@ -2339,7 +2343,9 @@
     }
 
     if (supported_profile == HEVCPROFILE_MAIN ||
-        supported_profile == HEVCPROFILE_MAIN10) {
+        supported_profile == HEVCPROFILE_MAIN10 ||
+        supported_profile == HEVCPROFILE_MAIN_STILL_PICTURE ||
+        supported_profile == HEVCPROFILE_REXT) {
 #if BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
       if (!workarounds.disable_accelerated_hevc_decode &&
           base::FeatureList::IsEnabled(kVideoToolboxHEVCDecoding)) {
diff --git a/media/mojo/services/mojo_audio_input_stream.cc b/media/mojo/services/mojo_audio_input_stream.cc
index 58c856d..75a3fd0 100644
--- a/media/mojo/services/mojo_audio_input_stream.cc
+++ b/media/mojo/services/mojo_audio_input_stream.cc
@@ -13,6 +13,7 @@
 #include "base/sync_socket.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "mojo/public/cpp/system/platform_handle.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace media {
 
@@ -90,7 +91,7 @@
   mojo::PlatformHandle socket_handle(foreign_socket->Take());
 
   std::move(stream_created_callback_)
-      .Run({base::in_place, std::move(shared_memory_region),
+      .Run({absl::in_place, std::move(shared_memory_region),
             std::move(socket_handle)},
            initially_muted);
 }
diff --git a/media/mojo/services/mojo_audio_output_stream.cc b/media/mojo/services/mojo_audio_output_stream.cc
index 7f30231..865dede 100644
--- a/media/mojo/services/mojo_audio_output_stream.cc
+++ b/media/mojo/services/mojo_audio_output_stream.cc
@@ -14,6 +14,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/mojo/mojom/audio_data_pipe.mojom.h"
 #include "mojo/public/cpp/system/platform_handle.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace media {
 
@@ -91,7 +92,7 @@
 
   std::move(stream_created_callback_)
       .Run(std::move(pending_stream),
-           {base::in_place, std::move(shared_memory_region),
+           {absl::in_place, std::move(shared_memory_region),
             std::move(socket_handle)});
 }
 
diff --git a/media/video/h265_parser.cc b/media/video/h265_parser.cc
index d366d29..46e840f 100644
--- a/media/video/h265_parser.cc
+++ b/media/video/h265_parser.cc
@@ -650,40 +650,44 @@
                    sps->pic_height_in_luma_samples);
   }
 
-  bool sps_extension_present_flag;
-  bool sps_range_extension_flag = false;
-  bool sps_multilayer_extension_flag = false;
-  bool sps_3d_extension_flag = false;
-  bool sps_scc_extension_flag = false;
-  READ_BOOL_OR_RETURN(&sps_extension_present_flag);
-  if (sps_extension_present_flag) {
-    READ_BOOL_OR_RETURN(&sps_range_extension_flag);
-    READ_BOOL_OR_RETURN(&sps_multilayer_extension_flag);
-    READ_BOOL_OR_RETURN(&sps_3d_extension_flag);
-    READ_BOOL_OR_RETURN(&sps_scc_extension_flag);
+  READ_BOOL_OR_RETURN(&sps->sps_extension_present_flag);
+  if (sps->sps_extension_present_flag) {
+    READ_BOOL_OR_RETURN(&sps->sps_range_extension_flag);
+    READ_BOOL_OR_RETURN(&sps->sps_multilayer_extension_flag);
+    READ_BOOL_OR_RETURN(&sps->sps_3d_extension_flag);
+    READ_BOOL_OR_RETURN(&sps->sps_scc_extension_flag);
     SKIP_BITS_OR_RETURN(4);  // sps_extension_4bits
   }
-  if (sps_range_extension_flag) {
-    DVLOG(1) << "HEVC range extension not supported";
-    return kInvalidStream;
+  if (sps->sps_range_extension_flag) {
+    READ_BOOL_OR_RETURN(&sps->transform_skip_rotation_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->transform_skip_context_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->implicit_rdpcm_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->explicit_rdpcm_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->extended_precision_processing_flag);
+    READ_BOOL_OR_RETURN(&sps->intra_smoothing_disabled_flag);
+    READ_BOOL_OR_RETURN(&sps->high_precision_offsets_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->persistent_rice_adaptation_enabled_flag);
+    READ_BOOL_OR_RETURN(&sps->cabac_bypass_alignment_enabled_flag);
   }
-  if (sps_multilayer_extension_flag) {
+  if (sps->sps_multilayer_extension_flag) {
     DVLOG(1) << "HEVC multilayer extension not supported";
     return kInvalidStream;
   }
-  if (sps_3d_extension_flag) {
+  if (sps->sps_3d_extension_flag) {
     DVLOG(1) << "HEVC 3D extension not supported";
     return kInvalidStream;
   }
-  if (sps_scc_extension_flag) {
+  if (sps->sps_scc_extension_flag) {
     DVLOG(1) << "HEVC SCC extension not supported";
     return kInvalidStream;
   }
 
-  // NOTE: The below 2 values are dependent upon the range extension if that is
-  // ever implemented.
-  sps->wp_offset_half_range_y = 1 << 7;
-  sps->wp_offset_half_range_c = 1 << 7;
+  sps->wp_offset_half_range_y = 1 << (sps->high_precision_offsets_enabled_flag
+                                          ? sps->bit_depth_luma_minus8 + 7
+                                          : 7);
+  sps->wp_offset_half_range_c = 1 << (sps->high_precision_offsets_enabled_flag
+                                          ? sps->bit_depth_chroma_minus8 + 7
+                                          : 7);
 
   // If an SPS with the same id already exists, replace it.
   *sps_id = sps->sps_seq_parameter_set_id;
@@ -808,33 +812,51 @@
   IN_RANGE_OR_RETURN(pps->log2_parallel_merge_level_minus2, 0,
                      sps->ctb_log2_size_y - 2);
   READ_BOOL_OR_RETURN(&pps->slice_segment_header_extension_present_flag);
-  bool pps_extension_present_flag;
-  READ_BOOL_OR_RETURN(&pps_extension_present_flag);
-  bool pps_range_extension_flag = false;
-  bool pps_multilayer_extension_flag = false;
-  bool pps_3d_extension_flag = false;
-  bool pps_scc_extension_flag = false;
-  if (pps_extension_present_flag) {
-    READ_BOOL_OR_RETURN(&pps_range_extension_flag);
-    READ_BOOL_OR_RETURN(&pps_multilayer_extension_flag);
-    READ_BOOL_OR_RETURN(&pps_3d_extension_flag);
-    READ_BOOL_OR_RETURN(&pps_scc_extension_flag);
+  READ_BOOL_OR_RETURN(&pps->pps_extension_present_flag);
+  if (pps->pps_extension_present_flag) {
+    READ_BOOL_OR_RETURN(&pps->pps_range_extension_flag);
+    READ_BOOL_OR_RETURN(&pps->pps_multilayer_extension_flag);
+    READ_BOOL_OR_RETURN(&pps->pps_3d_extension_flag);
+    READ_BOOL_OR_RETURN(&pps->pps_scc_extension_flag);
     SKIP_BITS_OR_RETURN(4);  // pps_extension_4bits
   }
 
-  if (pps_range_extension_flag) {
-    DVLOG(1) << "HEVC range extension not supported";
-    return kInvalidStream;
+  if (pps->pps_range_extension_flag) {
+    if (pps->transform_skip_enabled_flag) {
+      READ_UE_OR_RETURN(&pps->log2_max_transform_skip_block_size_minus2);
+      IN_RANGE_OR_RETURN(pps->log2_max_transform_skip_block_size_minus2, 0, 3);
+    }
+    READ_BOOL_OR_RETURN(&pps->cross_component_prediction_enabled_flag);
+    READ_BOOL_OR_RETURN(&pps->chroma_qp_offset_list_enabled_flag);
+    if (pps->chroma_qp_offset_list_enabled_flag) {
+      READ_UE_OR_RETURN(&pps->diff_cu_chroma_qp_offset_depth);
+      IN_RANGE_OR_RETURN(pps->diff_cu_chroma_qp_offset_depth, 0,
+                         sps->log2_diff_max_min_luma_coding_block_size);
+      READ_UE_OR_RETURN(&pps->chroma_qp_offset_list_len_minus1);
+      IN_RANGE_OR_RETURN(pps->chroma_qp_offset_list_len_minus1, 0, 5);
+      for (int i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
+        READ_SE_OR_RETURN(&pps->cb_qp_offset_list[i]);
+        IN_RANGE_OR_RETURN(pps->cb_qp_offset_list[i], -12, 12);
+        READ_SE_OR_RETURN(&pps->cr_qp_offset_list[i]);
+        IN_RANGE_OR_RETURN(pps->cr_qp_offset_list[i], -12, 12);
+      }
+    }
+    READ_UE_OR_RETURN(&pps->log2_sao_offset_scale_luma);
+    IN_RANGE_OR_RETURN(pps->log2_sao_offset_scale_luma, 0,
+                       std::max(sps->bit_depth_luma_minus8 - 2, 0));
+    READ_UE_OR_RETURN(&pps->log2_sao_offset_scale_chroma);
+    IN_RANGE_OR_RETURN(pps->log2_sao_offset_scale_chroma, 0,
+                       std::max(sps->bit_depth_chroma_minus8 - 2, 0));
   }
-  if (pps_multilayer_extension_flag) {
+  if (pps->pps_multilayer_extension_flag) {
     DVLOG(1) << "HEVC multilayer extension not supported";
     return kInvalidStream;
   }
-  if (pps_3d_extension_flag) {
+  if (pps->pps_3d_extension_flag) {
     DVLOG(1) << "HEVC 3D extension not supported";
     return kInvalidStream;
   }
-  if (pps_scc_extension_flag) {
+  if (pps->pps_scc_extension_flag) {
     DVLOG(1) << "HEVC SCC extension not supported";
     return kInvalidStream;
   }
@@ -1136,8 +1158,8 @@
 
     // pps_slice_act_qp_offsets_present_flag is zero, we don't support SCC ext.
 
-    // chroma_qp_offset_list_enabled_flag is zero, we don't support range ext.
-
+    if (pps->chroma_qp_offset_list_enabled_flag)
+      SKIP_BITS_OR_RETURN(1);  // cu_chroma_qp_offset_enabled_flag
     bool deblocking_filter_override_flag = false;
     if (pps->deblocking_filter_override_enabled_flag)
       READ_BOOL_OR_RETURN(&deblocking_filter_override_flag);
diff --git a/media/video/h265_parser.h b/media/video/h265_parser.h
index 2372a9a..0dce696 100644
--- a/media/video/h265_parser.h
+++ b/media/video/h265_parser.h
@@ -182,6 +182,22 @@
   bool strong_intra_smoothing_enabled_flag;
   H265VUIParameters vui_parameters;
 
+  // Extension extra elements.
+  bool sps_extension_present_flag;
+  bool sps_range_extension_flag;
+  bool sps_multilayer_extension_flag;
+  bool sps_3d_extension_flag;
+  bool sps_scc_extension_flag;
+  bool transform_skip_rotation_enabled_flag;
+  bool transform_skip_context_enabled_flag;
+  bool implicit_rdpcm_enabled_flag;
+  bool explicit_rdpcm_enabled_flag;
+  bool extended_precision_processing_flag;
+  bool intra_smoothing_disabled_flag;
+  bool high_precision_offsets_enabled_flag;
+  bool persistent_rice_adaptation_enabled_flag;
+  bool cabac_bypass_alignment_enabled_flag;
+
   // Calculated fields.
   int chroma_array_type;
   int sub_width_c;
@@ -254,6 +270,22 @@
   int log2_parallel_merge_level_minus2;
   bool slice_segment_header_extension_present_flag;
 
+  // Extension extra elements.
+  bool pps_extension_present_flag;
+  bool pps_range_extension_flag;
+  bool pps_multilayer_extension_flag;
+  bool pps_3d_extension_flag;
+  bool pps_scc_extension_flag;
+  int log2_max_transform_skip_block_size_minus2;
+  bool cross_component_prediction_enabled_flag;
+  bool chroma_qp_offset_list_enabled_flag;
+  int diff_cu_chroma_qp_offset_depth;
+  int chroma_qp_offset_list_len_minus1;
+  int cb_qp_offset_list[6];
+  int cr_qp_offset_list[6];
+  int log2_sao_offset_scale_luma;
+  int log2_sao_offset_scale_chroma;
+
   // Calculated fields.
   int qp_bd_offset_y;
 };
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h
index 58981a8..bb77c8c 100644
--- a/mojo/public/cpp/bindings/struct_ptr.h
+++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -14,6 +14,7 @@
 #include "base/template_util.h"
 #include "mojo/public/cpp/bindings/lib/hash_util.h"
 #include "mojo/public/cpp/bindings/type_converter.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 namespace mojo {
@@ -59,7 +60,7 @@
   }
 
   template <typename... Args>
-  StructPtr(base::in_place_t, Args&&... args)
+  StructPtr(absl::in_place_t, Args&&... args)
       : ptr_(new Struct(std::forward<Args>(args)...)) {}
 
   template <typename U>
@@ -158,7 +159,7 @@
   }
 
   template <typename... Args>
-  InlinedStructPtr(base::in_place_t, Args&&... args)
+  InlinedStructPtr(absl::in_place_t, Args&&... args)
       : value_(std::forward<Args>(args)...), state_(VALID) {}
 
   template <typename U>
diff --git a/mojo/public/java/BUILD.gn b/mojo/public/java/BUILD.gn
index e3bed29..2418fb5 100644
--- a/mojo/public/java/BUILD.gn
+++ b/mojo/public/java/BUILD.gn
@@ -21,8 +21,6 @@
     "system/src/org/chromium/mojo/system/UntypedHandle.java",
     "system/src/org/chromium/mojo/system/Watcher.java",
   ]
-
-  deps = [ "//base:base_java" ]
 }
 
 android_library("bindings_java") {
@@ -60,7 +58,6 @@
 
   deps = [
     ":system_java",
-    "//base:base_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
 
diff --git a/mojo/public/java/system/BUILD.gn b/mojo/public/java/system/BUILD.gn
index ca5f1b27..b281f94 100644
--- a/mojo/public/java/system/BUILD.gn
+++ b/mojo/public/java/system/BUILD.gn
@@ -120,7 +120,6 @@
   deps = [
     ":system_impl_java",
     ":test_support_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
@@ -167,7 +166,6 @@
   deps = [
     ":mojo_javatests",
     ":system_impl_java",
-    "//base:base_java",
     "//build/android:build_java",
     "//mojo/public/interfaces/bindings/tests:test_interfaces",
     "//mojo/public/java:bindings_java",
diff --git a/mojo/public/rust/support.cc b/mojo/public/rust/support.cc
index 1c8bdc3..2ff047c 100644
--- a/mojo/public/rust/support.cc
+++ b/mojo/public/rust/support.cc
@@ -35,24 +35,6 @@
 
 extern "C" {
 
-MojoResult MojoWait(MojoHandle handle,
-                    MojoHandleSignals signals,
-                    struct MojoHandleSignalsState* signals_state) {
-  return mojo::Wait(mojo::Handle(handle), signals, signals_state);
-}
-
-MojoResult MojoWaitMany(const MojoHandle* raw_handles,
-                        const MojoHandleSignals* signals,
-                        size_t num_handles,
-                        size_t* result_index,
-                        MojoHandleSignalsState* signals_states) {
-  std::vector<mojo::Handle> handles(num_handles);
-  for (size_t i = 0; i < handles.size(); ++i)
-    handles[i] = mojo::Handle(raw_handles[i]);
-  return mojo::WaitMany(handles.data(), signals, num_handles, result_index,
-                        signals_states);
-}
-
 MojoResult MojoCreateWaitSet(const MojoCreateWaitSetOptions*,
                              MojoWaitSetHandle* handle) {
   auto adapter = std::make_unique<WaitSetAdapter>();
diff --git a/mojo/public/rust/support.h b/mojo/public/rust/support.h
index a8194cb..94e8bf0 100644
--- a/mojo/public/rust/support.h
+++ b/mojo/public/rust/support.h
@@ -42,22 +42,6 @@
 extern "C" {
 #endif
 
-// These functions support waiting on handle signal changes, e.g. to wait for
-// a pipe to become readable. They used to be in the C API, but now the C API
-// only exposes more primitive building blocks such as traps.
-//
-// We re-implement these functions in terms of the C++ API functions.
-
-MojoResult MojoWait(MojoHandle handle,
-                    MojoHandleSignals signals,
-                    struct MojoHandleSignalsState* signals_state);
-
-MojoResult MojoWaitMany(const MojoHandle* raw_handles,
-                        const MojoHandleSignals* signals,
-                        size_t num_handles,
-                        size_t* result_index,
-                        struct MojoHandleSignalsState* signals_states);
-
 // Similar to the above, wait sets could wait for one of several handles to be
 // signalled. Unlike WaitMany they maintained a set of handles in their state.
 // They are long gone as first-class objects of the Mojo API. Previously they
diff --git a/mojo/public/rust/system/core.rs b/mojo/public/rust/system/core.rs
index 65cb7c1..0d0e56a 100644
--- a/mojo/public/rust/system/core.rs
+++ b/mojo/public/rust/system/core.rs
@@ -2,14 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use std::ptr;
-use std::vec;
-
 use crate::system::ffi;
-use crate::system::ffi::types::{MojoHandleSignals, MojoHandleSignalsState};
-// This full import is intentional; nearly every type in mojo_types needs to be used.
-use crate::system::handle;
-use crate::system::mojo_types::*;
+use crate::system::mojo_types::MojoTimeTicks;
 
 /// Get the time ticks now according to the Mojo IPC. As
 /// can be seen in the documentation for the Mojo C API,
@@ -19,44 +13,3 @@
 pub fn get_time_ticks_now() -> MojoTimeTicks {
     unsafe { ffi::MojoGetTimeTicksNow() }
 }
-
-/// Waits on many handles (or rather any structures that wrap
-/// handles) until the signals declared in 'signals' for each handle
-/// are triggered, waiting for a maximum global time of 'deadline'.
-/// This function blocks.
-pub fn wait_many(
-    handles: &[&dyn handle::Handle],
-    signals: &[HandleSignals],
-    states: &mut [SignalsState],
-) -> (isize, MojoResult) {
-    assert_eq!(handles.len(), signals.len());
-    assert!(states.len() == handles.len() || states.len() == 0);
-    let num_inputs = handles.len();
-    if num_inputs == 0 {
-        let result = MojoResult::from_code(unsafe {
-            ffi::MojoWaitMany(ptr::null(), ptr::null(), 0, ptr::null_mut(), ptr::null_mut())
-        });
-        return (-1, result);
-    }
-    let raw_states = if states.len() != 0 {
-        states.as_mut_ptr() as *mut MojoHandleSignalsState
-    } else {
-        ptr::null_mut()
-    };
-    let mut index: usize = usize::MAX;
-    let raw_signals = signals.as_ptr() as *const MojoHandleSignals;
-    let result = unsafe {
-        let mut raw_handles: vec::Vec<MojoHandle> = vec::Vec::with_capacity(num_inputs);
-        for handle in handles.iter() {
-            raw_handles.push(handle.get_native_handle())
-        }
-        MojoResult::from_code(ffi::MojoWaitMany(
-            raw_handles.as_ptr(),
-            raw_signals,
-            num_inputs,
-            &mut index as *mut usize,
-            raw_states,
-        ))
-    };
-    (index as isize, result)
-}
diff --git a/mojo/public/rust/system/ffi.rs b/mojo/public/rust/system/ffi.rs
index 9922c5082..8e4d0166 100644
--- a/mojo/public/rust/system/ffi.rs
+++ b/mojo/public/rust/system/ffi.rs
@@ -182,8 +182,6 @@
 pub use raw_ffi::MojoReadMessage;
 pub use raw_ffi::MojoRemoveTrigger;
 pub use raw_ffi::MojoUnmapBuffer;
-pub use raw_ffi::MojoWait;
-pub use raw_ffi::MojoWaitMany;
 pub use raw_ffi::MojoWaitSetAdd;
 pub use raw_ffi::MojoWaitSetRemove;
 pub use raw_ffi::MojoWaitSetWait;
diff --git a/mojo/public/rust/system/handle.rs b/mojo/public/rust/system/handle.rs
index 509fb40..c37197a 100644
--- a/mojo/public/rust/system/handle.rs
+++ b/mojo/public/rust/system/handle.rs
@@ -14,6 +14,8 @@
 //! but act much the same as untyped handles.
 
 use crate::system::ffi;
+use crate::system::wait::*;
+
 // This full import is intentional; nearly every type in mojo_types needs to be used.
 use crate::system::mojo_types::*;
 
@@ -46,12 +48,21 @@
     ///
     /// Returns the satisfied and satisfiable signals respectively for this
     /// handle when waiting is done.
-    fn wait(&self, signals: HandleSignals) -> (SignalsState, MojoResult) {
+    fn wait(&self, signals: HandleSignals) -> WaitResult {
+        wait(self.get_native_handle(), signals)
+    }
+
+    /// Gets the last known signals state of the handle. The state may change at any time during or after this call.
+    fn query_signals_state(&self) -> Result<SignalsState, MojoResult> {
         let mut state: SignalsState = Default::default();
-        let r = unsafe {
-            ffi::MojoWait(self.get_native_handle(), signals.get_bits(), &mut state.0 as *mut _)
-        };
-        (state, MojoResult::from_code(r))
+        let r = MojoResult::from_code(unsafe {
+            ffi::MojoQueryHandleSignalsState(self.get_native_handle(), state.as_raw_mut_ptr())
+        });
+
+        match r {
+            MojoResult::Okay => Ok(state),
+            r => Err(r),
+        }
     }
 }
 
diff --git a/mojo/public/rust/system/mod.rs b/mojo/public/rust/system/mod.rs
index 9ba5ef8..0b105a5 100644
--- a/mojo/public/rust/system/mod.rs
+++ b/mojo/public/rust/system/mod.rs
@@ -11,6 +11,7 @@
 pub mod message_pipe;
 pub mod shared_buffer;
 pub mod trap;
+pub mod wait;
 pub mod wait_set;
 
 // In order to keep the interface clean, we re-export basic Mojo and handle
diff --git a/mojo/public/rust/system/mojo_types.rs b/mojo/public/rust/system/mojo_types.rs
index 68a3a54..5fd009c1 100644
--- a/mojo/public/rust/system/mojo_types.rs
+++ b/mojo/public/rust/system/mojo_types.rs
@@ -193,6 +193,11 @@
     pub fn to_raw(self) -> MojoHandleSignalsState {
         self.0
     }
+
+    /// Get a pointer to the inner struct for FFI calls.
+    pub fn as_raw_mut_ptr(&mut self) -> *mut MojoHandleSignalsState {
+        &mut self.0 as *mut _
+    }
 }
 
 impl std::default::Default for SignalsState {
diff --git a/mojo/public/rust/system/wait.rs b/mojo/public/rust/system/wait.rs
new file mode 100644
index 0000000..b4ff2d5
--- /dev/null
+++ b/mojo/public/rust/system/wait.rs
@@ -0,0 +1,118 @@
+// 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.
+
+use std::sync::{Arc, Condvar, Mutex};
+
+use crate::system::mojo_types::{HandleSignals, MojoHandle, MojoResult, SignalsState};
+use crate::system::trap::{Trap, TrapEvent, TriggerCondition};
+
+/// The result of `wait`ing on a handle. There are three possible outcomes:
+///     * A requested signal was satisfied
+///     * A requested signal became unsatisfiable due to a change on the handle
+///     * The handle was closed
+#[derive(Clone, Copy, Debug)]
+pub enum WaitResult {
+    /// The handle had a signal satisfied.
+    Satisfied(SignalsState),
+    /// A requested signal became unsatisfiable for the handle.
+    Unsatisfiable(SignalsState),
+    /// The handle was closed.
+    Closed,
+}
+
+impl WaitResult {
+    /// Returns the signals state if satisfied, and an Err with the original
+    /// result otherwise.
+    pub fn satisfied(self) -> Result<SignalsState, WaitResult> {
+        match self {
+            Satisfied(s) => Ok(s),
+            _ => Err(self),
+        }
+    }
+
+    /// Returns the signals state if unsatisfiable, and an Err with the original
+    /// result otherwise.
+    pub fn unsatisfiable(self) -> Result<SignalsState, WaitResult> {
+        match self {
+            Unsatisfiable(s) => Ok(s),
+            _ => Err(self),
+        }
+    }
+
+    /// Returns the signals state if the handle wasn't closed, and an Err with
+    /// the original result otherwise.
+    pub fn signals_state(self) -> Result<SignalsState, WaitResult> {
+        match self {
+            Satisfied(s) => Ok(s),
+            Unsatisfiable(s) => Ok(s),
+            Closed => Err(self),
+        }
+    }
+}
+
+use WaitResult::*;
+
+/// Wait on `handle` until a signal in `signals` is satisfied or becomes
+/// unsatisfiable.
+#[must_use]
+pub fn wait(handle: MojoHandle, signals: HandleSignals) -> WaitResult {
+    // Mojo's mechanism for asynchronous event notification is traps: a trap
+    // object contains a handler function and a mapping of handles to
+    // interesting signals. Traps provide asynchronous notification.
+    //
+    // To implement synchronous waiting on a single handle, we use a trap along
+    // with a mutex/condvar. Our handler function simply stores the event and
+    // signals the condvar.
+    //
+    // In `wait`'s stack frame, we arm the trap then if successful wait on the
+    // mutex/condvar pair. We then process the received event.
+
+    let ctx = Arc::new(Context { signaled_event: Mutex::new(None), cond: Condvar::new() });
+
+    let handler = |event: &TrapEvent, context: &Arc<Context>| {
+        // We have no way to recover from a poisoned mutex so just unwrap.
+        let mut e = context.signaled_event.lock().unwrap();
+        *e = Some(HandleEventInfo { result: event.result(), signals_state: event.signals_state() });
+        context.cond.notify_all();
+    };
+
+    let trap = Trap::new(handler).unwrap();
+    trap.add_trigger(handle, signals, TriggerCondition::SignalsSatisfied, ctx.clone()).unwrap();
+
+    let event: HandleEventInfo = match trap.arm() {
+        MojoResult::Okay | MojoResult::FailedPrecondition => {
+            // Wait until we get a trap event callback (this should return
+            // immediately if there was a blocking event). Unwrap because we
+            // cannot recover from a poisoned mutex.
+            let event_slot: Option<HandleEventInfo> =
+                *ctx.cond.wait_while(ctx.signaled_event.lock().unwrap(), |e| e.is_none()).unwrap();
+
+            // We can unwrap because `Cond::wait_while` will only return when
+            // the condition is true (or the mutex was poisoned, but the first
+            // unwrap covers that).
+            event_slot.unwrap()
+        }
+        e => {
+            panic!("unexpected mojo error {:?}", e);
+        }
+    };
+
+    match event.result {
+        MojoResult::Okay => Satisfied(event.signals_state),
+        MojoResult::FailedPrecondition => Unsatisfiable(event.signals_state),
+        MojoResult::Cancelled => Closed,
+        e => panic!("unexpected mojo error {:?}", e),
+    }
+}
+
+#[derive(Clone, Copy, Debug)]
+struct HandleEventInfo {
+    result: MojoResult,
+    signals_state: SignalsState,
+}
+
+struct Context {
+    signaled_event: Mutex<Option<HandleEventInfo>>,
+    cond: Condvar,
+}
diff --git a/mojo/public/rust/tests/system.rs b/mojo/public/rust/tests/system.rs
index a87319fd..db7739da 100644
--- a/mojo/public/rust/tests/system.rs
+++ b/mojo/public/rust/tests/system.rs
@@ -16,8 +16,7 @@
     ArmResult, Trap, TrapEvent, TriggerCondition, UnsafeTrap, UnsafeTrapEvent,
 };
 use mojo::system::wait_set;
-use mojo::system::{self, MojoResult};
-use mojo::system::{CastHandle, Handle};
+use mojo::system::{self, CastHandle, Handle, MojoResult, SignalsState};
 
 use std::string::String;
 use std::sync::{Arc, Condvar, Mutex};
@@ -90,8 +89,7 @@
             let endpt0 = unsafe { message_pipe::MessageEndpoint::from_untyped(endpt_u) };
             assert_eq!(endpt0.get_native_handle(), endpt_h);
             {
-                let (s, r) = endpt0.wait(signals!(Signals::Writable));
-                assert_eq!(r, mojo::MojoResult::Okay);
+                let s: SignalsState = endpt0.wait(signals!(Signals::Writable)).satisfied().unwrap();
                 assert!(s.satisfied().is_writable());
                 assert!(s.satisfiable().is_readable());
                 assert!(s.satisfiable().is_writable());
@@ -105,8 +103,7 @@
             let write_result = endpt1.write(&hello, Vec::new(), mpflags!(Write::None));
             assert_eq!(write_result, mojo::MojoResult::Okay);
             {
-                let (s, r) = endpt0.wait(signals!(Signals::Readable));
-                assert_eq!(r, mojo::MojoResult::Okay);
+                let s: SignalsState = endpt0.wait(signals!(Signals::Readable)).satisfied().unwrap();
                 assert!(s.satisfied().is_readable());
                 assert!(s.satisfied().is_writable());
                 assert!(s.satisfiable().is_readable());
@@ -120,8 +117,7 @@
             }
             assert_eq!(String::from_utf8(hello_data).unwrap(), "hello".to_string());
         }
-        let (s, r) = endpt1.wait(signals!(Signals::Readable, Signals::Writable));
-        assert_eq!(r, mojo::MojoResult::FailedPrecondition);
+        let s: SignalsState = endpt1.wait(signals!(Signals::Readable, Signals::Writable)).unsatisfiable().unwrap();
         assert!(s.satisfied().is_peer_closed());
         // For some reason QuotaExceeded is also set. TOOD(collinbaker): investigate.
         assert!(s.satisfiable().get_bits() & (system::Signals::PeerClosed as u32) > 0);
@@ -142,20 +138,14 @@
         assert_eq!(cons.get_native_handle(), cons_h);
         assert_eq!(prod.get_native_handle(), prod_h);
         // Test waiting on producer
-        {
-            let (_s, r) = prod.wait(signals!(Signals::Writable));
-            assert_eq!(r, mojo::MojoResult::Okay);
-        }
+        prod.wait(signals!(Signals::Writable)).satisfied().unwrap();
         // Test one-phase read/write.
         // Writing.
         let hello = "hello".to_string().into_bytes();
         let bytes_written = prod.write(&hello, dpflags!(Write::None)).unwrap();
         assert_eq!(bytes_written, hello.len());
         // Reading.
-        {
-            let (_s, r) = cons.wait(signals!(Signals::Readable));
-            assert_eq!(r, mojo::MojoResult::Okay);
-        }
+        cons.wait(signals!(Signals::Readable)).satisfied().unwrap();
         let data_string = String::from_utf8(cons.read(dpflags!(Read::None)).unwrap()).unwrap();
         assert_eq!(data_string, "hello".to_string());
         {
@@ -175,10 +165,7 @@
                 None => (),
             }
             // Reading.
-            {
-                let (_s, r) = cons.wait(signals!(Signals::Readable));
-                assert_eq!(r, mojo::MojoResult::Okay);
-            }
+            cons.wait(signals!(Signals::Readable)).satisfied().unwrap();
             let mut data_goodbye: Vec<u8> = Vec::with_capacity(goodbye.len());
             {
                 let read_buf = match cons.begin() {
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
index 1652da7..2dc1d78 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -23,7 +23,7 @@
   template <typename... Args>
   static {{struct.name}}Ptr New(Args&&... args) {
     return {{struct.name}}Ptr(
-        base::in_place, std::forward<Args>(args)...);
+        absl::in_place, std::forward<Args>(args)...);
   }
 
   template <typename U>
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
index 6cef4290..f4c0aa9 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
@@ -12,7 +12,7 @@
   static {{union.name}}Ptr
   New{{field.name|under_to_camel}}(
       {{field.kind|cpp_wrapper_param_type_new}} {{field.name}}) {
-    auto result = {{union.name}}Ptr(base::in_place);
+    auto result = {{union.name}}Ptr(absl::in_place);
     result->set_{{field.name}}(std::move({{field.name}}));
     return result;
   }
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni
index a9fd563..3846125 100644
--- a/mojo/public/tools/bindings/mojom.gni
+++ b/mojo/public/tools/bindings/mojom.gni
@@ -1661,7 +1661,6 @@
       android_library(java_target_name) {
         forward_variables_from(invoker, [ "enable_bytecode_checks" ])
         deps = [
-          "//base:base_java",
           "//mojo/public/java:bindings_java",
           "//mojo/public/java:system_java",
           "//third_party/androidx:androidx_annotation_annotation_java",
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index 50b21b6..9a29c10 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -152,7 +152,6 @@
   deps = [
     ":net_java_test_support",
     ":net_java_test_support_provider",
-    "//base:base_java",
     "//build/android:build_java",
   ]
   android_manifest = "../test/android/javatests/AndroidManifest.xml"
diff --git a/net/socket/transport_connect_job.cc b/net/socket/transport_connect_job.cc
index b8f92f28..196b5ba 100644
--- a/net/socket/transport_connect_job.cc
+++ b/net/socket/transport_connect_job.cc
@@ -120,19 +120,6 @@
                                                params, delegate, net_log);
 }
 
-// TODO(eroman): The use of this constant needs to be re-evaluated. The time
-// needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since
-// the address list may contain many alternatives, and most of those may
-// timeout. Even worse, the per-connect timeout threshold varies greatly
-// between systems (anywhere from 20 seconds to 190 seconds).
-// See comment #12 at http://crbug.com/23364 for specifics.
-const int TransportConnectJob::kTimeoutInSeconds = 240;  // 4 minutes.
-
-// TODO(willchan): Base this off RTT instead of statically setting it. Note we
-// choose a timeout that is different from the backup connect job timer so they
-// don't synchronize.
-const int TransportConnectJob::kIPv6FallbackTimerInMs = 300;
-
 std::unique_ptr<ConnectJob> TransportConnectJob::CreateTransportConnectJob(
     scoped_refptr<TransportSocketParams> transport_client_params,
     RequestPriority priority,
@@ -268,7 +255,13 @@
 
 // static
 base::TimeDelta TransportConnectJob::ConnectionTimeout() {
-  return base::Seconds(TransportConnectJob::kTimeoutInSeconds);
+  // TODO(eroman): The use of this constant needs to be re-evaluated. The time
+  // needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since
+  // the address list may contain many alternatives, and most of those may
+  // timeout. Even worse, the per-connect timeout threshold varies greatly
+  // between systems (anywhere from 20 seconds to 190 seconds).
+  // See comment #12 at http://crbug.com/23364 for specifics.
+  return base::Minutes(4);
 }
 
 void TransportConnectJob::OnIOComplete(int result) {
@@ -455,8 +448,7 @@
   int rv = transport_socket_->Connect(base::BindOnce(
       &TransportConnectJob::OnIOComplete, base::Unretained(this)));
   if (rv == ERR_IO_PENDING && try_ipv6_connect_with_ipv4_fallback) {
-    fallback_timer_.Start(FROM_HERE, base::Milliseconds(kIPv6FallbackTimerInMs),
-                          this,
+    fallback_timer_.Start(FROM_HERE, kIPv6FallbackTime, this,
                           &TransportConnectJob::OnIPv6FallbackTimerComplete);
   }
   return rv;
diff --git a/net/socket/transport_connect_job.h b/net/socket/transport_connect_job.h
index 78ef7bf70..a2a06b3 100644
--- a/net/socket/transport_connect_job.h
+++ b/net/socket/transport_connect_job.h
@@ -89,7 +89,7 @@
 // logic for IPv6 connect() timeouts (which may happen due to networks / routers
 // with broken IPv6 support). Those timeouts take 20s, so rather than make the
 // user wait 20s for the timeout to fire, we use a fallback timer
-// (kIPv6FallbackTimerInMs) and start a connect() to a IPv4 address if the timer
+// (kIPv6FallbackTime) and start a connect() to a IPv4 address if the timer
 // fires. Then we race the IPv4 connect() against the IPv6 connect() (which has
 // a headstart) and return the one that completes first to the socket pool.
 class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob {
@@ -108,14 +108,14 @@
         const NetLogWithSource* net_log);
   };
 
-  // TransportConnectJobs will time out after this many seconds.  Note this is
-  // the total time, including both host resolution and TCP connect() times.
-  static const int kTimeoutInSeconds;
-
   // In cases where both IPv6 and IPv4 addresses were returned from DNS,
   // TransportConnectJobs will start a second connection attempt to just the
-  // IPv4 addresses after this many milliseconds. (This is "Happy Eyeballs".)
-  static const int kIPv6FallbackTimerInMs;
+  // IPv4 addresses after this much time. (This is "Happy Eyeballs".)
+  //
+  // TODO(willchan): Base this off RTT instead of statically setting it. Note we
+  // choose a timeout that is different from the backup connect job timer so
+  // they don't synchronize.
+  static constexpr base::TimeDelta kIPv6FallbackTime = base::Milliseconds(300);
 
   // Creates a TransportConnectJob or WebSocketTransportConnectJob, depending on
   // whether or not |common_connect_job_params.web_socket_endpoint_lock_manager|
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index 604818d..c866e0a 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -390,8 +390,8 @@
                       IPEndPoint(ParseIP("2:abcd::3:4:ff"), 80)})};
 
   client_socket_factory_.SetRules(rules);
-  client_socket_factory_.set_delay(
-      base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs + 50));
+  client_socket_factory_.set_delay(TransportConnectJob::kIPv6FallbackTime +
+                                   base::Milliseconds(50));
 
   // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
   host_resolver_.rules()->AddIPLiteralRule(kHostName, "2:abcd::3:4:ff,2.2.2.2",
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 3139013a..78c9136 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -649,8 +649,8 @@
           MockTransportClientSocketFactory::Type::kStalled)};
 
   client_socket_factory_.SetRules(rules);
-  client_socket_factory_.set_delay(
-      base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs + 50));
+  client_socket_factory_.set_delay(TransportConnectJob::kIPv6FallbackTime +
+                                   base::Milliseconds(50));
 
   // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
   host_resolver_->rules()->AddIPLiteralRule(
@@ -800,7 +800,7 @@
   base::TimeTicks start(base::TimeTicks::Now());
   EXPECT_THAT(callback.WaitForResult(), IsOk());
   EXPECT_LT(base::TimeTicks::Now() - start,
-            base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs));
+            TransportConnectJob::kIPv6FallbackTime);
   ASSERT_TRUE(handle.socket());
 
   IPEndPoint endpoint;
@@ -849,8 +849,7 @@
 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
   client_socket_factory_.set_default_client_socket_type(
       MockTransportClientSocketFactory::Type::kDelayedFailing);
-  base::TimeDelta delay =
-      base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs / 3);
+  base::TimeDelta delay = TransportConnectJob::kIPv6FallbackTime / 3;
   client_socket_factory_.set_delay(delay);
 
   // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
@@ -1160,8 +1159,7 @@
   }
   // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
   // are started yet.
-  RunLoopForTimePeriod(
-      base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs));
+  RunLoopForTimePeriod(TransportConnectJob::kIPv6FallbackTime);
   // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
   // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
   pool_.FlushWithError(ERR_FAILED, "Very good reason");
diff --git a/net/socket/websocket_transport_connect_job.cc b/net/socket/websocket_transport_connect_job.cc
index 46a94130..e0bf16d 100644
--- a/net/socket/websocket_transport_connect_job.cc
+++ b/net/socket/websocket_transport_connect_job.cc
@@ -242,8 +242,7 @@
       // This use of base::Unretained is safe because |fallback_timer_| is
       // owned by this object.
       fallback_timer_.Start(
-          FROM_HERE,
-          base::Milliseconds(TransportConnectJob::kIPv6FallbackTimerInMs),
+          FROM_HERE, TransportConnectJob::kIPv6FallbackTime,
           base::BindOnce(&WebSocketTransportConnectJob::StartIPv4JobAsync,
                          base::Unretained(this)));
     }
diff --git a/net/socket/websocket_transport_connect_job.h b/net/socket/websocket_transport_connect_job.h
index 5fc0aa2..8243cb0 100644
--- a/net/socket/websocket_transport_connect_job.h
+++ b/net/socket/websocket_transport_connect_job.h
@@ -27,7 +27,7 @@
 // logic for IPv6 connect() timeouts (which may happen due to networks / routers
 // with broken IPv6 support). Those timeouts take 20s, so rather than make the
 // user wait 20s for the timeout to fire, we use a fallback timer
-// (kIPv6FallbackTimerInMs) and start a connect() to an IPv4 address if the
+// (kIPv6FallbackTime) and start a connect() to an IPv4 address if the
 // timer fires. Then we race the IPv4 connect(s) against the IPv6 connect(s) and
 // use the socket that completes successfully first or fails last.
 //
@@ -118,8 +118,8 @@
 
   // The addresses are divided into IPv4 and IPv6, which are performed partially
   // in parallel. If the list of IPv6 addresses is non-empty, then the IPv6 jobs
-  // go first, followed after |kIPv6FallbackTimerInMs| by the IPv4
-  // addresses. First sub-job to establish a connection wins.
+  // go first, followed after |kIPv6FallbackTime| by the IPv4 addresses. First
+  // sub-job to establish a connection wins.
   std::unique_ptr<WebSocketTransportConnectSubJob> ipv4_job_;
   std::unique_ptr<WebSocketTransportConnectSubJob> ipv6_job_;
 
diff --git a/remoting/codec/BUILD.gn b/remoting/codec/BUILD.gn
index 5a6ea17ee..0a5b264 100644
--- a/remoting/codec/BUILD.gn
+++ b/remoting/codec/BUILD.gn
@@ -64,14 +64,10 @@
     sources += [
       "audio_encoder_opus.cc",
       "audio_encoder_opus.h",
-      "cast_software_video_encoder_adapter.cc",
-      "cast_software_video_encoder_adapter.h",
     ]
     deps += [
       "//media",
       "//media:shared_memory_support",
-      "//media/cast:common",
-      "//media/cast:encoding",
     ]
   }
 }
diff --git a/remoting/codec/DEPS b/remoting/codec/DEPS
index 9e88118..bce883b 100644
--- a/remoting/codec/DEPS
+++ b/remoting/codec/DEPS
@@ -7,7 +7,6 @@
   "+third_party/webrtc",
   "+gpu/config/gpu_driver_bug_workarounds.h",
   "+gpu/config/gpu_preferences.h",
-  "+media/cast",
   "+media/video",
   "+media/gpu",
   "+ui/gfx/geometry",
diff --git a/remoting/codec/cast_software_video_encoder_adapter.cc b/remoting/codec/cast_software_video_encoder_adapter.cc
deleted file mode 100644
index 66ec2d1..0000000
--- a/remoting/codec/cast_software_video_encoder_adapter.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "remoting/codec/cast_software_video_encoder_adapter.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/check.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_types.h"
-#include "media/cast/common/sender_encoded_frame.h"
-#include "media/cast/encoding/software_video_encoder.h"
-#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace remoting {
-
-CastSoftwareVideoEncoderAdapter::CastSoftwareVideoEncoderAdapter(
-    std::unique_ptr<media::cast::SoftwareVideoEncoder> encoder,
-    webrtc::VideoCodecType codec)
-    : encoder_(std::move(encoder)),
-      codec_(codec) {
-  DCHECK(encoder_);
-}
-
-CastSoftwareVideoEncoderAdapter::~CastSoftwareVideoEncoderAdapter() = default;
-
-void CastSoftwareVideoEncoderAdapter::Encode(
-    std::unique_ptr<webrtc::DesktopFrame> frame,
-    const FrameParams& params,
-    EncodeCallback done) {
-  const base::TimeTicks current_time = base::TimeTicks::Now();
-  if (start_timestamp_.is_null()) {
-    encoder_->Initialize();
-    start_timestamp_ = current_time;
-  }
-
-  if (params.key_frame) {
-    encoder_->GenerateKeyFrame();
-  }
-  if (params.bitrate_kbps > 0) {
-    encoder_->UpdateRates(params.bitrate_kbps * 1000);
-  }
-
-  media::cast::SenderEncodedFrame encoded_frame;
-  encoder_->Encode(CreateVideoFrame(*frame),
-                   current_time,
-                   &encoded_frame);
-  std::move(done).Run(EncodeResult::SUCCEEDED,
-                      CreateEncodedFrame(*frame, std::move(encoded_frame)));
-}
-
-scoped_refptr<media::VideoFrame>
-CastSoftwareVideoEncoderAdapter::CreateVideoFrame(
-    const webrtc::DesktopFrame& frame) const {
-  DCHECK(!start_timestamp_.is_null());
-  // TODO(zijiehe): According to http://crbug.com/555909, this does not work
-  // now, media::VideoFrame::WrapExternalData() accepts only I420 or Y16.
-  return media::VideoFrame::WrapExternalData(
-      media::PIXEL_FORMAT_ARGB,
-      gfx::Size(frame.stride() / webrtc::DesktopFrame::kBytesPerPixel,
-                frame.size().height()),
-      gfx::Rect(frame.size().width(), frame.size().height()),
-      gfx::Size(frame.size().width(), frame.size().height()),
-      frame.data(),
-      frame.stride() * frame.size().height(),
-      base::TimeTicks::Now() - start_timestamp_);
-}
-
-std::unique_ptr<CastSoftwareVideoEncoderAdapter::EncodedFrame>
-CastSoftwareVideoEncoderAdapter::CreateEncodedFrame(
-    const webrtc::DesktopFrame& frame,
-    media::cast::SenderEncodedFrame&& media_frame) const {
-  std::unique_ptr<EncodedFrame> result = std::make_unique<EncodedFrame>();
-  result->size = frame.size();
-  // TODO(zijiehe): Should INDEPENDENT frames also be considered as key frames?
-  result->key_frame =
-      media_frame.dependency == media::cast::EncodedFrame::KEY;
-  // TODO(zijiehe): Forward quantizer from media::cast::SoftwareVideoEncoder.
-  // Currently we set this value to INT32_MAX to always trigger top-off.
-  result->quantizer = INT32_MAX;
-  result->codec = codec_;
-  result->data = std::move(media_frame.data);
-  return result;
-}
-
-}  // namespace remoting
diff --git a/remoting/codec/cast_software_video_encoder_adapter.h b/remoting/codec/cast_software_video_encoder_adapter.h
deleted file mode 100644
index 59becb5..0000000
--- a/remoting/codec/cast_software_video_encoder_adapter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef REMOTING_CODEC_CAST_SOFTWARE_VIDEO_ENCODER_ADAPTER_H_
-#define REMOTING_CODEC_CAST_SOFTWARE_VIDEO_ENCODER_ADAPTER_H_
-
-#include <memory>
-
-#include "base/memory/scoped_refptr.h"
-#include "base/time/time.h"
-#include "remoting/codec/webrtc_video_encoder.h"
-
-namespace media {
-class VideoFrame;
-namespace cast {
-struct SenderEncodedFrame;
-class SoftwareVideoEncoder;
-}  // namespace cast
-}  // namespace media
-
-namespace webrtc {
-class DesktopFrame;
-}  // namespace webrtc
-
-namespace remoting {
-
-// Implements WebrtcVideoEncoder by using a media::cast::SoftwareVideoEncoder.
-class CastSoftwareVideoEncoderAdapter final : public WebrtcVideoEncoder {
- public:
-  CastSoftwareVideoEncoderAdapter(
-      std::unique_ptr<media::cast::SoftwareVideoEncoder> encoder,
-      webrtc::VideoCodecType codec);
-  ~CastSoftwareVideoEncoderAdapter() override;
-
-  void Encode(std::unique_ptr<webrtc::DesktopFrame> frame,
-              const FrameParams& param,
-              EncodeCallback done) override;
-
- private:
-  scoped_refptr<media::VideoFrame> CreateVideoFrame(
-      const webrtc::DesktopFrame& frame) const;
-  std::unique_ptr<EncodedFrame> CreateEncodedFrame(
-      const webrtc::DesktopFrame& frame,
-      media::cast::SenderEncodedFrame&& media_frame) const;
-
-  const std::unique_ptr<media::cast::SoftwareVideoEncoder> encoder_;
-  const webrtc::VideoCodecType codec_;
-  // The timestamp of the first Encode() function call. is_null() also indicates
-  // that this instance is not initialized.
-  base::TimeTicks start_timestamp_;
-};
-
-}  // namespace remoting
-
-#endif  // REMOTING_CODEC_CAST_SOFTWARE_VIDEO_ENCODER_ADAPTER_H_
diff --git a/remoting/codec/webrtc_video_encoder_vpx.cc b/remoting/codec/webrtc_video_encoder_vpx.cc
index 010a6e9a..facc0ee 100644
--- a/remoting/codec/webrtc_video_encoder_vpx.cc
+++ b/remoting/codec/webrtc_video_encoder_vpx.cc
@@ -145,6 +145,10 @@
     vpx_codec_control(codec, VP9E_SET_ROW_MT, 1);
   }
 
+  // The param for this knob is a log2 value so 0 is reasonable here.
+  vpx_codec_control(codec, VP9E_SET_TILE_COLUMNS,
+                    static_cast<int>(codec->config.enc->g_threads >> 1));
+
   // Use the lowest level of noise sensitivity so as to spend less time
   // on motion estimation and inter-prediction mode.
   ret = vpx_codec_control(codec, VP9E_SET_NOISE_SENSITIVITY, 0);
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index 8fa20feb..0df13df 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -589,6 +589,7 @@
     ]
     frameworks = [
       "Accelerate.framework",
+      "AudioToolbox.framework",
       "Carbon.framework",
       "CoreAudio.framework",
     ]
diff --git a/remoting/host/installer/linux/BUILD.gn b/remoting/host/installer/linux/BUILD.gn
index 27c3039..7301f6b 100644
--- a/remoting/host/installer/linux/BUILD.gn
+++ b/remoting/host/installer/linux/BUILD.gn
@@ -5,7 +5,6 @@
 import("//build/config/zip.gni")
 import("//remoting/build/config/remoting_build.gni")
 import("//remoting/remoting_locales.gni")
-import("//remoting/remoting_options.gni")
 
 build_deb_script = "build_deb.py"
 deb_filename =
@@ -63,7 +62,6 @@
     # Files to be packaged into the deb.
     "//remoting/host/installer/linux/Xsession",
     "//remoting/host/installer/linux/chrome-remote-desktop@.service",
-    "//remoting/host/installer/linux/chrome-remote-desktop-wayland@.service",
     "//remoting/host/installer/linux/is-remoting-session",
     "//remoting/host/linux/configure_url_forwarder.py",
     "//remoting/host/linux/linux_me2me_host.py",
@@ -97,9 +95,6 @@
     "-o",
     ".",
   ]
-  if (remoting_use_wayland) {
-    args += [ "-remoting_use_wayland" ]
-  }
 
   deps = [
     "//remoting/host:remoting_core",
diff --git a/remoting/host/installer/linux/Makefile b/remoting/host/installer/linux/Makefile
index 62c3ac6..77a06e7 100644
--- a/remoting/host/installer/linux/Makefile
+++ b/remoting/host/installer/linux/Makefile
@@ -120,18 +120,9 @@
 	    "$(INSTALL_DIR)/remoting_locales/$$locale"; \
 	done
 
-	echo "Current working dir: $(shell pwd)"
-	echo "Found env:\n$(shell env)"
-
-	if [ $(shell echo ${REMOTING_USE_WAYLAND}) == "true" ]; then \
-	install -m 0644 \
-	  "$(SRC_DIR)/remoting/host/installer/linux/chrome-remote-desktop-wayland@.service" \
-	  "$(SYSTEMD_UNIT_DIR)/chrome-remote-desktop@.service"; \
-	else \
 	install -m 0644 \
 	  "$(SRC_DIR)/remoting/host/installer/linux/chrome-remote-desktop@.service" \
-	  "$(SYSTEMD_UNIT_DIR)/chrome-remote-desktop@.service"; \
-	fi
+	  "$(SYSTEMD_UNIT_DIR)/chrome-remote-desktop@.service"
 
 	# Mask the SysV-style init script under systemd so both don't end up enabled.
 	ln -s /dev/null "$(SYSTEMD_UNIT_DIR)/chrome-remote-desktop.service"
diff --git a/remoting/host/installer/linux/build_deb.py b/remoting/host/installer/linux/build_deb.py
index cd44af9..62c9e965 100644
--- a/remoting/host/installer/linux/build_deb.py
+++ b/remoting/host/installer/linux/build_deb.py
@@ -11,16 +11,8 @@
 def main():
   this_dir = os.path.dirname(os.path.abspath(__file__))
   build_deb_script = os.path.join(this_dir, 'build-deb.sh')
-  if ("-remoting_use_wayland" in sys.argv):
-    proc_env = os.environ.copy()
-    proc_env["REMOTING_USE_WAYLAND"] = "true"
-    # This is expected to be the last argument and is not forwarded to the shell
-    # script.
-    proc = subprocess.Popen([build_deb_script] + sys.argv[1:-1],
-                            stdout=subprocess.PIPE, env=proc_env)
-  else:
-    proc = subprocess.Popen([build_deb_script] + sys.argv[1:],
-                            stdout=subprocess.PIPE)
+  proc = subprocess.Popen([build_deb_script] + sys.argv[1:],
+                          stdout=subprocess.PIPE)
   out, _ = proc.communicate()
   sys.stdout.write(out.decode('utf8').strip())
   return proc.returncode
diff --git a/remoting/host/installer/linux/chrome-remote-desktop-wayland@.service b/remoting/host/installer/linux/chrome-remote-desktop-wayland@.service
deleted file mode 100644
index cde711e..0000000
--- a/remoting/host/installer/linux/chrome-remote-desktop-wayland@.service
+++ /dev/null
@@ -1,21 +0,0 @@
-[Unit]
-Description=Chrome Remote Desktop instance for %I
-After=network.target
-
-[Service]
-Type=simple
-User=%I
-Environment=XDG_SESSION_CLASS=user XDG_SESSION_TYPE=wayland
-PAMName=chrome-remote-desktop
-ExecStart=/opt/google/chrome-remote-desktop/chrome-remote-desktop --start --new-session --is-wayland
-ExecReload=/opt/google/chrome-remote-desktop/chrome-remote-desktop --reload
-ExecStop=/opt/google/chrome-remote-desktop/chrome-remote-desktop --stop
-# Log output to the journal
-StandardOutput=journal
-# Use same fd as stdout
-StandardError=inherit
-# Must be kept in sync with RELAUNCH_EXIT_CODE in linux_me2me_host.py
-RestartForceExitStatus=41
-
-[Install]
-WantedBy=multi-user.target
diff --git a/remoting/host/linux/remote_desktop_portal.cc b/remoting/host/linux/remote_desktop_portal.cc
index ab7b41c6..55e6dfa 100644
--- a/remoting/host/linux/remote_desktop_portal.cc
+++ b/remoting/host/linux/remote_desktop_portal.cc
@@ -98,7 +98,7 @@
   // screencast portal to go into either failed/succeeded state before stopping
   // our loop.
   while (context_ && screencast_portal_status_ == RequestResponse::kUnknown) {
-    g_main_context_iteration(context_, /*may_block=*/false);
+    g_main_context_iteration(context_, /*may_block=*/true);
   }
   if (context_) {
     g_main_context_pop_thread_default(context_);
diff --git a/remoting/host/remote_open_url/BUILD.gn b/remoting/host/remote_open_url/BUILD.gn
index 9cbddef..10cc4e32 100644
--- a/remoting/host/remote_open_url/BUILD.gn
+++ b/remoting/host/remote_open_url/BUILD.gn
@@ -21,7 +21,6 @@
   ]
 
   deps = [
-    "//base",
     "//mojo/public/cpp/bindings",
     "//mojo/public/cpp/platform",
     "//mojo/public/cpp/system",
@@ -36,7 +35,10 @@
     "//ui/base",
   ]
 
-  public_deps = [ "//remoting/proto" ]
+  public_deps = [
+    "//base",
+    "//remoting/proto",
+  ]
 
   if (is_linux) {
     sources += [
diff --git a/services/audio/input_stream.cc b/services/audio/input_stream.cc
index eecc67cf..0ace63f1 100644
--- a/services/audio/input_stream.cc
+++ b/services/audio/input_stream.cc
@@ -22,6 +22,7 @@
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "services/audio/input_sync_writer.h"
 #include "services/audio/user_input_monitor.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace audio {
 
@@ -227,7 +228,7 @@
   DCHECK(socket_handle.is_valid());
 
   std::move(created_callback_)
-      .Run({base::in_place, std::move(shared_memory_region),
+      .Run({absl::in_place, std::move(shared_memory_region),
             std::move(socket_handle)},
            initially_muted, id_);
 }
diff --git a/services/audio/loopback_stream.cc b/services/audio/loopback_stream.cc
index e905c954..415ef09 100644
--- a/services/audio/loopback_stream.cc
+++ b/services/audio/loopback_stream.cc
@@ -17,6 +17,7 @@
 #include "media/base/vector_math.h"
 #include "mojo/public/cpp/system/buffer.h"
 #include "mojo/public/cpp/system/platform_handle.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace audio {
 
@@ -78,7 +79,7 @@
       socket_handle = mojo::PlatformHandle(foreign_socket.Take());
       if (socket_handle.is_valid()) {
         std::move(created_callback)
-            .Run({base::in_place, std::move(shared_memory_region),
+            .Run({absl::in_place, std::move(shared_memory_region),
                   std::move(socket_handle)});
         network_.reset(new FlowNetwork(std::move(flow_task_runner), params,
                                        std::move(writer)));
diff --git a/services/audio/output_stream.cc b/services/audio/output_stream.cc
index e41fbd3..d4ccbcf 100644
--- a/services/audio/output_stream.cc
+++ b/services/audio/output_stream.cc
@@ -12,6 +12,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/trace_event/trace_event.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace audio {
 
@@ -183,7 +184,7 @@
   }
 
   std::move(created_callback)
-      .Run({base::in_place, std::move(shared_memory_region),
+      .Run({absl::in_place, std::move(shared_memory_region),
             std::move(socket_handle)});
 }
 
diff --git a/services/audio/public/cpp/input_ipc_unittest.cc b/services/audio/public/cpp/input_ipc_unittest.cc
index ddf39b2..5d994c3 100644
--- a/services/audio/public/cpp/input_ipc_unittest.cc
+++ b/services/audio/public/cpp/input_ipc_unittest.cc
@@ -19,6 +19,7 @@
 #include "services/audio/public/cpp/fake_stream_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using testing::_;
 using testing::StrictMock;
@@ -70,7 +71,7 @@
     base::SyncSocket socket1, socket2;
     base::SyncSocket::CreatePair(&socket1, &socket2);
     std::move(created_callback)
-        .Run({base::in_place,
+        .Run({absl::in_place,
               base::ReadOnlySharedMemoryRegion::Create(kShMemSize).region,
               mojo::PlatformHandle(socket1.Take())},
              initially_muted_, base::UnguessableToken::Create());
diff --git a/services/audio/public/cpp/output_device_unittest.cc b/services/audio/public/cpp/output_device_unittest.cc
index 2433168..dd6f534 100644
--- a/services/audio/public/cpp/output_device_unittest.cc
+++ b/services/audio/public/cpp/output_device_unittest.cc
@@ -22,6 +22,7 @@
 #include "services/audio/sync_reader.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using testing::_;
 using testing::Invoke;
@@ -224,7 +225,7 @@
   task_env_.RunUntilIdle();
 
   std::move(stream_factory_->created_callback_)
-      .Run({base::in_place, env.reader->TakeSharedMemoryRegion(),
+      .Run({absl::in_place, env.reader->TakeSharedMemoryRegion(),
             mojo::PlatformHandle(env.client_socket.Take())});
   task_env_.RunUntilIdle();
 
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn
index 3fdbbbd..949297d 100644
--- a/services/device/BUILD.gn
+++ b/services/device/BUILD.gn
@@ -445,7 +445,6 @@
       "android/java/src/org/chromium/services/device/InterfaceRegistrar.java",
     ]
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//mojo/public/java:bindings_java",
       "//mojo/public/java:system_java",
diff --git a/services/device/fingerprint/fingerprint_chromeos.cc b/services/device/fingerprint/fingerprint_chromeos.cc
index 080ab92f..cb7795f4 100644
--- a/services/device/fingerprint/fingerprint_chromeos.cc
+++ b/services/device/fingerprint/fingerprint_chromeos.cc
@@ -14,6 +14,7 @@
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "services/device/fingerprint/fingerprint.h"
 #include "services/device/public/mojom/fingerprint.mojom.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace device {
 
@@ -289,7 +290,7 @@
 
   for (auto& observer : observers_) {
     observer->OnAuthScanDone(
-        {base::in_place, converted_msg},
+        {absl::in_place, converted_msg},
         // TODO(patrykd): Construct the map at the beginning of this function.
         base::flat_map<std::string, std::vector<std::string>>(entries));
   }
diff --git a/services/device/public/java/BUILD.gn b/services/device/public/java/BUILD.gn
index aa07a5e..5f4eaee 100644
--- a/services/device/public/java/BUILD.gn
+++ b/services/device/public/java/BUILD.gn
@@ -32,7 +32,6 @@
   ]
   deps = [
     ":geolocation_java",
-    "//base:base_java",
     "//build/android:build_java",
 
     # Ideally this dependency should be removed. http://crbug.com/850357
diff --git a/services/device/wake_lock/power_save_blocker/BUILD.gn b/services/device/wake_lock/power_save_blocker/BUILD.gn
index 2db7846..d80eb98 100644
--- a/services/device/wake_lock/power_save_blocker/BUILD.gn
+++ b/services/device/wake_lock/power_save_blocker/BUILD.gn
@@ -96,9 +96,6 @@
       "//services/device:*",
     ]
     sources = java_sources_needing_jni
-    deps = [
-      "//base:base_java",
-      "//base:jni_java",
-    ]
+    deps = [ "//base:jni_java" ]
   }
 }
diff --git a/services/media_session/public/cpp/android/BUILD.gn b/services/media_session/public/cpp/android/BUILD.gn
index bce79393..37400cc 100644
--- a/services/media_session/public/cpp/android/BUILD.gn
+++ b/services/media_session/public/cpp/android/BUILD.gn
@@ -17,7 +17,6 @@
 if (current_toolchain == default_toolchain) {
   android_library("media_session_java") {
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//url:gurl_java",
diff --git a/services/network/sct_auditing/sct_auditing_cache_unittest.cc b/services/network/sct_auditing/sct_auditing_cache_unittest.cc
index ec119be..d12a130 100644
--- a/services/network/sct_auditing/sct_auditing_cache_unittest.cc
+++ b/services/network/sct_auditing/sct_auditing_cache_unittest.cc
@@ -25,6 +25,7 @@
 #include "services/network/sct_auditing/sct_auditing_reporter.h"
 #include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/boringssl/src/include/openssl/pool.h"
 #include "third_party/boringssl/src/include/openssl/sha.h"
 
@@ -49,7 +50,7 @@
  protected:
   // Initializes the configuration for the SCTAuditingCache to defaults.
   void InitSCTAuditing(SCTAuditingCache* cache, double sampling_rate = 1.0) {
-    mojom::SCTAuditingConfigurationPtr configuration(base::in_place);
+    mojom::SCTAuditingConfigurationPtr configuration(absl::in_place);
     configuration->sampling_rate = sampling_rate;
     configuration->traffic_annotation =
         net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
diff --git a/services/network/sct_auditing/sct_auditing_handler_unittest.cc b/services/network/sct_auditing/sct_auditing_handler_unittest.cc
index 1c510f9..fd184a2 100644
--- a/services/network/sct_auditing/sct_auditing_handler_unittest.cc
+++ b/services/network/sct_auditing/sct_auditing_handler_unittest.cc
@@ -36,6 +36,7 @@
 #include "services/network/test/test_utils.h"
 #include "services/network/url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace network {
 
@@ -81,7 +82,7 @@
         std::move(context_params));
 
     // Set up fake CT logs.
-    mojom::CTLogInfoPtr log(base::in_place);
+    mojom::CTLogInfoPtr log(absl::in_place);
     log->id = kTestLogIdAsString;
     log->mmd = kTestLogMMD;
     std::vector<mojom::CTLogInfoPtr> log_list;
@@ -101,7 +102,7 @@
 
     // Set up SCT auditing configuration.
     auto* cache = network_service_->sct_auditing_cache();
-    mojom::SCTAuditingConfigurationPtr configuration(base::in_place);
+    mojom::SCTAuditingConfigurationPtr configuration(absl::in_place);
     configuration->sampling_rate = 1.0;
     configuration->report_uri = GURL("https://example.test");
     configuration->traffic_annotation =
diff --git a/services/network/sct_auditing/sct_auditing_reporter_unittest.cc b/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
index b1acfcc..14b55e15 100644
--- a/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
+++ b/services/network/sct_auditing/sct_auditing_reporter_unittest.cc
@@ -26,6 +26,7 @@
 #include "services/network/test/test_url_loader_factory.h"
 #include "services/network/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 namespace network {
 
@@ -114,7 +115,7 @@
     SCTAuditingReporter::SCTHashdanceMetadata metadata =
         *SCTAuditingReporter::SCTHashdanceMetadata::FromValue(
             reporter_metadata_.ToValue());
-    mojom::SCTAuditingConfigurationPtr configuration(base::in_place);
+    mojom::SCTAuditingConfigurationPtr configuration(absl::in_place);
     configuration->log_expected_ingestion_delay = kExpectedIngestionDelay;
     configuration->log_max_ingestion_random_delay = kMaxIngestionRandomDelay;
     configuration->report_uri = GURL(kTestReportURL);
diff --git a/services/network/tcp_socket_unittest.cc b/services/network/tcp_socket_unittest.cc
index 4004c32..0f8e8575 100644
--- a/services/network/tcp_socket_unittest.cc
+++ b/services/network/tcp_socket_unittest.cc
@@ -1080,8 +1080,8 @@
   std::vector<mojom::TCPKeepAliveOptionsPtr> keep_alive_options_list;
 
   keep_alive_options_list.emplace_back(nullptr);
-  keep_alive_options_list.emplace_back(base::in_place, false, 0U);
-  keep_alive_options_list.emplace_back(base::in_place, true, 100U);
+  keep_alive_options_list.emplace_back(absl::in_place, false, 0U);
+  keep_alive_options_list.emplace_back(absl::in_place, true, 100U);
 
   for (int receive_buffer_size :
        {-1, 0, 1024, TCPConnectedSocket::kMaxBufferSize,
diff --git a/services/service_manager/public/java/BUILD.gn b/services/service_manager/public/java/BUILD.gn
index 9113c28..61a8f9f 100644
--- a/services/service_manager/public/java/BUILD.gn
+++ b/services/service_manager/public/java/BUILD.gn
@@ -12,7 +12,6 @@
     "src/org/chromium/services/service_manager/InterfaceRegistry.java",
   ]
   deps = [
-    "//base:base_java",
     "//mojo/public/java:bindings_java",
     "//mojo/public/java:system_java",
     "//services/service_manager/public/mojom:constants_java",
diff --git a/services/tracing/BUILD.gn b/services/tracing/BUILD.gn
index e130d7f..ca186b3 100644
--- a/services/tracing/BUILD.gn
+++ b/services/tracing/BUILD.gn
@@ -177,7 +177,6 @@
   android_library("tracing_test_helper_java") {
     testonly = true
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
     ]
diff --git a/styleguide/c++/c++-features.md b/styleguide/c++/c++-features.md
index dfe8aa3..d546b42 100644
--- a/styleguide/c++/c++-features.md
+++ b/styleguide/c++/c++-features.md
@@ -902,6 +902,29 @@
 `absl::optional` instead.
 ***
 
+### std::in_place/in_place_type/in_place_index/in_place_t/in_place_type_t/in_place_index_t <sup>[banned]</sup>
+
+```c++
+std::optional<std::complex<double>> opt{std::in_place, 0, 1};
+std::variant<int, float> v{std::in_place_type<int>, 1.4};
+```
+
+**Description:** The `std::in_place` are disambiguation tags for
+`std::optional`, `std::variant`, and `std::any` to indicate that the object
+should be constructed in-place.
+
+**Documentation:**
+[std::in_place](https://en.cppreference.com/w/cpp/utility/in_place)
+
+**Notes:**
+*** promo
+Banned for now because `std::optional`, `std::variant`, and `std::any` are all
+banned for now. Because `absl::optional` and `absl::variant` are used instead,
+and they require `absl::in_place`, use `absl::in_place` for non-Abseil Chromium
+code. See the
+[discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ZspmuJPpv6s/m/wYYTCiRwAAAJ).
+***
+
 ### std::clamp <sup>[banned]</sup>
 
 ```c++
@@ -1677,6 +1700,24 @@
 [Discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/DqvG-TpvMyU)
 ***
 
+### in_place <sup>[allowed]</sup>
+
+```c++
+absl::in_place
+```
+
+**Description:** Early adaptation of C++17 `std::in_place`.
+
+**Documentation:**
+[std::in_place](https://en.cppreference.com/w/cpp/utility/in_place)
+
+**Notes:**
+*** promo
+Because the Abseil versions of `optional` and `variant` are used, the Abseil
+version of `in_place` is used in Chromium. See the
+[discussion thread](https://groups.google.com/a/chromium.org/g/cxx/c/ZspmuJPpv6s/m/wYYTCiRwAAAJ).
+***
+
 ## Abseil Banned Library Features {#absl-blocklist}
 
 The following Abseil library features are not allowed in the Chromium codebase.
diff --git a/testing/android/native_test/BUILD.gn b/testing/android/native_test/BUILD.gn
index 7d00b0f..3d54db0 100644
--- a/testing/android/native_test/BUILD.gn
+++ b/testing/android/native_test/BUILD.gn
@@ -47,7 +47,6 @@
   testonly = true
   sources = [ "java/src/org/chromium/native_test/MainRunner.java" ]
   deps = [
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
   ]
diff --git a/testing/android/reporter/BUILD.gn b/testing/android/reporter/BUILD.gn
index 4a6b32c..014149d 100644
--- a/testing/android/reporter/BUILD.gn
+++ b/testing/android/reporter/BUILD.gn
@@ -9,7 +9,6 @@
   chromium_code = true
 
   deps = [
-    "//base:base_java",
     "//build/android:build_java",
     "//build/android/gtest_apk:native_test_instrumentation_test_runner_java",
     "//third_party/android_sdk:android_test_base_java",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index e50c02b2d0..68267cb1 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5881,21 +5881,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
@@ -6023,21 +6023,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 93af60176..e1d0115 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -86963,21 +86963,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87080,21 +87080,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -88472,20 +88472,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
@@ -88614,20 +88614,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
@@ -90169,20 +90169,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
@@ -90311,20 +90311,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5040.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
@@ -91068,20 +91068,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5040.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 103.0.5041.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v103.0.5040.0",
-              "revision": "version:103.0.5040.0"
+              "location": "lacros_version_skew_tests_v103.0.5041.0",
+              "revision": "version:103.0.5041.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.updater.json b/testing/buildbot/chromium.updater.json
index 48916d51..43f0c35 100644
--- a/testing/buildbot/chromium.updater.json
+++ b/testing/buildbot/chromium.updater.json
@@ -990,58 +990,6 @@
       }
     ]
   },
-  "win7-updater-tester-dbg": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--test-launcher-timeout=90000",
-          "--ui-test-action-max-timeout=45000",
-          "--ui-test-action-timeout=40000"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "integrity": "high",
-              "os": "Windows-7-SP1"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "updater_tests",
-        "test_id_prefix": "ninja://chrome/updater:updater_tests/"
-      },
-      {
-        "args": [
-          "--test-launcher-timeout=90000",
-          "--ui-test-action-max-timeout=45000",
-          "--ui-test-action-timeout=40000"
-        ],
-        "merge": {
-          "args": [],
-          "script": "//testing/merge_scripts/standard_gtest_merge.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "integrity": "high",
-              "os": "Windows-7-SP1"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "updater_tests_system",
-        "test_id_prefix": "ninja://chrome/updater:updater_tests_system/"
-      }
-    ]
-  },
   "win7-updater-tester-dbg-uac": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index e997fde..3eb5e72 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -475,6 +475,14 @@
           '--flag-specific=enable-editing-ng',
         ],
       },
+      'linux_layout_tests_layout_ng_disabled': {
+        'args': [
+          '--flag-specific=disable-layout-ng',
+        ],
+        'swarming': {
+          'shards': 20,
+        },
+      },
       # TODO (crbug.com/1254971) Re-enable once fixed
       'mac-osxbeta-rel': {
         'experiment_percentage': 0,
diff --git a/testing/buildbot/tryserver.chromium.linux.json b/testing/buildbot/tryserver.chromium.linux.json
index 05a7f303..5f8ead2 100644
--- a/testing/buildbot/tryserver.chromium.linux.json
+++ b/testing/buildbot/tryserver.chromium.linux.json
@@ -90,6 +90,73 @@
       }
     ]
   },
+  "linux_layout_tests_layout_ng_disabled": {
+    "additional_compile_targets": [
+      "blink_tests"
+    ],
+    "gtest_tests": [
+      {
+        "args": [
+          "--disable-blink-features=LayoutNG,LayoutNGBlockFragmentation"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "webkit_unit_tests_ng",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "hard_timeout": 900,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "blink_unittests",
+        "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "--num-retries=3",
+          "--git-revision=${got_revision}",
+          "--flag-specific=disable-layout-ng"
+        ],
+        "isolate_name": "blink_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "blink_web_tests",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "hard_timeout": 900,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 20
+        },
+        "test_id_prefix": "ninja://:blink_web_tests/"
+      }
+    ]
+  },
   "linux_optional_gpu_tests_rel": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 6b5331d..5306d09 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5040.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v103.0.5041.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 103.0.5040.0',
+    'identifier': 'Lacros version skew testing ash 103.0.5041.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v103.0.5040.0',
-          'revision': 'version:103.0.5040.0',
+          'location': 'lacros_version_skew_tests_v103.0.5041.0',
+          'revision': 'version:103.0.5041.0',
         },
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index df28136..7e6513f 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -6142,22 +6142,6 @@
           ]
         },
       },
-      'win7-updater-tester-dbg': {
-        'mixins': [
-          'win7',
-          'x86-64'
-        ],
-        'test_suites': {
-          'gtest_tests': 'updater_gtests_win',
-        },
-        'swarming': {
-          'dimension_sets': [
-            {
-              'integrity': 'high',
-            }
-          ]
-        },
-      },
       'win7-updater-tester-dbg-uac': {
         'mixins': [
           'win7',
@@ -6860,6 +6844,21 @@
           'isolated_scripts': 'chromium_webkit_isolated_scripts',
         },
       },
+      'linux_layout_tests_layout_ng_disabled': {
+        'mixins': [
+          'linux-bionic',
+        ],
+        'additional_compile_targets': [
+          'blink_tests',
+        ],
+        'swarming': {
+          'hard_timeout': 900,
+        },
+        'test_suites': {
+          'gtest_tests': 'layout_ng_gtests',
+          'isolated_scripts': 'chromium_webkit_isolated_scripts',
+        },
+      },
       'linux_optional_gpu_tests_rel': {
         'os_type': 'linux',
         'browser_config': 'release',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index a9dc532..107700b1 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4076,21 +4076,6 @@
             ]
         }
     ],
-    "IOSTabGridSearch": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "TabsSearch"
-                    ]
-                }
-            ]
-        }
-    ],
     "IOSThumbstrip": [
         {
             "platforms": [
diff --git a/third_party/abseil-cpp/BUILD.gn b/third_party/abseil-cpp/BUILD.gn
index c7db8f7..e71d98a 100644
--- a/third_party/abseil-cpp/BUILD.gn
+++ b/third_party/abseil-cpp/BUILD.gn
@@ -89,6 +89,7 @@
     "//third_party/abseil-cpp/absl/types:optional",
     "//third_party/abseil-cpp/absl/types:span",
     "//third_party/abseil-cpp/absl/types:variant",
+    "//third_party/abseil-cpp/absl/utility",
   ]
 
   # The following dependencies currently don't build with NaCl.
diff --git a/third_party/android_deps/additional_readme_paths.json b/third_party/android_deps/additional_readme_paths.json
index 2e738a0b..b5610b45 100644
--- a/third_party/android_deps/additional_readme_paths.json
+++ b/third_party/android_deps/additional_readme_paths.json
@@ -44,6 +44,7 @@
     "libs/com_android_tools_sdk_common",
     "libs/com_github_ben_manes_caffeine_caffeine",
     "libs/com_github_kevinstern_software_and_algorithms",
+    "libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework",
     "libs/com_google_android_datatransport_transport_api",
     "libs/com_google_android_gms_play_services_auth",
     "libs/com_google_android_gms_play_services_auth_api_phone",
@@ -105,6 +106,7 @@
     "libs/com_google_j2objc_j2objc_annotations",
     "libs/com_google_protobuf_protobuf_java",
     "libs/com_google_protobuf_protobuf_javalite",
+    "libs/com_google_protobuf_protobuf_lite",
     "libs/com_googlecode_java_diff_utils_diffutils",
     "libs/com_squareup_javapoet",
     "libs/com_squareup_javawriter",
@@ -120,6 +122,7 @@
     "libs/org_checkerframework_dataflow_errorprone",
     "libs/org_codehaus_mojo_animal_sniffer_annotations",
     "libs/org_eclipse_jgit_org_eclipse_jgit",
+    "libs/org_hamcrest_hamcrest",
     "libs/org_jetbrains_annotations",
     "libs/org_jetbrains_kotlin_kotlin_stdlib",
     "libs/org_jetbrains_kotlin_kotlin_stdlib_common",
@@ -128,6 +131,7 @@
     "libs/org_jetbrains_kotlinx_kotlinx_coroutines_android",
     "libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm",
     "libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm",
+    "libs/org_jsoup_jsoup",
     "libs/org_ow2_asm_asm",
     "libs/org_ow2_asm_asm_analysis",
     "libs/org_ow2_asm_asm_commons",
diff --git a/third_party/android_deps/build.gradle b/third_party/android_deps/build.gradle
index 66d991d..695cae7 100644
--- a/third_party/android_deps/build.gradle
+++ b/third_party/android_deps/build.gradle
@@ -175,6 +175,10 @@
     buildCompileNoDeps "com.android.tools.layoutlib:layoutlib-api:${androidToolsVersion}"
     buildCompile 'org.jetbrains.kotlin:kotlin-stdlib:1.4.32'
 
+    androidTestCompile 'com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:3.1.2'
+    // accessibility-test-framework:3.1.2 depends on jsoup 1.12, which has a security
+    // vulnerability, so grab a later version.
+    androidTestCompile 'org.jsoup:jsoup:1.14.2'
     androidTestCompile 'com.googlecode.java-diff-utils:diffutils:1.3.0'
     // Version 1.2 is needed by espresso-web, but we'll newer 1.2.1.
     androidTestCompile 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index 23f3d91..c071755e 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -55,8 +55,6 @@
     static final Map<String, String> EXISTING_LIBS = [
         com_ibm_icu_icu4j: '//third_party/icu4j:icu4j_java',
         com_almworks_sqlite4java_sqlite4java: '//third_party/sqlite4java:sqlite4java_java',
-        com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework:
-            '//third_party/accessibility_test_framework:accessibility_test_framework_java',
         junit_junit: '//third_party/junit:junit',
         org_bouncycastle_bcprov_jdk15on: '//third_party/bouncycastle:bouncycastle_java',
         org_hamcrest_hamcrest_core: '//third_party/hamcrest:hamcrest_core_java',
@@ -67,6 +65,14 @@
         androidx_window_window: EXCLUDE_THIS_LIB,
     ]
 
+    // Some libraries have such long names they'll create a path that exceeds the 200 char path
+    // limit, which is enforce by presubmit checks for Windows.
+    // Needs to match mapping in fetch_all.py.
+    static final Map<String, String> REDUCED_ID_LENGTH_MAP = [
+        'com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework':
+            'com_google_android_accessibility_test_framework',
+    ]
+
     /**
      * Prefixes of androidx dependencies which are allowed to use non-SNAPSHOT
      * versions. These are the legacy androidx targets that are no longer being
@@ -137,6 +143,13 @@
     @SourceURI
     URI sourceUri
 
+    static void reduceDependencyStrLength(ChromiumDepGraph.DependencyDescription dependency) {
+      String reduced_id = REDUCED_ID_LENGTH_MAP.get(dependency.id)
+      if (reduced_id) {
+          dependency.id = reduced_id
+      }
+    }
+
     static String translateTargetName(String targetName) {
         if (isPlayServicesTarget(targetName)) {
             return targetName.replaceFirst('com_', '').replaceFirst('android_gms_', '')
@@ -175,6 +188,7 @@
 
         boolean securityCritical = dependency.supportsAndroid && dependency.isShipped
         String licenseFile = dependency.isShipped ? 'LICENSE' : 'NOT_SHIPPED'
+        String cpePrefix = dependency.cpePrefix ? dependency.cpePrefix : 'unknown'
 
         return """\
             Name: ${dependency.displayName}
@@ -183,7 +197,7 @@
             Version: ${dependency.version}
             License: ${licenseString}
             License File: ${licenseFile}
-            CPEPrefix: ${dependency.cpePrefix}
+            CPEPrefix: ${cpePrefix}
             Security Critical: ${securityCritical ? 'yes' : 'no'}
             ${dependency.licenseAndroidCompatible ? 'License Android Compatible: yes' : ''}
             Description:
@@ -452,6 +466,7 @@
             return
         }
 
+        reduceDependencyStrLength(dependency)
         String targetName = translateTargetName(dependency.id) + '_java'
         List<String> javaDeps = computeJavaGroupForwardingTargets(dependency) ?: dependency.children
 
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
index 68f60ef6..4449547 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/ChromiumDepGraph.groovy
@@ -134,6 +134,10 @@
             url: 'https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md',
             licenseUrl: 'https://raw.githubusercontent.com/protocolbuffers/protobuf/master/LICENSE',
             licenseName: 'BSD'),
+        com_google_protobuf_protobuf_lite: new PropertyOverride(
+            url: 'https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md',
+            licenseUrl: 'https://raw.githubusercontent.com/protocolbuffers/protobuf/master/LICENSE',
+            licenseName: 'BSD'),
         javax_annotation_javax_annotation_api: new PropertyOverride(
             isShipped: false,  // Annotations are stripped by R8.
             licenseName: 'CDDLv1.1',
@@ -154,6 +158,13 @@
         org_checkerframework_dataflow_errorprone: new PropertyOverride(
             licenseUrl: 'https://raw.githubusercontent.com/typetools/checker-framework/master/LICENSE.txt',
             licenseName: 'GPL v2 with the classpath exception'),
+        org_hamcrest_hamcrest: new PropertyOverride(
+            licenseUrl: 'https://raw.githubusercontent.com/hamcrest/JavaHamcrest/master/LICENSE.txt',
+            licenseName: 'BSD'),
+        org_jsoup_jsoup: new PropertyOverride(
+            cpePrefix: 'cpe:/a:jsoup:jsoup:1.14.2',
+            licenseUrl: 'https://raw.githubusercontent.com/jhy/jsoup/master/LICENSE',
+            licenseName: 'The MIT License'),
         org_ow2_asm_asm: new PropertyOverride(
             licenseUrl: 'https://gitlab.ow2.org/asm/asm/raw/master/LICENSE.txt',
             licenseName: 'BSD'),
diff --git a/third_party/android_deps/fetch_all.py b/third_party/android_deps/fetch_all.py
index 59a04040..3a4dc6a3 100755
--- a/third_party/android_deps/fetch_all.py
+++ b/third_party/android_deps/fetch_all.py
@@ -71,6 +71,13 @@
     'subprojects.txt',
 ]
 
+# Dictionary mapping long path names to shorter ones to avoid paths being over
+# 200 chars. This should match the dictionary in BuildConfigGenerator.groovy.
+_REDUCED_ID_LENGTH_MAP = {
+    'com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework':
+    'com_google_android_accessibility_test_framework',
+}
+
 # If this file exists in an aar file then it is appended to LICENSE
 _THIRD_PARTY_LICENSE_FILENAME = 'third_party_licenses.txt'
 
@@ -349,6 +356,18 @@
             CopyFileOrDirectory(report_src, report_dst)
 
 
+def _ReduceNameLength(path_str):
+    """Returns a shorter path string if needed.
+
+  Args:
+    path_str: A String representing the path.
+  Returns:
+    A String (possibly shortened) of that path.
+  """
+    return path_str if path_str not in _REDUCED_ID_LENGTH_MAP else _REDUCED_ID_LENGTH_MAP[
+        path_str]
+
+
 def GetCipdPackageInfo(cipd_yaml_path):
     """Returns the CIPD package name corresponding to a given cipd.yaml file.
 
@@ -415,7 +434,8 @@
 
     for aar_file in aar_files:
         aar_dirname = os.path.dirname(aar_file)
-        aar_info_name = os.path.basename(aar_dirname) + '.info'
+        aar_info_name = _ReduceNameLength(
+            os.path.basename(aar_dirname)) + '.info'
         aar_info_path = os.path.join(aar_dirname, aar_info_name)
 
         logging.debug('- %s', aar_info_name)
diff --git a/third_party/android_deps/libs/android_arch_core_common/README.chromium b/third_party/android_deps/libs/android_arch_core_common/README.chromium
index c684021..35f6304 100644
--- a/third_party/android_deps/libs/android_arch_core_common/README.chromium
+++ b/third_party/android_deps/libs/android_arch_core_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_core_runtime/README.chromium b/third_party/android_deps/libs/android_arch_core_runtime/README.chromium
index 81fa9d4..ba59add0 100644
--- a/third_party/android_deps/libs/android_arch_core_runtime/README.chromium
+++ b/third_party/android_deps/libs/android_arch_core_runtime/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_common/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_common/README.chromium
index 9843214..934abed 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_common/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_common_java8/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_common_java8/README.chromium
index 75df6031..817062a 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_common_java8/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_common_java8/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_livedata/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_livedata/README.chromium
index 90452c31..1aaf1a2 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_livedata/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_livedata/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/README.chromium
index 9b164e8..b2f77a9 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_livedata_core/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_runtime/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_runtime/README.chromium
index 84de68b..30469196 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_runtime/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_runtime/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/README.chromium b/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/README.chromium
index 7c19c97..1270cb5 100644
--- a/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/README.chromium
+++ b/third_party/android_deps/libs/android_arch_lifecycle_viewmodel/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_animated_vector_drawable/README.chromium b/third_party/android_deps/libs/com_android_support_animated_vector_drawable/README.chromium
index 6db1114..fb1b14d 100644
--- a/third_party/android_deps/libs/com_android_support_animated_vector_drawable/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_animated_vector_drawable/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_appcompat_v7/README.chromium b/third_party/android_deps/libs/com_android_support_appcompat_v7/README.chromium
index da941bc..1cef4479 100644
--- a/third_party/android_deps/libs/com_android_support_appcompat_v7/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_appcompat_v7/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_asynclayoutinflater/README.chromium b/third_party/android_deps/libs/com_android_support_asynclayoutinflater/README.chromium
index 33dd0dc..4176ad5 100644
--- a/third_party/android_deps/libs/com_android_support_asynclayoutinflater/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_asynclayoutinflater/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_cardview_v7/README.chromium b/third_party/android_deps/libs/com_android_support_cardview_v7/README.chromium
index 1cda700..21b16cc 100644
--- a/third_party/android_deps/libs/com_android_support_cardview_v7/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_cardview_v7/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_collections/README.chromium b/third_party/android_deps/libs/com_android_support_collections/README.chromium
index 82cf6afa..60cfcc9 100644
--- a/third_party/android_deps/libs/com_android_support_collections/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_collections/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_coordinatorlayout/README.chromium b/third_party/android_deps/libs/com_android_support_coordinatorlayout/README.chromium
index e301284b..c17568f 100644
--- a/third_party/android_deps/libs/com_android_support_coordinatorlayout/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_coordinatorlayout/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_cursoradapter/README.chromium b/third_party/android_deps/libs/com_android_support_cursoradapter/README.chromium
index 79ee60e..2c110a99 100644
--- a/third_party/android_deps/libs/com_android_support_cursoradapter/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_cursoradapter/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_customview/README.chromium b/third_party/android_deps/libs/com_android_support_customview/README.chromium
index f0b755d..ed4073c8 100644
--- a/third_party/android_deps/libs/com_android_support_customview/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_customview/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_design/README.chromium b/third_party/android_deps/libs/com_android_support_design/README.chromium
index dbe3ce6..433417f5 100644
--- a/third_party/android_deps/libs/com_android_support_design/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_design/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_documentfile/README.chromium b/third_party/android_deps/libs/com_android_support_documentfile/README.chromium
index e1bc20fd..52909702 100644
--- a/third_party/android_deps/libs/com_android_support_documentfile/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_documentfile/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_drawerlayout/README.chromium b/third_party/android_deps/libs/com_android_support_drawerlayout/README.chromium
index bc15e40..2af57316 100644
--- a/third_party/android_deps/libs/com_android_support_drawerlayout/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_drawerlayout/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_interpolator/README.chromium b/third_party/android_deps/libs/com_android_support_interpolator/README.chromium
index 8c41dc1..7222d72 100644
--- a/third_party/android_deps/libs/com_android_support_interpolator/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_interpolator/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_loader/README.chromium b/third_party/android_deps/libs/com_android_support_loader/README.chromium
index 12cfb7b..98e44f0 100644
--- a/third_party/android_deps/libs/com_android_support_loader/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_loader/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_localbroadcastmanager/README.chromium b/third_party/android_deps/libs/com_android_support_localbroadcastmanager/README.chromium
index d69d669..ea8980e 100644
--- a/third_party/android_deps/libs/com_android_support_localbroadcastmanager/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_localbroadcastmanager/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_multidex/README.chromium b/third_party/android_deps/libs/com_android_support_multidex/README.chromium
index b97d5f41..54ac518 100644
--- a/third_party/android_deps/libs/com_android_support_multidex/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_multidex/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_print/README.chromium b/third_party/android_deps/libs/com_android_support_print/README.chromium
index 5b01118..ec35452 100644
--- a/third_party/android_deps/libs/com_android_support_print/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_print/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_recyclerview_v7/README.chromium b/third_party/android_deps/libs/com_android_support_recyclerview_v7/README.chromium
index 36bb034..4f033904 100644
--- a/third_party/android_deps/libs/com_android_support_recyclerview_v7/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_recyclerview_v7/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_slidingpanelayout/README.chromium b/third_party/android_deps/libs/com_android_support_slidingpanelayout/README.chromium
index 72be315..1b9999f 100644
--- a/third_party/android_deps/libs/com_android_support_slidingpanelayout/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_slidingpanelayout/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_annotations/README.chromium b/third_party/android_deps/libs/com_android_support_support_annotations/README.chromium
index 92d8e74..5500d43e 100644
--- a/third_party/android_deps/libs/com_android_support_support_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_compat/README.chromium b/third_party/android_deps/libs/com_android_support_support_compat/README.chromium
index d756bdd..ce5b81d7 100644
--- a/third_party/android_deps/libs/com_android_support_support_compat/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_compat/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_core_ui/README.chromium b/third_party/android_deps/libs/com_android_support_support_core_ui/README.chromium
index b9fea5a..65e72c6b 100644
--- a/third_party/android_deps/libs/com_android_support_support_core_ui/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_core_ui/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_core_utils/README.chromium b/third_party/android_deps/libs/com_android_support_support_core_utils/README.chromium
index 9f448fa..2816e3b 100644
--- a/third_party/android_deps/libs/com_android_support_support_core_utils/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_core_utils/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_fragment/README.chromium b/third_party/android_deps/libs/com_android_support_support_fragment/README.chromium
index a92ce26..80e13fa 100644
--- a/third_party/android_deps/libs/com_android_support_support_fragment/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_fragment/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_media_compat/README.chromium b/third_party/android_deps/libs/com_android_support_support_media_compat/README.chromium
index 840cc64..371d933a 100644
--- a/third_party/android_deps/libs/com_android_support_support_media_compat/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_media_compat/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_v4/README.chromium b/third_party/android_deps/libs/com_android_support_support_v4/README.chromium
index bd1e564..17082d85 100644
--- a/third_party/android_deps/libs/com_android_support_support_v4/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_v4/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_support_vector_drawable/README.chromium b/third_party/android_deps/libs/com_android_support_support_vector_drawable/README.chromium
index e961d3b8..18db5a6 100644
--- a/third_party/android_deps/libs/com_android_support_support_vector_drawable/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_support_vector_drawable/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_swiperefreshlayout/README.chromium b/third_party/android_deps/libs/com_android_support_swiperefreshlayout/README.chromium
index b889645..9a36d5b 100644
--- a/third_party/android_deps/libs/com_android_support_swiperefreshlayout/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_swiperefreshlayout/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_transition/README.chromium b/third_party/android_deps/libs/com_android_support_transition/README.chromium
index 3ee8884..0c45c81 100644
--- a/third_party/android_deps/libs/com_android_support_transition/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_transition/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_versionedparcelable/README.chromium b/third_party/android_deps/libs/com_android_support_versionedparcelable/README.chromium
index 7ed6a7ab..50b75c8 100644
--- a/third_party/android_deps/libs/com_android_support_versionedparcelable/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_versionedparcelable/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_support_viewpager/README.chromium b/third_party/android_deps/libs/com_android_support_viewpager/README.chromium
index 3fff530..76780fd 100644
--- a/third_party/android_deps/libs/com_android_support_viewpager/README.chromium
+++ b/third_party/android_deps/libs/com_android_support_viewpager/README.chromium
@@ -4,7 +4,7 @@
 Version: 28.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_tools_common/README.chromium b/third_party/android_deps/libs/com_android_tools_common/README.chromium
index d7252198..511ecf5 100644
--- a/third_party/android_deps/libs/com_android_tools_common/README.chromium
+++ b/third_party/android_deps/libs/com_android_tools_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 30.2.0-beta01
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/README.chromium b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/README.chromium
index 0a698e5a..a66b1af 100644
--- a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/README.chromium
+++ b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.5
 License: GPL v2 with the classpath exception
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/README.chromium b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/README.chromium
index 9d99a70..792954b 100644
--- a/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/README.chromium
+++ b/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.1.5
 License: BSD 3-Clause
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/README.chromium b/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/README.chromium
index 619da61..497e2e50 100644
--- a/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/README.chromium
+++ b/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api/README.chromium
@@ -4,7 +4,7 @@
 Version: 30.2.0-beta01
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_android_tools_sdk_common/README.chromium b/third_party/android_deps/libs/com_android_tools_sdk_common/README.chromium
index 387d816..004ed43 100644
--- a/third_party/android_deps/libs/com_android_tools_sdk_common/README.chromium
+++ b/third_party/android_deps/libs/com_android_tools_sdk_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 30.2.0-beta01
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/README.chromium b/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/README.chromium
index 4ea9175..12b68da 100644
--- a/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/README.chromium
+++ b/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.8.8
 License: Apache License, Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/README.chromium b/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/README.chromium
index bcf865ec..6f825b1 100644
--- a/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/README.chromium
+++ b/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0
 License: MIT License
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/3pp.pb b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/3pp.pb
new file mode 100644
index 0000000..d8137c1
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/3pp.pb
@@ -0,0 +1,16 @@
+# 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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
+
+create {
+  source {
+    script { name: "fetch.py" }
+  }
+}
+
+upload {
+  pkg_prefix: "chromium/third_party/android_deps/libs"
+  universal: true
+}
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/fetch.py b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/fetch.py
new file mode 100755
index 0000000..33401fa5
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/3pp/fetch.py
@@ -0,0 +1,78 @@
+#!/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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy and
+# 3ppFetch.template instead.
+
+import argparse
+import json
+import os
+import re
+import urllib.request
+
+_REPO_URL = 'https://dl.google.com/dl/android/maven2'
+_GROUP_NAME = 'com/google/android/apps/common/testing/accessibility/framework'
+_MODULE_NAME = 'accessibility-test-framework'
+_FILE_EXT = 'aar'
+_OVERRIDE_LATEST = None
+_PATCH_VERSION = 'cr1'
+
+
+def do_latest():
+    if _OVERRIDE_LATEST is not None:
+        print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}')
+        return
+    maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format(
+        _REPO_URL, _GROUP_NAME, _MODULE_NAME)
+    metadata = urllib.request.urlopen(maven_metadata_url).read().decode(
+        'utf-8')
+    # Do not parse xml with the python included parser since it is susceptible
+    # to maliciously crafted xmls. Only use regular expression parsing to be
+    # safe. RE should be enough to handle what we need to extract.
+    match = re.search('<latest>([^<]+)</latest>', metadata)
+    if match:
+        latest = match.group(1)
+    else:
+        # if no latest info was found just hope the versions are sorted and the
+        # last one is the latest (as is commonly the case).
+        latest = re.findall('<version>([^<]+)</version>', metadata)[-1]
+    print(latest + f'.{_PATCH_VERSION}')
+
+
+def get_download_url(version):
+    # Remove the patch version when getting the download url
+    version_no_patch, patch = version.rsplit('.', 1)
+    if patch.startswith('cr'):
+        version = version_no_patch
+    file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME,
+                                                    _MODULE_NAME, version,
+                                                    _FILE_EXT)
+    file_name = file_url.rsplit('/', 1)[-1]
+
+    partial_manifest = {
+        'url': [file_url],
+        'name': [file_name],
+        'ext': '.' + _FILE_EXT,
+    }
+    print(json.dumps(partial_manifest))
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    sub = ap.add_subparsers()
+
+    latest = sub.add_parser('latest')
+    latest.set_defaults(func=lambda _opts: do_latest())
+
+    download = sub.add_parser('get_url')
+    download.set_defaults(
+        func=lambda _opts: get_download_url(os.environ['_3PP_VERSION']))
+
+    opts = ap.parse_args()
+    opts.func(opts)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/LICENSE b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/LICENSE
new file mode 100644
index 0000000..bee4082
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/LICENSE
@@ -0,0 +1,147 @@
+Terms and conditions
+
+This is the Android Software Development Kit License Agreement
+
+1. Introduction
+
+1.1 The Android Software Development Kit (referred to in the License Agreement as the "SDK" and specifically including the Android system files, packaged APIs, and Google APIs add-ons) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the SDK.
+
+1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
+
+1.3 A "compatible implementation" means any Android device that (i) complies with the Android Compatibility Definition document, which can be found at the Android compatibility website (http://source.android.com/compatibility) and which may be updated from time to time; and (ii) successfully passes the Android Compatibility Test Suite (CTS).
+
+1.4 "Google" means Google LLC, a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+
+
+2. Accepting this License Agreement
+
+2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use the SDK if you do not accept the License Agreement.
+
+2.2 By clicking to accept, you hereby agree to the terms of the License Agreement.
+
+2.3 You may not use the SDK and may not accept the License Agreement if you are a person barred from receiving the SDK under the laws of the United States or other countries, including the country in which you are resident or from which you use the SDK.
+
+2.4 If you are agreeing to be bound by the License Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the SDK on behalf of your employer or other entity.
+
+
+3. SDK License from Google
+
+3.1 Subject to the terms of the License Agreement, Google grants you a limited, worldwide, royalty-free, non-assignable, non-exclusive, and non-sublicensable license to use the SDK solely to develop applications for compatible implementations of Android.
+
+3.2 You may not use this SDK to develop applications for other platforms (including non-compatible implementations of Android) or to develop another SDK. You are of course free to develop applications for other platforms, including non-compatible implementations of Android, provided that this SDK is not used for that purpose.
+
+3.3 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
+
+3.4 You may not use the SDK for any purpose not expressly permitted by the License Agreement.  Except to the extent required by applicable third party licenses, you may not copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK.
+
+3.5 Use, reproduction and distribution of components of the SDK licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement.
+
+3.6 You agree that the form and nature of the SDK that Google provides may change without prior notice to you and that future versions of the SDK may be incompatible with applications developed on previous versions of the SDK. You agree that Google may stop (permanently or temporarily) providing the SDK (or any features within the SDK) to you or to users generally at Google's sole discretion, without prior notice to you.
+
+3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
+
+3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the SDK.
+
+
+4. Use of the SDK by You
+
+4.1 Google agrees that it obtains no right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the SDK, including any intellectual property rights that subsist in those applications.
+
+4.2 You agree to use the SDK and write applications only for purposes that are permitted by (a) the License Agreement and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
+
+4.3 You agree that if you use the SDK to develop applications for general public users, you will protect the privacy and legal rights of those users. If the users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If the user provides your application with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, the user has given you permission to do so.
+
+4.4 You agree that you will not engage in any activity with the SDK, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of any third party including, but not limited to, Google or any mobile communications carrier.
+
+4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
+
+4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
+
+
+5. Your Developer Credentials
+
+5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
+
+
+6. Privacy and Information
+
+6.1 In order to continually innovate and improve the SDK, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the SDK are being used and how they are being used. Before any of this information is collected, the SDK will notify you and seek your consent. If you withhold consent, the information will not be collected.
+
+6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in accordance with Google's Privacy Policy.
+
+
+7. Third Party Applications
+
+7.1 If you use the SDK to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
+
+7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
+
+7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party. In that case, the License Agreement does not affect your legal relationship with these third parties.
+
+
+8. Using Android APIs
+
+8.1 Google Data APIs
+
+8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
+
+8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
+
+
+9. Terminating this License Agreement
+
+9.1 The License Agreement will continue to apply until terminated by either you or Google as set out below.
+
+9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the SDK and any relevant developer credentials.
+
+9.3 Google may at any time, terminate the License Agreement with you if:
+(A) you have breached any provision of the License Agreement; or
+(B) Google is required to do so by law; or
+(C) the partner with whom Google offered certain parts of SDK (such as APIs) to you has terminated its relationship with Google or ceased to offer certain parts of the SDK to you; or
+(D) Google decides to no longer provide the SDK or certain parts of the SDK to users in the country in which you are resident or from which you use the service, or the provision of the SDK or certain SDK services to you by Google is, in Google's sole discretion, no longer commercially viable.
+
+9.4 When the License Agreement comes to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst the License Agreement has been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall continue to apply to such rights, obligations and liabilities indefinitely.
+
+
+10. DISCLAIMER OF WARRANTIES
+
+10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+
+10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE.
+
+10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+
+
+11. LIMITATION OF LIABILITY
+
+11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+
+
+12. Indemnification
+
+12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys fees) arising out of or accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with the License Agreement.
+
+
+13. Changes to the License Agreement
+
+13.1 Google may make changes to the License Agreement as it distributes new versions of the SDK. When these changes are made, Google will make a new version of the License Agreement available on the website where the SDK is made available.
+
+
+14. General Legal Terms
+
+14.1 The License Agreement constitutes the whole legal agreement between you and Google and governs your use of the SDK (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the SDK.
+
+14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
+
+14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.
+
+14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.
+
+14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+
+14.6 The rights granted in the License Agreement may not be assigned or transferred by either you or Google without the prior written approval of the other party. Neither you nor Google shall be permitted to delegate their responsibilities or obligations under the License Agreement without the prior written approval of the other party.
+
+14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+
+
+December 9, 2016
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/OWNERS b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/OWNERS
new file mode 100644
index 0000000..aea47a05
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/README.chromium b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/README.chromium
new file mode 100644
index 0000000..e3d52695
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/README.chromium
@@ -0,0 +1,14 @@
+Name: Accessibility Test Framework
+Short Name: accessibility-test-framework
+URL: https://github.com/google/Accessibility-Test-Framework-for-Android
+Version: 3.1.2
+License: Android Software Development Kit License
+License File: NOT_SHIPPED
+CPEPrefix: unknown
+Security Critical: no
+
+Description:
+Library used to test for common accessibility issues.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/cipd.yaml b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/cipd.yaml
new file mode 100644
index 0000000..f4268a7a
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2@3.1.2.cr1
+package: chromium/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework
+description: "Accessibility Test Framework"
+data:
+- file: accessibility-test-framework-3.1.2.aar
diff --git a/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/com_google_android_accessibility_test_framework.info b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/com_google_android_accessibility_test_framework.info
new file mode 100644
index 0000000..cdc1e3d
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework/com_google_android_accessibility_test_framework.info
@@ -0,0 +1,14 @@
+# Generated by //build/android/gyp/aar.py
+# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen".
+
+aidl = []
+assets = []
+has_classes_jar = true
+has_native_libraries = false
+has_proguard_flags = false
+has_r_text_file = true
+is_manifest_empty = true
+manifest_package = "com.google.android.apps.common.testing.accessibility.framework"
+resources = []
+subjar_tuples = []
+subjars = []
diff --git a/third_party/android_deps/libs/com_google_android_datatransport_transport_api/README.chromium b/third_party/android_deps/libs/com_google_android_datatransport_transport_api/README.chromium
index 75dce5c..70011e7 100644
--- a/third_party/android_deps/libs/com_google_android_datatransport_transport_api/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_datatransport_transport_api/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.2.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_auth/README.chromium
index b1a09b7..3620994d 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth/README.chromium
@@ -4,7 +4,7 @@
 Version: 20.1.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/README.chromium
index 44435ab..455432b 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/README.chromium
index 3ac3854..79915ce 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.2
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_base/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_base/README.chromium
index afaf3a3..e9a5716 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_base/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_base/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_basement/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_basement/README.chromium
index 4f93e083..fdfab31 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_basement/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_basement/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cast/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_cast/README.chromium
index 49bb6f5..f4f3572 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cast/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cast/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/README.chromium
index b261325..9ef411f 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/README.chromium
index 28e5475..66d0d74 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/README.chromium
index cbf8cfe5..01bdf06 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_fido/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_fido/README.chromium
index bf859691..49ed988 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_fido/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_fido/README.chromium
@@ -4,7 +4,7 @@
 Version: 19.0.0-beta
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_flags/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_flags/README.chromium
index 70c9d22..8e663c4 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_flags/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_flags/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/README.chromium
index 2c0e231..152c5c4 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_gcm/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_iid/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_iid/README.chromium
index 8c7cf324..01ae78f 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_iid/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_iid/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/README.chromium
index 1cae124..0c471ed 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_location/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_location/README.chromium
index 833fcfd9..088f4bd3 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_location/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_location/README.chromium
@@ -4,7 +4,7 @@
 Version: 19.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/README.chromium
index 5df0136..9aadcc4 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/README.chromium
index f3b892a..fce83fdf 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_places_placereport/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_stats/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_stats/README.chromium
index 1fcf703..8691d89 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_stats/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_stats/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/README.chromium
index 2675dcf..eaa5c99c 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_tasks/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_vision/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_vision/README.chromium
index 3aa7506..5dae2cc 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_vision/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_vision/README.chromium
@@ -4,7 +4,7 @@
 Version: 20.1.3
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/README.chromium b/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/README.chromium
index 8a3954c3..88e1a8a 100644
--- a/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 19.1.3
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_material_material/README.chromium b/third_party/android_deps/libs/com_google_android_material_material/README.chromium
index 0bcb8848..3bee109 100644
--- a/third_party/android_deps/libs/com_google_android_material_material/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_material_material/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.0-alpha01
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_android_play_core/README.chromium b/third_party/android_deps/libs/com_google_android_play_core/README.chromium
index b2496af..cff44a8 100644
--- a/third_party/android_deps/libs/com_google_android_play_core/README.chromium
+++ b/third_party/android_deps/libs/com_google_android_play_core/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.10.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_auto_auto_common/README.chromium b/third_party/android_deps/libs/com_google_auto_auto_common/README.chromium
index 6991cf8..882e12a 100644
--- a/third_party/android_deps/libs/com_google_auto_auto_common/README.chromium
+++ b/third_party/android_deps/libs/com_google_auto_auto_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.2.1
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_auto_service_auto_service/README.chromium b/third_party/android_deps/libs/com_google_auto_service_auto_service/README.chromium
index 0ceb437..888c2fe 100644
--- a/third_party/android_deps/libs/com_google_auto_service_auto_service/README.chromium
+++ b/third_party/android_deps/libs/com_google_auto_service_auto_service/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0-rc6
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/README.chromium b/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/README.chromium
index 2b20cba..99c00d5e 100644
--- a/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0-rc6
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/README.chromium b/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/README.chromium
index c7f341f..8304de3 100644
--- a/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.9
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_code_findbugs_jsr305/README.chromium b/third_party/android_deps/libs/com_google_code_findbugs_jsr305/README.chromium
index 6b9dbea9..fac4103 100644
--- a/third_party/android_deps/libs/com_google_code_findbugs_jsr305/README.chromium
+++ b/third_party/android_deps/libs/com_google_code_findbugs_jsr305/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.0.2
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_code_gson_gson/README.chromium b/third_party/android_deps/libs/com_google_code_gson_gson/README.chromium
index ae66ce4b..2bfef92 100644
--- a/third_party/android_deps/libs/com_google_code_gson_gson/README.chromium
+++ b/third_party/android_deps/libs/com_google_code_gson_gson/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.8.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium
index e064f72..c53bda91 100644
--- a/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium
+++ b/third_party/android_deps/libs/com_google_dagger_dagger/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.30
 License: Apache 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium
index 726f87e8..bc5e648d 100644
--- a/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_compiler/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.30
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium
index 4f96338..27ec297 100644
--- a/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_producers/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.30
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium b/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium
index 80e4b57f..bb05b40 100644
--- a/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium
+++ b/third_party/android_deps/libs/com_google_dagger_dagger_spi/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.30
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/README.chromium b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/README.chromium
index 2e1016709..8f3fb94 100644
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.11.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/README.chromium b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/README.chromium
index 734af91..e06b9a46 100644
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.11.0
 License: Apache 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/README.chromium b/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/README.chromium
index 3881bbd..83c343f 100644
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.11.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_core/README.chromium b/third_party/android_deps/libs/com_google_errorprone_error_prone_core/README.chromium
index 68a8a1b..b17f1ad 100644
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_core/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_core/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.11.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/README.chromium b/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/README.chromium
index 407ae18..b0b0ff0 100644
--- a/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.11.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac/README.chromium b/third_party/android_deps/libs/com_google_errorprone_javac/README.chromium
index 4d5da43..5908348 100644
--- a/third_party/android_deps/libs/com_google_errorprone_javac/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_javac/README.chromium
@@ -4,7 +4,7 @@
 Version: 9+181-r4173-1
 License: GPL v2 with the classpath exception
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium
index 5c73995d..77c428e 100644
--- a/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium
+++ b/third_party/android_deps/libs/com_google_errorprone_javac_shaded/README.chromium
@@ -4,7 +4,7 @@
 Version: 9-dev-r4023-3
 License: GPL v2 with the classpath exception
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_annotations/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_annotations/README.chromium
index 3df0e1da..75dff9f 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.0.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_common/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_common/README.chromium
index ad26366..9fa5aee 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_common/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 19.5.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_components/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_components/README.chromium
index a09987c..11bba34 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_components/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_components/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.1.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_encoders/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_encoders/README.chromium
index 1206298..7c5daa1c 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_encoders/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_encoders/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.1.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/README.chromium
index 020c8b2..bb3cb7dd 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.1.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_iid/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_iid/README.chromium
index 53f6a94..561895f 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_iid/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_iid/README.chromium
@@ -4,7 +4,7 @@
 Version: 21.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/README.chromium
index 08a3b47..8ee5c34 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop/README.chromium
@@ -4,7 +4,7 @@
 Version: 17.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_installations/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_installations/README.chromium
index 25b33ae..eaa04967 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_installations/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_installations/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.3.5
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/README.chromium
index eef8f56e..bbc4d94 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop/README.chromium
@@ -4,7 +4,7 @@
 Version: 16.0.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/README.chromium
index a20b26c..2524b67 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector/README.chromium
@@ -4,7 +4,7 @@
 Version: 18.0.0
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_firebase_firebase_messaging/README.chromium b/third_party/android_deps/libs/com_google_firebase_firebase_messaging/README.chromium
index 59b23bfe..07d84b0 100644
--- a/third_party/android_deps/libs/com_google_firebase_firebase_messaging/README.chromium
+++ b/third_party/android_deps/libs/com_google_firebase_firebase_messaging/README.chromium
@@ -4,7 +4,7 @@
 Version: 21.0.1
 License: Android Software Development Kit License
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/README.chromium b/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/README.chromium
index cc0f8a13..71b0fe8 100644
--- a/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/README.chromium
+++ b/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.0.3
 License: Apache License V2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium
index 25f9cfc..db35aaf 100644
--- a/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium
+++ b/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.5
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_guava_failureaccess/README.chromium b/third_party/android_deps/libs/com_google_guava_failureaccess/README.chromium
index b4754b8..e55db1c 100644
--- a/third_party/android_deps/libs/com_google_guava_failureaccess/README.chromium
+++ b/third_party/android_deps/libs/com_google_guava_failureaccess/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0.1
 License: Apache 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_guava_guava/README.chromium b/third_party/android_deps/libs/com_google_guava_guava/README.chromium
index cbf09b89..a0277182 100644
--- a/third_party/android_deps/libs/com_google_guava_guava/README.chromium
+++ b/third_party/android_deps/libs/com_google_guava_guava/README.chromium
@@ -4,7 +4,7 @@
 Version: 31.0.1-jre
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_guava_guava_android/README.chromium b/third_party/android_deps/libs/com_google_guava_guava_android/README.chromium
index df702ff..a1f87dc 100644
--- a/third_party/android_deps/libs/com_google_guava_guava_android/README.chromium
+++ b/third_party/android_deps/libs/com_google_guava_guava_android/README.chromium
@@ -4,7 +4,7 @@
 Version: 31.0-android
 License: Apache 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_guava_listenablefuture/README.chromium b/third_party/android_deps/libs/com_google_guava_listenablefuture/README.chromium
index 7bdaa03..6b3a6946 100644
--- a/third_party/android_deps/libs/com_google_guava_listenablefuture/README.chromium
+++ b/third_party/android_deps/libs/com_google_guava_listenablefuture/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0
 License: Apache 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/README.chromium b/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/README.chromium
index ab0efa5..9ca941e 100644
--- a/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/README.chromium
+++ b/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.3
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_java/README.chromium b/third_party/android_deps/libs/com_google_protobuf_protobuf_java/README.chromium
index 5fc20920..e9aa394 100644
--- a/third_party/android_deps/libs/com_google_protobuf_protobuf_java/README.chromium
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_java/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.19.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/README.chromium b/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/README.chromium
index d561f27..386ef5fe 100644
--- a/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/README.chromium
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.19.3
 License: BSD
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/3pp.pb b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/3pp.pb
new file mode 100644
index 0000000..d8137c1
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/3pp.pb
@@ -0,0 +1,16 @@
+# 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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
+
+create {
+  source {
+    script { name: "fetch.py" }
+  }
+}
+
+upload {
+  pkg_prefix: "chromium/third_party/android_deps/libs"
+  universal: true
+}
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/fetch.py b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/fetch.py
new file mode 100755
index 0000000..3847823
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/3pp/fetch.py
@@ -0,0 +1,78 @@
+#!/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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy and
+# 3ppFetch.template instead.
+
+import argparse
+import json
+import os
+import re
+import urllib.request
+
+_REPO_URL = 'https://repo.maven.apache.org/maven2'
+_GROUP_NAME = 'com/google/protobuf'
+_MODULE_NAME = 'protobuf-lite'
+_FILE_EXT = 'jar'
+_OVERRIDE_LATEST = None
+_PATCH_VERSION = 'cr1'
+
+
+def do_latest():
+    if _OVERRIDE_LATEST is not None:
+        print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}')
+        return
+    maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format(
+        _REPO_URL, _GROUP_NAME, _MODULE_NAME)
+    metadata = urllib.request.urlopen(maven_metadata_url).read().decode(
+        'utf-8')
+    # Do not parse xml with the python included parser since it is susceptible
+    # to maliciously crafted xmls. Only use regular expression parsing to be
+    # safe. RE should be enough to handle what we need to extract.
+    match = re.search('<latest>([^<]+)</latest>', metadata)
+    if match:
+        latest = match.group(1)
+    else:
+        # if no latest info was found just hope the versions are sorted and the
+        # last one is the latest (as is commonly the case).
+        latest = re.findall('<version>([^<]+)</version>', metadata)[-1]
+    print(latest + f'.{_PATCH_VERSION}')
+
+
+def get_download_url(version):
+    # Remove the patch version when getting the download url
+    version_no_patch, patch = version.rsplit('.', 1)
+    if patch.startswith('cr'):
+        version = version_no_patch
+    file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME,
+                                                    _MODULE_NAME, version,
+                                                    _FILE_EXT)
+    file_name = file_url.rsplit('/', 1)[-1]
+
+    partial_manifest = {
+        'url': [file_url],
+        'name': [file_name],
+        'ext': '.' + _FILE_EXT,
+    }
+    print(json.dumps(partial_manifest))
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    sub = ap.add_subparsers()
+
+    latest = sub.add_parser('latest')
+    latest.set_defaults(func=lambda _opts: do_latest())
+
+    download = sub.add_parser('get_url')
+    download.set_defaults(
+        func=lambda _opts: get_download_url(os.environ['_3PP_VERSION']))
+
+    opts = ap.parse_args()
+    opts.func(opts)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE
new file mode 100644
index 0000000..19b305b0
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/LICENSE
@@ -0,0 +1,32 @@
+Copyright 2008 Google Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS
new file mode 100644
index 0000000..aea47a05
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium
new file mode 100644
index 0000000..3a44277
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/README.chromium
@@ -0,0 +1,14 @@
+Name: Protocol Buffers [Lite]
+Short Name: protobuf-lite
+URL: https://github.com/protocolbuffers/protobuf/blob/master/java/lite.md
+Version: 3.0.1
+License: BSD
+License File: NOT_SHIPPED
+CPEPrefix: unknown
+Security Critical: no
+
+Description:
+A trimmed-down version of the Protocol Buffers library.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml
new file mode 100644
index 0000000..a524b08
--- /dev/null
+++ b/third_party/android_deps/libs/com_google_protobuf_protobuf_lite/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2@3.0.1.cr1
+package: chromium/third_party/android_deps/libs/com_google_protobuf_protobuf_lite
+description: "Protocol Buffers [Lite]"
+data:
+- file: protobuf-lite-3.0.1.jar
diff --git a/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/README.chromium b/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/README.chromium
index 5b5a02d..81ba78b47 100644
--- a/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/README.chromium
+++ b/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.3.0
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_squareup_javapoet/README.chromium b/third_party/android_deps/libs/com_squareup_javapoet/README.chromium
index 627e730..5d7ad05 100644
--- a/third_party/android_deps/libs/com_squareup_javapoet/README.chromium
+++ b/third_party/android_deps/libs/com_squareup_javapoet/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.13.0
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/com_squareup_javawriter/README.chromium b/third_party/android_deps/libs/com_squareup_javawriter/README.chromium
index 4e51d250..be45f5a 100644
--- a/third_party/android_deps/libs/com_squareup_javawriter/README.chromium
+++ b/third_party/android_deps/libs/com_squareup_javawriter/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.1.1
 License: Apache 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/README.chromium b/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/README.chromium
index 8280d34..0dc1a62b 100644
--- a/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/README.chromium
+++ b/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.0
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/javax_annotation_javax_annotation_api/README.chromium b/third_party/android_deps/libs/javax_annotation_javax_annotation_api/README.chromium
index ab195bb7..f22436fb 100644
--- a/third_party/android_deps/libs/javax_annotation_javax_annotation_api/README.chromium
+++ b/third_party/android_deps/libs/javax_annotation_javax_annotation_api/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.3.2
 License: CDDLv1.1
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium b/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium
index c873d17..f7c63dc 100644
--- a/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium
+++ b/third_party/android_deps/libs/javax_annotation_jsr250_api/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.0
 License: CDDLv1.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium b/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium
index 5bce1f1f8..36ee0af3 100644
--- a/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium
+++ b/third_party/android_deps/libs/javax_inject_javax_inject/README.chromium
@@ -4,7 +4,7 @@
 Version: 1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/README.chromium b/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/README.chromium
index f65f509e..a9fe0e2 100644
--- a/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/README.chromium
+++ b/third_party/android_deps/libs/net_ltgt_gradle_incap_incap/README.chromium
@@ -4,7 +4,7 @@
 Version: 0.2
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium b/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium
index 1179a81..75eaaab 100644
--- a/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium
+++ b/third_party/android_deps/libs/net_sf_kxml_kxml2/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.3.0
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/README.chromium b/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/README.chromium
index 1558499..1057f79 100644
--- a/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/README.chromium
+++ b/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.2.1
 License: Apache License 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/README.chromium b/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/README.chromium
index 4e82be3..659eb8d 100644
--- a/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/README.chromium
+++ b/third_party/android_deps/libs/org_checkerframework_checker_compat_qual/README.chromium
@@ -4,7 +4,7 @@
 Version: 2.5.5
 License: GPL v2 with the classpath exception
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_checkerframework_checker_qual/README.chromium b/third_party/android_deps/libs/org_checkerframework_checker_qual/README.chromium
index 7dc76c85..71c4bda 100644
--- a/third_party/android_deps/libs/org_checkerframework_checker_qual/README.chromium
+++ b/third_party/android_deps/libs/org_checkerframework_checker_qual/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.12.0
 License: GPL v2 with the classpath exception
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/README.chromium b/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/README.chromium
index 9528b80..a3b31da 100644
--- a/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/README.chromium
+++ b/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.15.0
 License: GPL v2 with the classpath exception
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/README.chromium b/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/README.chromium
index bf699f9..7a16991 100644
--- a/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/README.chromium
+++ b/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.17
 License: MIT
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/README.chromium b/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/README.chromium
index f509643..bf38ef8 100644
--- a/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/README.chromium
+++ b/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.4.1.201607150455-r
 License: BSD 3-Clause
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/3pp.pb b/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/3pp.pb
new file mode 100644
index 0000000..d8137c1
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/3pp.pb
@@ -0,0 +1,16 @@
+# 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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
+
+create {
+  source {
+    script { name: "fetch.py" }
+  }
+}
+
+upload {
+  pkg_prefix: "chromium/third_party/android_deps/libs"
+  universal: true
+}
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/fetch.py b/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/fetch.py
new file mode 100755
index 0000000..3ad54d11
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/3pp/fetch.py
@@ -0,0 +1,78 @@
+#!/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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy and
+# 3ppFetch.template instead.
+
+import argparse
+import json
+import os
+import re
+import urllib.request
+
+_REPO_URL = 'https://repo.maven.apache.org/maven2'
+_GROUP_NAME = 'org/hamcrest'
+_MODULE_NAME = 'hamcrest'
+_FILE_EXT = 'jar'
+_OVERRIDE_LATEST = None
+_PATCH_VERSION = 'cr1'
+
+
+def do_latest():
+    if _OVERRIDE_LATEST is not None:
+        print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}')
+        return
+    maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format(
+        _REPO_URL, _GROUP_NAME, _MODULE_NAME)
+    metadata = urllib.request.urlopen(maven_metadata_url).read().decode(
+        'utf-8')
+    # Do not parse xml with the python included parser since it is susceptible
+    # to maliciously crafted xmls. Only use regular expression parsing to be
+    # safe. RE should be enough to handle what we need to extract.
+    match = re.search('<latest>([^<]+)</latest>', metadata)
+    if match:
+        latest = match.group(1)
+    else:
+        # if no latest info was found just hope the versions are sorted and the
+        # last one is the latest (as is commonly the case).
+        latest = re.findall('<version>([^<]+)</version>', metadata)[-1]
+    print(latest + f'.{_PATCH_VERSION}')
+
+
+def get_download_url(version):
+    # Remove the patch version when getting the download url
+    version_no_patch, patch = version.rsplit('.', 1)
+    if patch.startswith('cr'):
+        version = version_no_patch
+    file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME,
+                                                    _MODULE_NAME, version,
+                                                    _FILE_EXT)
+    file_name = file_url.rsplit('/', 1)[-1]
+
+    partial_manifest = {
+        'url': [file_url],
+        'name': [file_name],
+        'ext': '.' + _FILE_EXT,
+    }
+    print(json.dumps(partial_manifest))
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    sub = ap.add_subparsers()
+
+    latest = sub.add_parser('latest')
+    latest.set_defaults(func=lambda _opts: do_latest())
+
+    download = sub.add_parser('get_url')
+    download.set_defaults(
+        func=lambda _opts: get_download_url(os.environ['_3PP_VERSION']))
+
+    opts = ap.parse_args()
+    opts.func(opts)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/LICENSE b/third_party/android_deps/libs/org_hamcrest_hamcrest/LICENSE
new file mode 100644
index 0000000..4933bda5
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/LICENSE
@@ -0,0 +1,27 @@
+BSD License
+
+Copyright (c) 2000-2015 www.hamcrest.org
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of Hamcrest nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/OWNERS b/third_party/android_deps/libs/org_hamcrest_hamcrest/OWNERS
new file mode 100644
index 0000000..aea47a05
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/README.chromium b/third_party/android_deps/libs/org_hamcrest_hamcrest/README.chromium
new file mode 100644
index 0000000..0ac5311a
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/README.chromium
@@ -0,0 +1,14 @@
+Name: Hamcrest
+Short Name: hamcrest
+URL: http://hamcrest.org/JavaHamcrest/
+Version: 2.2
+License: BSD
+License File: NOT_SHIPPED
+CPEPrefix: unknown
+Security Critical: no
+
+Description:
+Core API and libraries of hamcrest matcher framework.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/org_hamcrest_hamcrest/cipd.yaml b/third_party/android_deps/libs/org_hamcrest_hamcrest/cipd.yaml
new file mode 100644
index 0000000..fd13495
--- /dev/null
+++ b/third_party/android_deps/libs/org_hamcrest_hamcrest/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2@2.2.cr1
+package: chromium/third_party/android_deps/libs/org_hamcrest_hamcrest
+description: "Hamcrest"
+data:
+- file: hamcrest-2.2.jar
diff --git a/third_party/android_deps/libs/org_jetbrains_annotations/README.chromium b/third_party/android_deps/libs/org_jetbrains_annotations/README.chromium
index a1201c3..f9c7cc5 100644
--- a/third_party/android_deps/libs/org_jetbrains_annotations/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 13.0
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/README.chromium
index cf2731a..95f6dd30 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.20
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/README.chromium
index 9dede05..070ef5a 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_common/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.20
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/README.chromium
index f8f548fc..8076984 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.20
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/README.chromium
index abcce66..ac6e84aa 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.20
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/README.chromium
index 36e2022..c09fa8c4 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/README.chromium
index b5c895d2..dd9b97f 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm/README.chromium
@@ -4,7 +4,7 @@
 Version: 1.6.1
 License: Apache Version 2.0
 License File: LICENSE
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: yes
 
 Description:
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/README.chromium b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/README.chromium
index d553a5d3..59db76b1 100644
--- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/README.chromium
+++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm/README.chromium
@@ -4,7 +4,7 @@
 Version: 0.1.0
 License: Apache Version 2.0
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/3pp/3pp.pb b/third_party/android_deps/libs/org_jsoup_jsoup/3pp/3pp.pb
new file mode 100644
index 0000000..d8137c1
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/3pp/3pp.pb
@@ -0,0 +1,16 @@
+# 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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
+
+create {
+  source {
+    script { name: "fetch.py" }
+  }
+}
+
+upload {
+  pkg_prefix: "chromium/third_party/android_deps/libs"
+  universal: true
+}
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/3pp/fetch.py b/third_party/android_deps/libs/org_jsoup_jsoup/3pp/fetch.py
new file mode 100755
index 0000000..e20447c
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/3pp/fetch.py
@@ -0,0 +1,78 @@
+#!/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.
+
+# This is generated, do not edit. Update BuildConfigGenerator.groovy and
+# 3ppFetch.template instead.
+
+import argparse
+import json
+import os
+import re
+import urllib.request
+
+_REPO_URL = 'https://repo.maven.apache.org/maven2'
+_GROUP_NAME = 'org/jsoup'
+_MODULE_NAME = 'jsoup'
+_FILE_EXT = 'jar'
+_OVERRIDE_LATEST = None
+_PATCH_VERSION = 'cr1'
+
+
+def do_latest():
+    if _OVERRIDE_LATEST is not None:
+        print(_OVERRIDE_LATEST + f'.{_PATCH_VERSION}')
+        return
+    maven_metadata_url = '{}/{}/{}/maven-metadata.xml'.format(
+        _REPO_URL, _GROUP_NAME, _MODULE_NAME)
+    metadata = urllib.request.urlopen(maven_metadata_url).read().decode(
+        'utf-8')
+    # Do not parse xml with the python included parser since it is susceptible
+    # to maliciously crafted xmls. Only use regular expression parsing to be
+    # safe. RE should be enough to handle what we need to extract.
+    match = re.search('<latest>([^<]+)</latest>', metadata)
+    if match:
+        latest = match.group(1)
+    else:
+        # if no latest info was found just hope the versions are sorted and the
+        # last one is the latest (as is commonly the case).
+        latest = re.findall('<version>([^<]+)</version>', metadata)[-1]
+    print(latest + f'.{_PATCH_VERSION}')
+
+
+def get_download_url(version):
+    # Remove the patch version when getting the download url
+    version_no_patch, patch = version.rsplit('.', 1)
+    if patch.startswith('cr'):
+        version = version_no_patch
+    file_url = '{0}/{1}/{2}/{3}/{2}-{3}.{4}'.format(_REPO_URL, _GROUP_NAME,
+                                                    _MODULE_NAME, version,
+                                                    _FILE_EXT)
+    file_name = file_url.rsplit('/', 1)[-1]
+
+    partial_manifest = {
+        'url': [file_url],
+        'name': [file_name],
+        'ext': '.' + _FILE_EXT,
+    }
+    print(json.dumps(partial_manifest))
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    sub = ap.add_subparsers()
+
+    latest = sub.add_parser('latest')
+    latest.set_defaults(func=lambda _opts: do_latest())
+
+    download = sub.add_parser('get_url')
+    download.set_defaults(
+        func=lambda _opts: get_download_url(os.environ['_3PP_VERSION']))
+
+    opts = ap.parse_args()
+    opts.func(opts)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/LICENSE b/third_party/android_deps/libs/org_jsoup_jsoup/LICENSE
new file mode 100644
index 0000000..fef8197f
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/LICENSE
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2009-2022 Jonathan Hedley <https://jsoup.org/>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/OWNERS b/third_party/android_deps/libs/org_jsoup_jsoup/OWNERS
new file mode 100644
index 0000000..aea47a05
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/OWNERS
@@ -0,0 +1 @@
+file://third_party/android_deps/OWNERS
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/README.chromium b/third_party/android_deps/libs/org_jsoup_jsoup/README.chromium
new file mode 100644
index 0000000..e524728b
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/README.chromium
@@ -0,0 +1,14 @@
+Name: jsoup Java HTML Parser
+Short Name: jsoup
+URL: https://jsoup.org/
+Version: 1.14.2
+License: The MIT License
+License File: NOT_SHIPPED
+CPEPrefix: cpe:/a:jsoup:jsoup:1.14.2
+Security Critical: no
+
+Description:
+jsoup is a Java library for working with real-world HTML. It provides a very convenient API for fetching URLs and extracting and manipulating data, using the best of HTML5 DOM methods and CSS selectors. jsoup implements the WHATWG HTML5 specification, and parses HTML to the same DOM as modern browsers do.
+
+Local Modifications:
+No modifications.
diff --git a/third_party/android_deps/libs/org_jsoup_jsoup/cipd.yaml b/third_party/android_deps/libs/org_jsoup_jsoup/cipd.yaml
new file mode 100644
index 0000000..51d32b1
--- /dev/null
+++ b/third_party/android_deps/libs/org_jsoup_jsoup/cipd.yaml
@@ -0,0 +1,10 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -tag version:2@1.14.2.cr1
+package: chromium/third_party/android_deps/libs/org_jsoup_jsoup
+description: "jsoup Java HTML Parser"
+data:
+- file: jsoup-1.14.2.jar
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm/README.chromium b/third_party/android_deps/libs/org_ow2_asm_asm/README.chromium
index 367ac19..310f30e 100644
--- a/third_party/android_deps/libs/org_ow2_asm_asm/README.chromium
+++ b/third_party/android_deps/libs/org_ow2_asm_asm/README.chromium
@@ -4,7 +4,7 @@
 Version: 9.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_analysis/README.chromium b/third_party/android_deps/libs/org_ow2_asm_asm_analysis/README.chromium
index 54318354..be91647 100644
--- a/third_party/android_deps/libs/org_ow2_asm_asm_analysis/README.chromium
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_analysis/README.chromium
@@ -4,7 +4,7 @@
 Version: 9.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_commons/README.chromium b/third_party/android_deps/libs/org_ow2_asm_asm_commons/README.chromium
index 2aa8cbc..8ddeded 100644
--- a/third_party/android_deps/libs/org_ow2_asm_asm_commons/README.chromium
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_commons/README.chromium
@@ -4,7 +4,7 @@
 Version: 9.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_tree/README.chromium b/third_party/android_deps/libs/org_ow2_asm_asm_tree/README.chromium
index 40d4fb4..68ff5fa 100644
--- a/third_party/android_deps/libs/org_ow2_asm_asm_tree/README.chromium
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_tree/README.chromium
@@ -4,7 +4,7 @@
 Version: 9.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_ow2_asm_asm_util/README.chromium b/third_party/android_deps/libs/org_ow2_asm_asm_util/README.chromium
index 77f0add6..5c8724252 100644
--- a/third_party/android_deps/libs/org_ow2_asm_asm_util/README.chromium
+++ b/third_party/android_deps/libs/org_ow2_asm_asm_util/README.chromium
@@ -4,7 +4,7 @@
 Version: 9.2
 License: BSD
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_pcollections_pcollections/README.chromium b/third_party/android_deps/libs/org_pcollections_pcollections/README.chromium
index 0571611..4c2649c 100644
--- a/third_party/android_deps/libs/org_pcollections_pcollections/README.chromium
+++ b/third_party/android_deps/libs/org_pcollections_pcollections/README.chromium
@@ -4,7 +4,7 @@
 Version: 3.1.4
 License: The MIT License
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_annotations/README.chromium b/third_party/android_deps/libs/org_robolectric_annotations/README.chromium
index 0b8ccd9..aaacc62 100644
--- a/third_party/android_deps/libs/org_robolectric_annotations/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_annotations/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_junit/README.chromium b/third_party/android_deps/libs/org_robolectric_junit/README.chromium
index 3d67cce4..a8f3602 100644
--- a/third_party/android_deps/libs/org_robolectric_junit/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_junit/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium b/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium
index 65a61d4..6ae38dd 100644
--- a/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_nativeruntime/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_pluginapi/README.chromium b/third_party/android_deps/libs/org_robolectric_pluginapi/README.chromium
index 7e673f3..05478a7 100644
--- a/third_party/android_deps/libs/org_robolectric_pluginapi/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_pluginapi/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/README.chromium b/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/README.chromium
index 4f8dae0..5a975aa8 100644
--- a/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_resources/README.chromium b/third_party/android_deps/libs/org_robolectric_resources/README.chromium
index 3630c650..1bf85c2 100644
--- a/third_party/android_deps/libs/org_robolectric_resources/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_resources/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_robolectric/README.chromium b/third_party/android_deps/libs/org_robolectric_robolectric/README.chromium
index 7fb747d..5ea39ea 100644
--- a/third_party/android_deps/libs/org_robolectric_robolectric/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_robolectric/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_sandbox/README.chromium b/third_party/android_deps/libs/org_robolectric_sandbox/README.chromium
index 7cb1ea9..d71e8a23 100644
--- a/third_party/android_deps/libs/org_robolectric_sandbox/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_sandbox/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_shadowapi/README.chromium b/third_party/android_deps/libs/org_robolectric_shadowapi/README.chromium
index d70c8b6..406fb4d38 100644
--- a/third_party/android_deps/libs/org_robolectric_shadowapi/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_shadowapi/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_framework/README.chromium b/third_party/android_deps/libs/org_robolectric_shadows_framework/README.chromium
index ddf28d4..b31e4ff 100644
--- a/third_party/android_deps/libs/org_robolectric_shadows_framework/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_shadows_framework/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_multidex/README.chromium b/third_party/android_deps/libs/org_robolectric_shadows_multidex/README.chromium
index b2807c64..b724bbad 100644
--- a/third_party/android_deps/libs/org_robolectric_shadows_multidex/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_shadows_multidex/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_shadows_playservices/README.chromium b/third_party/android_deps/libs/org_robolectric_shadows_playservices/README.chromium
index 8cb5759f..22bedc3 100644
--- a/third_party/android_deps/libs/org_robolectric_shadows_playservices/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_shadows_playservices/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_utils/README.chromium b/third_party/android_deps/libs/org_robolectric_utils/README.chromium
index 93d0d06..747c02c4 100644
--- a/third_party/android_deps/libs/org_robolectric_utils/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_utils/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/libs/org_robolectric_utils_reflector/README.chromium b/third_party/android_deps/libs/org_robolectric_utils_reflector/README.chromium
index 79eb030a..cba643f 100644
--- a/third_party/android_deps/libs/org_robolectric_utils_reflector/README.chromium
+++ b/third_party/android_deps/libs/org_robolectric_utils_reflector/README.chromium
@@ -4,7 +4,7 @@
 Version: 4.7.3
 License: MIT
 License File: NOT_SHIPPED
-CPEPrefix: null
+CPEPrefix: unknown
 Security Critical: no
 
 Description:
diff --git a/third_party/android_deps/local_modifications/preconditions/javatests/BUILD.gn b/third_party/android_deps/local_modifications/preconditions/javatests/BUILD.gn
index ff763309..952a192 100644
--- a/third_party/android_deps/local_modifications/preconditions/javatests/BUILD.gn
+++ b/third_party/android_deps/local_modifications/preconditions/javatests/BUILD.gn
@@ -9,7 +9,6 @@
   sources = [ "org/chromium/preconditions/PreconditionsTest.java" ]
   deps = [
     "$google_play_services_package:google_play_services_basement_java",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base/test:test_support_java",
     "//build/android:build_java",
diff --git a/third_party/blink/PRESUBMIT.py b/third_party/blink/PRESUBMIT.py
index 808f9a5..4ea03fc 100644
--- a/third_party/blink/PRESUBMIT.py
+++ b/third_party/blink/PRESUBMIT.py
@@ -130,7 +130,8 @@
             output_api,
             excluded_paths=_EXCLUDED_PATHS,
             maxlen=800,
-            license_header=license_header))
+            license_header=license_header,
+            global_checks=False))
     results.extend(_CheckForWrongMojomIncludes(input_api, output_api))
     return results
 
@@ -243,7 +244,4 @@
 def CheckChangeOnCommit(input_api, output_api):
     results = []
     results.extend(_CommonChecks(input_api, output_api))
-    results.extend(
-        input_api.canned_checks.CheckChangeHasDescription(
-            input_api, output_api))
     return results
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn
index 2e9fedd9..18a2d577 100644
--- a/third_party/blink/common/BUILD.gn
+++ b/third_party/blink/common/BUILD.gn
@@ -302,7 +302,6 @@
   ]
   if (is_android) {
     deps += [
-      "//base:base_java",
       "//build/android:build_java",
       "//media/base/android:media_java",
     ]
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 0047424..4c07505 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -331,6 +331,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_is_visible_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_is_visible_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state_init.cc",
diff --git a/third_party/blink/renderer/controller/BUILD.gn b/third_party/blink/renderer/controller/BUILD.gn
index 07f5a8bd..550eac0 100644
--- a/third_party/blink/renderer/controller/BUILD.gn
+++ b/third_party/blink/renderer/controller/BUILD.gn
@@ -137,7 +137,6 @@
 
   if (is_android) {
     deps += [
-      "//base:base_java",
       "//build/android:build_java",
       "//content/public/android:content_java",
       "//content/shell/android:content_shell_assets",
diff --git a/third_party/blink/renderer/core/css/popup.css b/third_party/blink/renderer/core/css/popup.css
index 65a6296..bf6e09b 100644
--- a/third_party/blink/renderer/core/css/popup.css
+++ b/third_party/blink/renderer/core/css/popup.css
@@ -33,3 +33,15 @@
   background: -internal-light-dark(white, black);
   color: -internal-light-dark(black, white);
 }
+
+[popup=popup i]::backdrop,
+[popup=hint i]::backdrop,
+[popup=async i]::backdrop {
+    position: fixed;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    background: transparent;
+    pointer-events: none !important;
+}
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index c244d1f..04fc525 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -249,8 +249,9 @@
 
 DisplayLockUtilities::ScopedForcedUpdate::Impl::Impl(
     const Range* range,
-    DisplayLockContext::ForcedPhase phase)
-    : node_(range->FirstNode()), phase_(phase) {
+    DisplayLockContext::ForcedPhase phase,
+    bool only_cv_auto)
+    : node_(range->FirstNode()), phase_(phase), only_cv_auto_(only_cv_auto) {
   if (!node_)
     return;
 
@@ -316,8 +317,10 @@
 DisplayLockUtilities::ScopedForcedUpdate::Impl::Impl(
     const Node* node,
     DisplayLockContext::ForcedPhase phase,
-    bool include_self)
-    : node_(node), phase_(phase) {
+    bool include_self,
+    bool only_cv_auto,
+    bool emit_warnings)
+    : node_(node), phase_(phase), only_cv_auto_(only_cv_auto) {
   if (!node_)
     return;
 
@@ -362,12 +365,11 @@
     if (!ancestor_node)
       continue;
     if (auto* context = ancestor_node->GetDisplayLockContext()) {
-      if (context->IsLocked() &&
+      if (emit_warnings && context->IsLocked() &&
           !context->IsActivatable(DisplayLockActivationReason::kAny)) {
         WarnOnForcedUpdateInNonActivatableContext(node->GetDocument());
       }
-      context->NotifyForcedUpdateScopeStarted(phase_);
-      forced_context_set_.insert(context);
+      ForceDisplayLockIfNeeded(context);
     }
   }
 }
@@ -397,9 +399,18 @@
 
 void DisplayLockUtilities::ScopedForcedUpdate::Impl::
     AddForcedUpdateScopeForContext(DisplayLockContext* context) {
-  auto result = forced_context_set_.insert(context);
-  if (result.is_new_entry)
+  if (!forced_context_set_.Contains(context)) {
+    ForceDisplayLockIfNeeded(context);
+  }
+}
+
+void DisplayLockUtilities::ScopedForcedUpdate::Impl::ForceDisplayLockIfNeeded(
+    DisplayLockContext* context) {
+  if (!only_cv_auto_ ||
+      context->IsActivatable(DisplayLockActivationReason::kViewport)) {
+    forced_context_set_.insert(context);
     context->NotifyForcedUpdateScopeStarted(phase_);
+  }
 }
 
 Element* DisplayLockUtilities::NearestHiddenMatchableInclusiveAncestor(
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
index 549370a..439990ac 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
@@ -62,6 +62,7 @@
     FrameSelection::ComputeVisibleSelectionInDOMTreeDeprecated() const;
     friend gfx::RectF Range::BoundingRect() const;
     friend DOMRectList* Range::getClientRects() const;
+    friend bool Element::isVisible(IsVisibleOptions*) const;
 
     friend class DisplayLockContext;
 
@@ -69,12 +70,21 @@
     friend class DisplayLockContextRenderingTest;
     friend class DisplayLockContextTest;
 
+    // This method will emit console warnings for content-visibility:hidden
+    // subtrees when |emit_warnings| is true and |only_cv_auto| is false.
     explicit ScopedForcedUpdate(const Node* node,
                                 DisplayLockContext::ForcedPhase phase,
-                                bool include_self = false)
-        : impl_(MakeGarbageCollected<Impl>(node, phase, include_self)) {}
+                                bool include_self = false,
+                                bool only_cv_auto = false,
+                                bool emit_warnings = true)
+        : impl_(MakeGarbageCollected<Impl>(node,
+                                           phase,
+                                           include_self,
+                                           only_cv_auto,
+                                           emit_warnings)) {}
     explicit ScopedForcedUpdate(const Range* range,
-                                DisplayLockContext::ForcedPhase phase)
+                                DisplayLockContext::ForcedPhase phase,
+                                bool only_cv_auto = false)
         : impl_(MakeGarbageCollected<Impl>(range, phase)) {}
 
     friend class DisplayLockDocumentState;
@@ -83,8 +93,12 @@
      public:
       Impl(const Node* node,
            DisplayLockContext::ForcedPhase phase,
-           bool include_self = false);
-      Impl(const Range* range, DisplayLockContext::ForcedPhase phase);
+           bool include_self = false,
+           bool only_cv_auto = false,
+           bool emit_warnings = true);
+      Impl(const Range* range,
+           DisplayLockContext::ForcedPhase phase,
+           bool only_cv_auto = false);
 
       // Adds another display-lock scope to this chain. Added when a new lock is
       // created in the ancestor chain of this chain's node.
@@ -101,10 +115,13 @@
       }
 
      private:
+      void ForceDisplayLockIfNeeded(DisplayLockContext* context);
+
       Member<const Node> node_;
       DisplayLockContext::ForcedPhase phase_;
       HeapHashSet<Member<DisplayLockContext>> forced_context_set_;
       Member<Impl> parent_frame_impl_;
+      bool only_cv_auto_;
     };
 
     Impl* impl_ = nullptr;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 55dfa7e..b4e5357 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -40,6 +40,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_get_inner_html_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_is_visible_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_pointer_lock_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_scroll_to_options.h"
@@ -7849,4 +7850,62 @@
   return GetElementRareData()->GetFocusgroupFlags();
 }
 
+bool Element::isVisible(IsVisibleOptions* options) const {
+  // Unlock ancestor content-visibility:auto elements. If this element is
+  // offscreen and locked due to content-visibility:auto, this method should not
+  // count that as invisible.
+  DisplayLockUtilities::ScopedForcedUpdate force_locks(
+      this, DisplayLockContext::ForcedPhase::kStyleAndLayoutTree,
+      /*include_self=*/false, /*only_cv_auto=*/true,
+      /*emit_warnings=*/false);
+  GetDocument().UpdateStyleAndLayoutTree();
+
+  if (!GetLayoutObject())
+    return false;
+
+  auto* style = GetComputedStyle();
+  if (!style)
+    return false;
+
+  DCHECK(options);
+  if (options->checkVisibilityCSS() &&
+      style->Visibility() != EVisibility::kVisible) {
+    return false;
+  }
+
+  for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*this)) {
+    // Check for content-visibility:hidden
+    if (&ancestor != this) {
+      if (Element* ancestor_element = DynamicTo<Element>(ancestor)) {
+        if (auto* lock = ancestor_element->GetDisplayLockContext()) {
+          if (lock->IsLocked() &&
+              !lock->IsActivatable(DisplayLockActivationReason::kViewport)) {
+            return false;
+          }
+        }
+      }
+    }
+
+    // Check for opacity:0
+    if (options->checkOpacity()) {
+      if (auto* style = ancestor.GetComputedStyle()) {
+        if (style->Opacity() == 0.f) {
+          return false;
+        }
+      }
+    }
+
+    // Check for inert
+    if (options->checkInert()) {
+      if (HTMLElement* ancestor_element = DynamicTo<HTMLElement>(&ancestor)) {
+        if (ancestor_element->IsInertRoot()) {
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 968d8e8..322af19 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -101,6 +101,7 @@
 class ResizeObserver;
 class ResizeObserverSize;
 class ScrollIntoViewOptions;
+class IsVisibleOptions;
 class ScrollToOptions;
 class ShadowRoot;
 class ShadowRootInit;
@@ -1126,6 +1127,8 @@
 
   FocusgroupFlags GetFocusgroupFlags() const;
 
+  bool isVisible(IsVisibleOptions* options) const;
+
  protected:
   const ElementData* GetElementData() const { return element_data_.Get(); }
   UniqueElementData& EnsureUniqueElementData();
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl
index 9530b71..9eda33b 100644
--- a/third_party/blink/renderer/core/dom/element.idl
+++ b/third_party/blink/renderer/core/dom/element.idl
@@ -24,6 +24,13 @@
 enum NativeScrollBehavior { "disable-native-scroll", "perform-before-native-scroll", "perform-after-native-scroll" };
 callback ScrollStateCallback = void (ScrollState scrollState);
 
+// https://drafts.csswg.org/cssom-view/#dictdef-isvisibleoptions
+dictionary IsVisibleOptions {
+  boolean checkInert = false;
+  boolean checkOpacity = false;
+  boolean checkVisibilityCSS = false;
+};
+
 // https://dom.spec.whatwg.org/#interface-element
 
 [
@@ -111,6 +118,9 @@
     [Measure] DOMRectList getClientRects();
     [Affects=Nothing, Measure, RuntimeCallStatsCounter=ElementGetBoundingClientRect] DOMRect getBoundingClientRect();
 
+    // https://drafts.csswg.org/cssom-view/#dom-element-isvisible
+    [RuntimeEnabled=isVisible] boolean isVisible(optional IsVisibleOptions options = {});
+
     // TODO(sunyunjia): Add default value for scrollIntoView() once
     // crbug.com/734599 is fixed.
     void scrollIntoView(optional (ScrollIntoViewOptions or boolean) arg = {});
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index 28eb99e..4ddcbe7 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -30,9 +30,6 @@
 
 #include "third_party/blink/renderer/core/frame/frame_serializer.h"
 
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/time/time.h"
 #include "third_party/blink/renderer/core/css/css_font_face_rule.h"
 #include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
 #include "third_party/blink/renderer/core/css/css_image_value.h"
@@ -67,7 +64,6 @@
 #include "third_party/blink/renderer/core/style/style_image.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/mhtml/serialized_resource.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
@@ -285,14 +281,7 @@
 
 FrameSerializer::FrameSerializer(Deque<SerializedResource>& resources,
                                  Delegate& delegate)
-    : resources_(&resources),
-      is_serializing_css_(false),
-      delegate_(delegate),
-      total_image_count_(0),
-      loaded_image_count_(0),
-      total_css_count_(0),
-      loaded_css_count_(0),
-      should_collect_problem_metric_(false) {}
+    : resources_(&resources), delegate_(delegate) {}
 
 void FrameSerializer::SerializeFrame(const LocalFrame& frame) {
   TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame");
@@ -306,12 +295,8 @@
     return;
   }
 
-  should_collect_problem_metric_ =
-      delegate_.ShouldCollectProblemMetric() && frame.IsMainFrame();
   {
     TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame HTML");
-    SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
-        "PageSerialization.SerializationTime.Html");
     SerializerMarkupAccumulator accumulator(delegate_, *this, document);
     String text =
         accumulator.SerializeNodes<EditingStrategy>(document, kIncludeNode);
@@ -323,34 +308,6 @@
         url, document.SuggestedMIMEType(),
         SharedBuffer::Create(frame_html.c_str(), frame_html.length())));
   }
-
-  if (should_collect_problem_metric_) {
-    // Report detectors through UMA.
-    // Note: some of these histograms used 21 buckets to try to ensure each
-    // bucket covered 5% of the range. Unfortunately, there was an off-by-one
-    // error... but changing the meaning of buckets is annoying.
-    base::UmaHistogramCounts100(
-        "PageSerialization.ProblemDetection.TotalImageCount",
-        total_image_count_);
-    if (total_image_count_ > 0) {
-      DCHECK_LE(loaded_image_count_, total_image_count_);
-      base::LinearHistogram::FactoryGet(
-          "PageSerialization.ProblemDetection.LoadedImagePercentage", 1, 100,
-          21, base::HistogramBase::kUmaTargetedHistogramFlag)
-          ->Add(loaded_image_count_ * 100 / total_image_count_);
-    }
-
-    base::UmaHistogramCounts100(
-        "PageSerialization.ProblemDetection.TotalCSSCount", total_css_count_);
-    if (total_css_count_ > 0) {
-      DCHECK_LE(loaded_css_count_, total_css_count_);
-      base::LinearHistogram::FactoryGet(
-          "PageSerialization.ProblemDetection.LoadedCSSPercentage", 1, 100, 21,
-          base::HistogramBase::kUmaTargetedHistogramFlag)
-          ->Add(loaded_css_count_ * 100 / total_css_count_);
-    }
-    should_collect_problem_metric_ = false;
-  }
 }
 
 void FrameSerializer::AddResourceForElement(Document& document,
@@ -415,20 +372,9 @@
   }
   if (!is_inline_css)
     resource_urls_.insert(url);
-  if (should_collect_problem_metric_ && !is_inline_css) {
-    total_css_count_++;
-    if (style_sheet.LoadCompleted())
-      loaded_css_count_++;
-  }
 
   TRACE_EVENT2("page-serialization", "FrameSerializer::serializeCSSStyleSheet",
                "type", "CSS", "url", url.ElidedString().Utf8());
-  // Only report UMA metric if this is not a reentrant CSS serialization call.
-  base::TimeTicks css_start_time;
-  if (!is_serializing_css_) {
-    is_serializing_css_ = true;
-    css_start_time = base::TimeTicks::Now();
-  }
 
   // If this CSS is inlined its definition was already serialized with the frame
   // HTML code that was previously generated. No need to regenerate it here.
@@ -463,13 +409,6 @@
   // need to be.
   for (unsigned i = 0; i < style_sheet.length(); ++i)
     SerializeCSSRule(style_sheet.item(i));
-
-  if (css_start_time != base::TimeTicks()) {
-    is_serializing_css_ = false;
-    base::UmaHistogramMicrosecondsTimes(
-        "PageSerialization.SerializationTime.CSSElement",
-        base::TimeTicks::Now() - css_start_time);
-  }
 }
 
 void FrameSerializer::SerializeCSSRule(CSSRule* rule) {
@@ -551,28 +490,13 @@
   if (!ShouldAddURL(url))
     return;
   resource_urls_.insert(url);
-  if (should_collect_problem_metric_)
-    total_image_count_++;
   if (!image || !image->HasImage() || image->ErrorOccurred())
     return;
-  if (should_collect_problem_metric_ && image->IsLoaded())
-    loaded_image_count_++;
 
   TRACE_EVENT2("page-serialization", "FrameSerializer::addImageToResources",
                "type", "image", "url", url.ElidedString().Utf8());
-  base::TimeTicks image_start_time = base::TimeTicks::Now();
-
   scoped_refptr<const SharedBuffer> data = image->GetImage()->Data();
-  AddToResources(image->GetResponse().MimeType(),
-                 data, url);
-
-  // If we're already reporting time for CSS serialization don't report it for
-  // this image to avoid reporting the same time twice.
-  if (!is_serializing_css_) {
-    base::UmaHistogramMicrosecondsTimes(
-        "PageSerialization.SerializationTime.ImageElement",
-        base::TimeTicks::Now() - image_start_time);
-  }
+  AddToResources(image->GetResponse().MimeType(), data, url);
 }
 
 void FrameSerializer::AddFontToResources(FontResource& font) {
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.h b/third_party/blink/renderer/core/frame/frame_serializer.h
index 2abe6f3..22d58d0 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.h
+++ b/third_party/blink/renderer/core/frame/frame_serializer.h
@@ -158,16 +158,7 @@
   // This hashset is only used for de-duplicating resources to be serialized.
   HashSet<KURL> resource_urls_;
 
-  bool is_serializing_css_;
-
   Delegate& delegate_;
-
-  // Variables for problem detection during serialization.
-  int total_image_count_;
-  int loaded_image_count_;
-  int total_css_count_;
-  int loaded_css_count_;
-  bool should_collect_problem_metric_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js b/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js
index 9f715136..f3738dc1 100644
--- a/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js
+++ b/third_party/blink/renderer/core/html/forms/resources/calendar_picker.js
@@ -2178,6 +2178,27 @@
      */
     this._timer = null;
 
+    /**
+     * @type {?function}
+     * @protected
+     */
+    this._mouseUpEventListener = null;
+    /**
+     * @type {?function}
+     * @protected
+     */
+    this._mouseMoveEventListener = null;
+    /**
+     * @type {?function}
+     * @protected
+     */
+    this._touchEndEventListener = null;
+    /**
+     * @type {?function}
+     * @protected
+     */
+    this._touchMoveEventListener = null;
+
     this.element.addEventListener(
         'mousedown', this.onMouseDown.bind(this), false);
     this.element.addEventListener(
@@ -2200,10 +2221,10 @@
       this._thumbStyleTopAnimator.stop();
     this._timer = setInterval(
         this.onScrollTimer.bind(this), ScrubbyScrollBar.ScrollInterval);
-    window.addEventListener(
-        'touchmove', this.onWindowTouchMove.bind(this), false);
-    window.addEventListener(
-        'touchend', this.onWindowTouchEnd.bind(this), false);
+    this._touchMoveEventListener = this.onWindowTouchMove.bind(this);
+    window.addEventListener('touchmove', this._touchMoveEventListener, false);
+    this._touchEndEventListener = this.onWindowTouchEnd.bind(this);
+    window.addEventListener('touchend', this._touchEndEventListener, false);
     event.stopPropagation();
     event.preventDefault();
   }
@@ -2231,8 +2252,9 @@
     this._thumbStyleTopAnimator.duration = 100;
     this._thumbStyleTopAnimator.start();
 
-    window.removeEventListener('touchmove', this.onWindowTouchMove, false);
-    window.removeEventListener('touchend', this.onWindowTouchEnd, false);
+    window.removeEventListener(
+        'touchmove', this._touchMoveEventListener, false);
+    window.removeEventListener('touchend', this._touchEndEventListener, false);
     clearInterval(this._timer);
   }
 
@@ -2290,9 +2312,10 @@
   onMouseDown(event) {
     this._setThumbPositionFromEventPosition(event.clientY);
 
-    window.addEventListener(
-        'mousemove', this.onWindowMouseMove.bind(this), false);
-    window.addEventListener('mouseup', this.onWindowMouseUp.bind(this), false);
+    this._mouseMoveEventListener = this.onWindowMouseMove.bind(this);
+    window.addEventListener('mousemove', this._mouseMoveEventListener, false);
+    this._mouseUpEventListener = this.onWindowMouseUp.bind(this);
+    window.addEventListener('mouseup', this._mouseUpEventListener, false);
     if (this._thumbStyleTopAnimator)
       this._thumbStyleTopAnimator.stop();
     this._timer = setInterval(
@@ -2313,7 +2336,8 @@
    */
   onWindowMouseUp(event) {
     this._thumbStyleTopAnimator = new TransitionAnimator();
-    this._thumbStyleTopAnimator.step = this.onThumbStyleTopAnimationStep;
+    this._thumbStyleTopAnimator.step =
+        this.onThumbStyleTopAnimationStep.bind(this);
     this._thumbStyleTopAnimator.setFrom(this.thumb.offsetTop);
     this._thumbStyleTopAnimator.setTo((this._height - this._thumbHeight) / 2);
     this._thumbStyleTopAnimator.timingFunction =
@@ -2321,8 +2345,9 @@
     this._thumbStyleTopAnimator.duration = 100;
     this._thumbStyleTopAnimator.start();
 
-    window.removeEventListener('mousemove', this.onWindowMouseMove, false);
-    window.removeEventListener('mouseup', this.onWindowMouseUp, false);
+    window.removeEventListener(
+        'mousemove', this._mouseMoveEventListener, false);
+    window.removeEventListener('mouseup', this._mouseUpEventListener, false);
     clearInterval(this._timer);
   }
 
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 e773885a..a8917c9 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
@@ -639,9 +639,10 @@
     const NGBreakToken* child_break_token = entry.token;
 
     if (child.IsOutOfFlowPositioned()) {
-      // We don't support fragmentation inside out-of-flow positioned boxes yet,
-      // but breaking before is fine. This may happen when a column spanner is
-      // directly followed by an OOF.
+      // Out-of-flow fragmentation is a special step that takes place after
+      // regular layout, so we should never resume anything here. However, we
+      // may have break-before tokens, when a column spanner is directly
+      // followed by an OOF.
       DCHECK(!child_break_token ||
              (child_break_token->IsBlockType() &&
               To<NGBlockBreakToken>(child_break_token)->IsBreakBefore()));
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index e2adcbd..2730acb 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -35,6 +35,7 @@
 #include "cc/trees/layer_tree_host.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/common/widget/device_emulation_params.h"
 #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
 #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-blink.h"
@@ -465,7 +466,7 @@
       : type_(type),
         optimizer_flag_(
             base::MakeRefCounted<base::RefCountedData<std::atomic_bool>>(
-                base::in_place,
+                absl::in_place,
                 false)) {}
 
   ScriptPromise start(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/media/audio/mojo_audio_input_ipc_test.cc b/third_party/blink/renderer/modules/media/audio/mojo_audio_input_ipc_test.cc
index d7c22ac2..5d822c95 100644
--- a/third_party/blink/renderer/modules/media/audio/mojo_audio_input_ipc_test.cc
+++ b/third_party/blink/renderer/modules/media/audio/mojo_audio_input_ipc_test.cc
@@ -26,6 +26,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 
 using testing::_;
 using testing::AtLeast;
@@ -127,7 +128,7 @@
     factory_client_->StreamCreated(
         receiver_.BindNewPipeAndPassRemote(),
         stream_client_.BindNewPipeAndPassReceiver(),
-        {base::in_place,
+        {absl::in_place,
          base::ReadOnlySharedMemoryRegion::Create(kMemoryLength).region,
          mojo::PlatformHandle(foreign_socket.Take())},
         initially_muted_, base::UnguessableToken::Create());
diff --git a/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc
index 7ae2abb..21ffaee 100644
--- a/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc
+++ b/third_party/blink/renderer/modules/media/audio/mojo_audio_output_ipc_test.cc
@@ -21,6 +21,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/abseil-cpp/absl/utility/utility.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/renderer/platform/wtf/functional.h"
 
@@ -80,7 +81,7 @@
         base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
     provider_client_->Created(
         std::move(stream_pending_remote),
-        {base::in_place, base::UnsafeSharedMemoryRegion::Create(kMemoryLength),
+        {absl::in_place, base::UnsafeSharedMemoryRegion::Create(kMemoryLength),
          mojo::PlatformHandle(foreign_socket.Take())});
   }
 
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn
index 4496905..a504d3b7 100644
--- a/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -115,7 +115,6 @@
 
   if (is_android) {
     deps += [
-      "//base:base_java",
       "//build/android:build_java",
       "//content/shell/android:content_shell_assets",
       "//net/android:net_java",
@@ -184,7 +183,6 @@
 
   if (is_android) {
     deps += [
-      "//base:base_java",
       "//build/android:build_java",
       "//content/shell/android:content_shell_assets",
       "//net/android:net_java",
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index cd89b475..d17b334 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1304,6 +1304,10 @@
       status: "stable",
     },
     {
+      name: "isVisible",
+      status: "experimental",
+    },
+    {
       name: "KeyboardAccessibleTooltip",
       status: "experimental",
     },
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index 40566b4..2022318 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -107,7 +107,7 @@
             'base::WritableSharedMemoryMapping',
             'base::as_bytes',
             'base::bit_cast',
-            'base::in_place',
+            'absl::in_place',
             'absl::make_optional',
             'base::make_span',
             'absl::nullopt',
diff --git a/third_party/blink/tools/blinkpy/w3c/export_notifier.py b/third_party/blink/tools/blinkpy/w3c/export_notifier.py
index de0e018..3163633 100644
--- a/third_party/blink/tools/blinkpy/w3c/export_notifier.py
+++ b/third_party/blink/tools/blinkpy/w3c/export_notifier.py
@@ -55,8 +55,7 @@
             if not check_runs:
                 continue
 
-            checks_results = self.get_relevant_failed_taskcluster_checks(
-                check_runs, pr.number)
+            checks_results = self.get_relevant_failed_taskcluster_checks(check_runs)
             if not checks_results:
                 continue
 
@@ -139,13 +138,12 @@
 
         return False
 
-    def get_relevant_failed_taskcluster_checks(self, check_runs, pr_number):
+    def get_relevant_failed_taskcluster_checks(self, check_runs):
         """Filters relevant failed Taskcluster checks from check_runs.
 
         Args:
             check_runs: A JSON array; e.g. "check_runs" in
                 https://developer.github.com/v3/checks/runs/#response-3
-            pr_number: The PR number.
 
         Returns:
             A dictionary where keys are names of the Taskcluster checks and values
@@ -155,8 +153,7 @@
         for check in check_runs:
             if (check['conclusion'] == 'failure') and (
                     check['name'] in RELEVANT_TASKCLUSTER_CHECKS):
-                result_url = '{}pull/{}/checks?check_run_id={}'.format(
-                    WPT_GH_URL, pr_number, check['id'])
+                result_url = '{}runs/{}'.format(WPT_GH_URL, check['id'])
                 checks_results[check['name']] = result_url
 
         return checks_results
diff --git a/third_party/blink/tools/blinkpy/w3c/export_notifier_unittest.py b/third_party/blink/tools/blinkpy/w3c/export_notifier_unittest.py
index f792d54..4204929 100644
--- a/third_party/blink/tools/blinkpy/w3c/export_notifier_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/export_notifier_unittest.py
@@ -87,18 +87,18 @@
         ]
         expected = {
             'wpt-chrome-dev-stability':
-            'https://github.com/web-platform-tests/wpt/pull/123/checks?check_run_id=1',
+            'https://github.com/web-platform-tests/wpt/runs/1',
             'wpt-firefox-nightly-stability':
-            'https://github.com/web-platform-tests/wpt/pull/123/checks?check_run_id=2',
+            'https://github.com/web-platform-tests/wpt/runs/2',
             'lint':
-            'https://github.com/web-platform-tests/wpt/pull/123/checks?check_run_id=3',
+            'https://github.com/web-platform-tests/wpt/runs/3',
             'infrastructure/ tests':
-            'https://github.com/web-platform-tests/wpt/pull/123/checks?check_run_id=4',
+            'https://github.com/web-platform-tests/wpt/runs/4',
         }
 
         self.assertEqual(
             self.notifier.get_relevant_failed_taskcluster_checks(
-                check_runs, 123), expected)
+                check_runs), expected)
 
     def test_get_relevant_failed_taskcluster_checks_empty(self):
         check_runs = [
@@ -116,7 +116,7 @@
 
         self.assertEqual(
             self.notifier.get_relevant_failed_taskcluster_checks(
-                check_runs, 123), {})
+                check_runs), {})
 
     def test_has_latest_taskcluster_status_commented_false(self):
         pr_status_info = PRStatusInfo('bar', 123, 'SHA')
@@ -320,7 +320,7 @@
         ]
         checks_results = {
             'wpt-chrome-dev-stability':
-            'https://github.com/web-platform-tests/wpt/pull/1234/checks?check_run_id=123'
+            'https://github.com/web-platform-tests/wpt/runs/123'
         }
 
         self.notifier.dry_run = False
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index a6b3a73..83064c5d 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -29,6 +29,9 @@
 # Temporarily disabled for DevTools.
 crbug.com/1304217 http/tests/devtools/text-source-map.js [ Skip ]
 
+# Temporarily disabled while making DevTools change
+crbug.com/1192230 http/tests/devtools/network/network-serviceworker-timing-view.js [ Skip ]
+
 # Expected to time out.
 external/wpt/infrastructure/expected-fail/timeout.html [ Timeout ]
 external/wpt/infrastructure/reftest/reftest_ref_timeout.html [ Timeout ]
@@ -3388,6 +3391,7 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac11 ] external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/tentative/same-document-traversal-cross-document-traversal.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/css/css-sizing/aspect-ratio/fieldset-element-001.html [ Failure ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/css/css-sizing/aspect-ratio/fieldset-element-001.html [ Failure ]
 crbug.com/626703 [ Mac11 ] external/wpt/css/css-sizing/aspect-ratio/fieldset-element-001.html [ Failure ]
@@ -7757,3 +7761,4 @@
 # Sheriff 2022-05-02
 crbug.com/1321293 fast/forms/calendar-picker/week-picker-choose-default-value-after-set-value.html [ Failure Pass ]
 crbug.com/1322072 [ Mac10.15 ] external/wpt/fetch/content-type/script.window.html [ Failure Pass ]
+crbug.com/1322134 [ Mac11 ] virtual/gpu/fast/canvas/OffscreenCanvasImageRenderingPixelatedWorker.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/Version b/third_party/blink/web_tests/external/Version
index 829aa4b4..b2fa1300 100644
--- a/third_party/blink/web_tests/external/Version
+++ b/third_party/blink/web_tests/external/Version
@@ -1 +1 @@
-Version: 1819cdad5c337be1f3b72bee983eb0cc6b951ea3
+Version: 146851fc385ee6e4c1a7c2434c41a9c170489438
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 1fe40d0..e7ee737 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
@@ -87477,6 +87477,45 @@
        {}
       ]
      ],
+     "revert-layer-013.html": [
+      "862ee72746bb9085c3102e555a601e6220add639",
+      [
+       null,
+       [
+        [
+         "/css/css-cascade/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "revert-layer-014.html": [
+      "6b968625628309959508d452e3b30d5b9a9799f0",
+      [
+       null,
+       [
+        [
+         "/css/css-cascade/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "revert-layer-015.html": [
+      "a60f5d78f5e3640312ee562ccab9b57bc95ef2d3",
+      [
+       null,
+       [
+        [
+         "/css/css-cascade/revert-layer-015-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "revert-val-001.html": [
       "b3d79d9e6909afc2a8fbd8a7e7ab4c5db6ebb3ab",
       [
@@ -259650,6 +259689,10 @@
        []
       ]
      },
+     "revert-layer-015-ref.html": [
+      "661016619c0c46c113dedc57aa890f62b35e137c",
+      []
+     ],
      "support": {
       "test-green.css": [
        "da8e1014d2a95eb3300124b8d6b7c2baa04b8fcd",
@@ -455217,10 +455260,12 @@
       ]
      ],
      "popup-meta-http-equiv.https.html": [
-      "e36b5190aafc0b42b043802422dd411a831a20a5",
+      "157f7aef46af78ede303f3ed4066cb51fcdecb2a",
       [
        null,
-       {}
+       {
+        "timeout": "long"
+       }
       ]
      ],
      "popup-redirect-cache.https.html": [
@@ -455381,7 +455426,7 @@
       ]
      ],
      "popup-with-structured-header.https.html": [
-      "a1b355f15b51cff3a622cce86854c45ddfd9108a",
+      "4066595b8978b410156cbf0287b2df00816eb092",
       [
        null,
        {
@@ -510082,7 +510127,7 @@
      ]
     ],
     "post-task-with-abort-signal-in-handler.any.js": [
-     "f5786951948745c9987a9a52b56a209b4e30b8e0",
+     "1fd416c775dcdd03286024ace3d61d929afb7282",
      [
       "scheduler/post-task-with-abort-signal-in-handler.any.html",
       {
@@ -544871,6 +544916,13 @@
       {}
      ]
     ],
+    "RollbackEvents.https.html": [
+     "0207a076c88be713abd564f6ea2826dbf3b99d61",
+     [
+      null,
+      {}
+     ]
+    ],
     "getstats.html": [
      "d6a692bb7860b9c6bd7699ba4e99ea8010922c08",
      [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-013.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-013.html
new file mode 100644
index 0000000..862ee72
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-013.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>CSS Cascade Layers: 'revert-layer' to host context</title>
+<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#revert-layer">
+<link rel="match" href="reference/ref-filled-green-100px-square.xht">
+
+<style>
+#target {
+  width: 100px;
+  height: 100px;
+  background-color: revert-layer;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id="target"></div>
+
+<script>
+target.attachShadow({mode: 'open'}).innerHTML = `
+<style>
+@layer first {
+    :host { background-color: green; }
+}
+@layer second {
+    :host { background-color: revert-layer; }
+}
+</style>
+`;
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-014.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-014.html
new file mode 100644
index 0000000..6b968625
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-014.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>CSS Cascade Layers: 'revert-layer' in slotted context</title>
+<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#revert-layer">
+<link rel="match" href="reference/ref-filled-green-100px-square.xht">
+
+<style>
+#target {
+  width: 100px;
+  height: 100px;
+  background-color: revert-layer;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id="host"><div id="target"></div></div>
+
+<script>
+host.attachShadow({mode: 'open'}).innerHTML = `
+<style>
+@layer first {
+    ::slotted(*) { background-color: green; }
+}
+@layer second {
+    ::slotted(*) { background-color: revert-layer; }
+}
+</style>
+<slot></slot>
+`;
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015-ref.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015-ref.html
new file mode 100644
index 0000000..6610166
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<style>
+input::placeholder { background-color: green; }
+</style>
+<input placeholder="placeholder">
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015.html
new file mode 100644
index 0000000..a60f5d7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/revert-layer-015.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>CSS Cascade Layers: 'revert-layer' with shadow pseudo-element</title>
+<link rel="help" href="https://drafts.csswg.org/css-cascade-5/#revert-layer">
+<link rel="match" href="revert-layer-015-ref.html">
+
+<style>
+@layer first {
+    input::placeholder { background-color: green; }
+}
+@layer second {
+    input::placeholder { background-color: revert-layer; }
+}
+</style>
+<input placeholder="placeholder">
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/isVisible.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/isVisible.html
new file mode 100644
index 0000000..0679a75
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/isVisible.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/w3c/csswg-drafts/issues/6850">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=visibilityhidden style="visibility:hidden">hello</div>
+
+<div style="content-visibility:hidden">
+  <div id=cvhidden>hello</div>
+</div>
+
+<div style="content-visibility:auto">
+  <div id=cvauto>hello</div>
+</div>
+
+<div id=displaynone style="display:none">hello</div>
+
+<div id=opacityzero style="opacity:0">hello</div>
+
+<div id=inert inert>hello</div>
+
+<div style="content-visibility:hidden">
+  <div id=cvhiddenchildwithupdate></div>
+</div>
+
+<div style="content-visibility:hidden" id=cvhiddenwithupdate></div>
+
+<div style="height:10000px">spacer</div>
+
+<div style="content-visibility:auto">
+  <div id=cvautooffscreen>hello</div>
+</div>
+
+<div id=cvautocontainer>
+  <div id=cvautochild></div>
+</div>
+
+<div style="content-visibility:auto">
+  <div style="content-visibility:auto">
+    <div id=nestedcvautochild></div>
+  </div>
+</div>
+
+<script>
+test(() => {
+  assert_false(visibilityhidden.isVisible({
+    checkVisibilityCSS: true
+  }), 'checkVisibilityCSS:true');
+  assert_true(visibilityhidden.isVisible({
+    checkVisibilityCSS: false
+  }), 'checkVisibilityCSS:false');
+}, 'isVisible on visibility:hidden element.');
+
+test(() => {
+  assert_false(cvhidden.isVisible());
+}, 'isVisible on content-visibility:hidden element.');
+
+test(() => {
+  assert_true(cvauto.isVisible());
+}, 'isVisible on content-visibility:auto element.');
+
+test(() => {
+  assert_true(cvautooffscreen.isVisible());
+}, 'isVisible on content-visibility:auto element which is outside the viewport.');
+
+test(() => {
+  assert_false(displaynone.isVisible());
+}, 'isVisible on display:none element.');
+
+test(() => {
+  assert_false(opacityzero.isVisible({
+    checkOpacity: true
+  }), 'checkOpacity:true');
+  assert_true(opacityzero.isVisible({
+    checkOpacity: false
+  }), 'checkOpacity:false');
+}, 'isVisible on opacity:0 element.');
+
+test(() => {
+  assert_false(inert.isVisible({
+    checkInert: true
+  }), 'checkInert:true');
+  assert_true(inert.isVisible({
+    checkInert: false
+  }), 'checkInert:false');
+}, 'isVisible on an inert element.');
+
+test(() => {
+  cvautocontainer.style.contentVisibility = 'auto';
+  cvautochild.style.visibility = 'hidden';
+  assert_false(cvautochild.isVisible({checkVisibilityCSS: true}));
+  cvautochild.style.visibility = 'visible';
+  assert_true(cvautochild.isVisible({checkVisibilityCSS: true}));
+}, 'isVisible on content-visibility:auto with visibility:hidden inside.');
+
+test(() => {
+  assert_true(nestedcvautochild.isVisible());
+}, 'isVisible on nested content-visibility:auto containers reports that the content is visible.');
+
+test(() => {
+  cvhiddenchildwithupdate.getBoundingClientRect();
+  assert_false(cvhiddenchildwithupdate.isVisible());
+}, 'isVisible on content-visibility:hidden child after forced layout update.');
+
+test(() => {
+  cvhiddenwithupdate.getBoundingClientRect();
+  assert_true(cvhiddenwithupdate.isVisible());
+}, 'isVisible on content-visibility:hidden element after forced layout update.');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance-ref.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance-ref.tentative.html
new file mode 100644
index 0000000..9ae95c2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance-ref.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Popup ::backdrop pseudo element appearance</title>
+
+<style>
+#bottom { top: 70px; left: 70px; }
+#middle { top: 120px; left: 120px; }
+#top { top: 170px; left: 170px; }
+.popup {
+  position: fixed;
+  width: fit-content;
+  height: fit-content;
+  color: black;
+  border: 0;
+  padding: 1em;
+  background: white;
+}
+.backdrop {
+  position: absolute;
+  height: 200px;
+  width: 200px;
+}
+#bottom-backdrop {
+    top: 50px;
+    left: 50px;
+    background-color: rgb(0, 50, 0);
+}
+#middle-backdrop {
+    top: 100px;
+    left: 100px;
+    background-color: rgb(0, 130, 0);
+}
+#top-backdrop {
+    top: 150px;
+    left: 150px;
+    background-color: rgb(0, 210, 0);
+}
+</style>
+<p>Test for [popup]::backdrop presence and stacking order. The test passes
+  if there are 3 stacked boxes, with the brightest green on top.</p>
+<div popup=popup id=bottom>Bottom
+  <div popup=hint id=middle>Middle
+    <div popup=async id=top>Top</div>
+  </div>
+</div>
+<div id="bottom-backdrop" class="backdrop"></div>
+<div id="bottom" class="popup">Bottom</div>
+<div id="middle-backdrop" class="backdrop"></div>
+<div id="middle" class="popup">Middle</div>
+<div id="top-backdrop" class="backdrop"></div>
+<div id="top" class="popup">Top</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance.tentative.html
new file mode 100644
index 0000000..7dcd401
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-backdrop-appearance.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Popup ::backdrop pseudo element appearance</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel=help href="https://open-ui.org/components/popup.research.explainer">
+<link rel="match" href="popup-backdrop-appearance-ref.tentative.html">
+
+<style>
+#bottom { top: 70px; left: 70px; }
+#middle { top: 120px; left: 120px; }
+#top { top: 170px; left: 170px; }
+::backdrop { height: 200px; width: 200px; }
+#bottom::backdrop {
+    top: 50px;
+    left: 50px;
+    background-color: rgb(0, 50, 0);
+    z-index: 100;  /* z-index has no effect. */
+}
+#middle::backdrop {
+    top: 100px;
+    left: 100px;
+    background-color: rgb(0, 130, 0);
+    z-index: -100;  /* z-index has no effect. */
+}
+#top::backdrop {
+    top: 150px;
+    left: 150px;
+    background-color: rgb(0, 210, 0);
+    z-index: 0;  /* z-index has no effect. */
+}
+[popup] {
+    width: fit-content;
+    height: fit-content;
+    color: black;
+    border: 0;
+    padding: 1em;
+    background: white;
+}
+</style>
+<p>Test for [popup]::backdrop presence and stacking order. The test passes
+  if there are 3 stacked boxes, with the brightest green on top.</p>
+<div popup=popup id=bottom>Bottom
+  <div popup=hint id=middle>Middle
+    <div popup=async id=top>Top</div>
+  </div>
+</div>
+<script>
+document.getElementById('bottom').showPopup();
+document.getElementById('middle').showPopup();
+document.getElementById('top').showPopup();
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html
index 1b36233..e2a91b5 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popups/popup-light-dismiss.tentative.html
@@ -24,6 +24,10 @@
 <style>
   #p1 {top: 50px;}
   #p2 {top: 120px;}
+  [popup]::backdrop {
+    /* This should *not* affect anything: */
+    pointer-events: auto;
+  }
 </style>
 <script>
   function spinEventLoop() {
diff --git a/third_party/blink/web_tests/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.js b/third_party/blink/web_tests/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.js
index f578695..1fd416c 100644
--- a/third_party/blink/web_tests/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.js
+++ b/third_party/blink/web_tests/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.js
@@ -13,8 +13,8 @@
 promise_test(t => {
   const controller = new TaskController();
   const signal = controller.signal;
-  return promise_rejects_dom(t, 'AbortError', scheduler.postTask(async () => {
+  return scheduler.postTask(async () => {
     await new Promise(resolve => t.step_timeout(resolve, 0));
     controller.abort();
-  }, { signal }));
+  }, { signal });
 }, 'Posting a task with a signal and abort the signal when running the async callback');
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html
index 8135d275..12b048e 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-iframe-claim.html
@@ -26,7 +26,7 @@
     // 3p mode will tell its SW to claim and then postMessage its results
     // automatically.
     async function onLoad3pMode() {
-      reg = await setup3pIframe();
+      reg = await setupServiceWorker();
 
       if(navigator.serviceWorker.controller != null){
         //This iframe is already under control of a service worker, testing for
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html
index 5dd58f3..0362b58 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-nested-iframe-child.html
@@ -16,7 +16,7 @@
 
 async function onLoad() {
   // Set-up the ServiceWorker for this iframe.
-  await setup3pIframe();
+  await setupServiceWorker();
 
   // When the SW's iframe finishes it'll post a message. This forwards
   // it up to the middle-iframe.
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html
index 4aceb56..747c058 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-getRegistrations.html
@@ -15,7 +15,7 @@
       const scope = './partitioned-'
       const absoluteScope = new URL(scope, window.location).href;
 
-      await setup3pIframe();
+      await setupServiceWorker();
 
       // Once the SW sends us its ID, forward it up to the window.
       navigator.serviceWorker.addEventListener('message', evt => {
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html
index 8be12103..7a2c366 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe-matchAll.html
@@ -11,7 +11,7 @@
   SW's response up, eventually, to the test.
   <script>
     async function onLoad() {
-      reg = await setup3pIframe();
+      reg = await setupServiceWorker();
 
       // Once the SW sends us its ID, forward it up to the window.
       navigator.serviceWorker.addEventListener('message', evt => {
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html
index 624a8e25..1b7f671b 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-service-worker-third-party-iframe.html
@@ -12,7 +12,7 @@
 <script>
 
 async function onLoad() {
-  await setup3pIframe();
+  await setupServiceWorker();
 
   // When the SW's iframe finishes it'll post a message. This forwards it up to
   // the window.
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-utils.js b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-utils.js
index 5d9b4e2..22e90bea 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-utils.js
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/partitioned-utils.js
@@ -57,8 +57,10 @@
   return message_promise;
 }
 
-// 3p iframe utilities
-async function setup3pIframe() {
+// Checks for an existing service worker registration. If not present,
+// registers and maintains a service worker. Used in windows or iframes
+// that will be partitioned from the main frame.
+async function setupServiceWorker() {
 
   const script = './partitioned-storage-sw.js';
   const scope = './partitioned-';
diff --git a/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-scrubby-scrollbar.html b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-scrubby-scrollbar.html
new file mode 100644
index 0000000..c7ca3ac
--- /dev/null
+++ b/third_party/blink/web_tests/fast/forms/calendar-picker/month-picker-scrubby-scrollbar.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1321616">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../../resources/testdriver.js"></script>
+<script src="../../../resources/testdriver-vendor.js"></script>
+<script src="../resources/common.js"></script>
+<script src="../resources/picker-common.js"></script>
+<script src="resources/calendar-picker-common.js"></script>
+
+<input type=month id=picker>
+
+<script>
+promise_test(async () => {
+  await openPicker(picker);
+
+  async function rAF() {
+    return new Promise(resolve => internals.pagePopupWindow.requestAnimationFrame(resolve));
+  }
+
+  const scrubby = internals.pagePopupWindow.global.picker.yearListView_.scrubbyScrollBar;
+  const thumb = scrubby.element.querySelector('.scrubby-scroll-thumb');
+  const originalTop = thumb.style.top;
+  const thumbOffset = cumulativeOffset(thumb);
+
+  eventSender.mouseMoveTo(thumbOffset[0] + 1, thumbOffset[1] + 1);
+  eventSender.mouseDown();
+  eventSender.mouseMoveTo(thumbOffset[0] + 1, thumbOffset[1] - 15);
+  skipAnimation();
+  eventSender.mouseUp();
+  skipAnimation();
+  assert_equals(thumb.style.top, originalTop);
+}, `Verifies that the date picker's scrubby scrollbar returns to its initial state after being clicked and dragged.`);
+</script>
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/cssom-view/idlharness-expected.txt
index 10e225d..b8c8e9f7 100644
--- a/third_party/blink/web_tests/platform/generic/external/wpt/css/cssom-view/idlharness-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/cssom-view/idlharness-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 378 tests; 303 PASS, 75 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS idl_test validation
 PASS Partial interface Window: original interface defined
@@ -147,8 +147,8 @@
 PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
 PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
 PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
+PASS Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type
+PASS Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError
 PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
 PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
 PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
@@ -190,8 +190,8 @@
 PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
 PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
 PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
+PASS Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type
+PASS Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError
 PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
 PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
 PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
@@ -308,7 +308,7 @@
 FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
 PASS Element interface: operation getClientRects()
 PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
+PASS Element interface: operation isVisible(optional IsVisibleOptions)
 PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
 PASS Element interface: operation scroll(optional ScrollToOptions)
 PASS Element interface: operation scroll(unrestricted double, unrestricted double)
@@ -330,8 +330,8 @@
 FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
 PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
 PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
+PASS Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type
+PASS Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
 PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
 PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
 PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/element-instance-property-listing-expected.txt
index d399e3ae..417ed37a 100644
--- a/third_party/blink/web_tests/platform/generic/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/webexposed/element-instance-property-listing-expected.txt
@@ -152,6 +152,7 @@
     property isDefaultNamespace
     property isEqualNode
     property isSameNode
+    property isVisible
     property lang
     property lastChild
     property lastElementChild
@@ -1378,6 +1379,7 @@
     property isDefaultNamespace
     property isEqualNode
     property isSameNode
+    property isVisible
     property lastChild
     property lastElementChild
     property localName
diff --git a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
index 07a0d145..2ab32ee 100644
--- a/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/platform/generic/webexposed/global-interface-listing-expected.txt
@@ -2299,6 +2299,7 @@
     method insertAdjacentElement
     method insertAdjacentHTML
     method insertAdjacentText
+    method isVisible
     method matches
     method prepend
     method querySelector
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.13/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.serviceworker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.serviceworker-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.serviceworker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.serviceworker-expected.txt
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.sharedworker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.sharedworker-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.sharedworker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.sharedworker-expected.txt
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.worker-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/generic/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.worker-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/scheduler/post-task-with-abort-signal-in-handler.any.worker-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt b/third_party/blink/web_tests/platform/win/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
deleted file mode 100644
index 10e225d..0000000
--- a/third_party/blink/web_tests/platform/win/virtual/threaded-prefer-compositing/external/wpt/css/cssom-view/idlharness-expected.txt
+++ /dev/null
@@ -1,382 +0,0 @@
-This is a testharness.js-based test.
-Found 378 tests; 296 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Window: original interface defined
-PASS Partial interface Window: member names are unique
-PASS Partial interface Document: original interface defined
-PASS Partial interface Document: member names are unique
-PASS Partial interface Element: original interface defined
-PASS Partial interface Element: member names are unique
-PASS Partial interface HTMLElement: original interface defined
-PASS Partial interface HTMLElement: member names are unique
-PASS Partial interface HTMLImageElement: original interface defined
-PASS Partial interface HTMLImageElement: member names are unique
-PASS Partial interface Range: original interface defined
-PASS Partial interface Range: member names are unique
-PASS Partial interface MouseEvent: original interface defined
-PASS Partial interface MouseEvent: member names are unique
-PASS Partial interface Element[2]: member names are unique
-PASS Partial interface Window[2]: member names are unique
-PASS Partial interface UIEvent: member names are unique
-PASS Partial interface MouseEvent[2]: member names are unique
-PASS Partial interface UIEvent[2]: member names are unique
-PASS Partial interface Document[2]: member names are unique
-PASS Partial interface Document[3]: member names are unique
-PASS Partial interface HTMLImageElement[2]: member names are unique
-PASS Partial interface Document[4]: member names are unique
-PASS Partial interface Window[3]: member names are unique
-PASS Text includes GeometryUtils: member names are unique
-PASS Element includes GeometryUtils: member names are unique
-PASS CSSPseudoElement includes GeometryUtils: member names are unique
-PASS Document includes GeometryUtils: member names are unique
-PASS HTMLElement includes ElementCSSInlineStyle: member names are unique
-PASS Document includes GlobalEventHandlers: member names are unique
-PASS Document includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes GlobalEventHandlers: member names are unique
-PASS HTMLElement includes DocumentAndElementEventHandlers: member names are unique
-PASS HTMLElement includes ElementContentEditable: member names are unique
-PASS HTMLElement includes HTMLOrSVGElement: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS Document includes NonElementParentNode: member names are unique
-PASS Document includes ParentNode: member names are unique
-PASS Element includes ParentNode: member names are unique
-PASS Element includes NonDocumentTypeChildNode: member names are unique
-PASS CharacterData includes NonDocumentTypeChildNode: member names are unique
-PASS Element includes ChildNode: member names are unique
-PASS CharacterData includes ChildNode: member names are unique
-PASS Element includes Slottable: member names are unique
-PASS Text includes Slottable: member names are unique
-PASS Document includes XPathEvaluatorBase: member names are unique
-PASS MediaQueryList interface: existence and properties of interface object
-PASS MediaQueryList interface object length
-PASS MediaQueryList interface object name
-PASS MediaQueryList interface: existence and properties of interface prototype object
-PASS MediaQueryList interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryList interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryList interface: attribute media
-PASS MediaQueryList interface: attribute matches
-PASS MediaQueryList interface: operation addListener(EventListener?)
-PASS MediaQueryList interface: operation removeListener(EventListener?)
-PASS MediaQueryList interface: attribute onchange
-PASS MediaQueryList must be primary interface of matchMedia("all")
-PASS Stringification of matchMedia("all")
-PASS MediaQueryList interface: matchMedia("all") must inherit property "media" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "matches" with the proper type
-PASS MediaQueryList interface: matchMedia("all") must inherit property "addListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling addListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "removeListener(EventListener?)" with the proper type
-PASS MediaQueryList interface: calling removeListener(EventListener?) on matchMedia("all") with too few arguments must throw TypeError
-PASS MediaQueryList interface: matchMedia("all") must inherit property "onchange" with the proper type
-PASS MediaQueryListEvent interface: existence and properties of interface object
-PASS MediaQueryListEvent interface object length
-PASS MediaQueryListEvent interface object name
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS MediaQueryListEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS MediaQueryListEvent interface: attribute media
-PASS MediaQueryListEvent interface: attribute matches
-PASS MediaQueryListEvent must be primary interface of new MediaQueryListEvent("change")
-PASS Stringification of new MediaQueryListEvent("change")
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "media" with the proper type
-PASS MediaQueryListEvent interface: new MediaQueryListEvent("change") must inherit property "matches" with the proper type
-FAIL Screen interface: existence and properties of interface object assert_equals: prototype of self's property "Screen" is not Function.prototype expected function "function () { [native code] }" but got function "function EventTarget() { [native code] }"
-PASS Screen interface object length
-PASS Screen interface object name
-FAIL Screen interface: existence and properties of interface prototype object assert_equals: prototype of Screen.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
-PASS Screen interface: existence and properties of interface prototype object's "constructor" property
-PASS Screen interface: existence and properties of interface prototype object's @@unscopables property
-PASS Screen interface: attribute availWidth
-PASS Screen interface: attribute availHeight
-PASS Screen interface: attribute width
-PASS Screen interface: attribute height
-PASS Screen interface: attribute colorDepth
-PASS Screen interface: attribute pixelDepth
-PASS Screen must be primary interface of screen
-PASS Stringification of screen
-PASS Screen interface: screen must inherit property "availWidth" with the proper type
-PASS Screen interface: screen must inherit property "availHeight" with the proper type
-PASS Screen interface: screen must inherit property "width" with the proper type
-PASS Screen interface: screen must inherit property "height" with the proper type
-PASS Screen interface: screen must inherit property "colorDepth" with the proper type
-PASS Screen interface: screen must inherit property "pixelDepth" with the proper type
-FAIL CaretPosition interface: existence and properties of interface object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object length assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface object name assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offsetNode assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: attribute offset assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition interface: operation getClientRect() assert_own_property: self does not have own property "CaretPosition" expected property "CaretPosition" missing
-FAIL CaretPosition must be primary interface of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL Stringification of document.caretPositionFromPoint(5, 5) assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offsetNode" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "offset" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CaretPosition interface: document.caretPositionFromPoint(5, 5) must inherit property "getClientRect()" with the proper type assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: document.caretPositionFromPoint is not a function"
-FAIL CSSPseudoElement interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-FAIL CSSPseudoElement interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: self does not have own property "CSSPseudoElement" expected property "CSSPseudoElement" missing
-PASS MouseEvent interface: attribute pageX
-PASS MouseEvent interface: attribute pageY
-PASS MouseEvent interface: attribute x
-PASS MouseEvent interface: attribute y
-PASS MouseEvent interface: attribute offsetX
-PASS MouseEvent interface: attribute offsetY
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "pageY" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type
-PASS MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type
-PASS HTMLElement interface: attribute offsetParent
-PASS HTMLElement interface: attribute offsetTop
-PASS HTMLElement interface: attribute offsetLeft
-PASS HTMLElement interface: attribute offsetWidth
-PASS HTMLElement interface: attribute offsetHeight
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("div") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("div") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("div") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("div") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("div") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("div") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("div") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS HTMLImageElement interface: attribute x
-PASS HTMLImageElement interface: attribute y
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "x" with the proper type
-PASS HTMLImageElement interface: document.createElement("img") must inherit property "y" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetParent" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetTop" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetLeft" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetWidth" with the proper type
-PASS HTMLElement interface: document.createElement("img") must inherit property "offsetHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElement("img") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElement("img") with too few arguments must throw TypeError
-PASS Element interface: document.createElement("img") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElement("img") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElement("img") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElement("img") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElement("img") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Window interface: operation matchMedia(CSSOMString)
-PASS Window interface: attribute screen
-PASS Window interface: operation moveTo(long, long)
-PASS Window interface: operation moveBy(long, long)
-PASS Window interface: operation resizeTo(long, long)
-PASS Window interface: operation resizeBy(long, long)
-PASS Window interface: attribute innerWidth
-PASS Window interface: attribute innerHeight
-PASS Window interface: attribute scrollX
-PASS Window interface: attribute pageXOffset
-PASS Window interface: attribute scrollY
-PASS Window interface: attribute pageYOffset
-PASS Window interface: operation scroll(optional ScrollToOptions)
-PASS Window interface: operation scroll(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollTo(optional ScrollToOptions)
-PASS Window interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Window interface: operation scrollBy(optional ScrollToOptions)
-PASS Window interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Window interface: attribute screenX
-PASS Window interface: attribute screenLeft
-PASS Window interface: attribute screenY
-PASS Window interface: attribute screenTop
-PASS Window interface: attribute outerWidth
-PASS Window interface: attribute outerHeight
-PASS Window interface: attribute devicePixelRatio
-PASS Window interface: window must inherit property "matchMedia(CSSOMString)" with the proper type
-PASS Window interface: calling matchMedia(CSSOMString) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screen" with the proper type
-PASS Window interface: window must inherit property "moveTo(long, long)" with the proper type
-PASS Window interface: calling moveTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "moveBy(long, long)" with the proper type
-PASS Window interface: calling moveBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeTo(long, long)" with the proper type
-PASS Window interface: calling resizeTo(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "resizeBy(long, long)" with the proper type
-PASS Window interface: calling resizeBy(long, long) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "innerWidth" with the proper type
-PASS Window interface: window must inherit property "innerHeight" with the proper type
-PASS Window interface: window must inherit property "scrollX" with the proper type
-PASS Window interface: window must inherit property "pageXOffset" with the proper type
-PASS Window interface: window must inherit property "scrollY" with the proper type
-PASS Window interface: window must inherit property "pageYOffset" with the proper type
-PASS Window interface: window must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scroll(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scroll(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollTo(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollTo(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Window interface: calling scrollBy(optional ScrollToOptions) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Window interface: calling scrollBy(unrestricted double, unrestricted double) on window with too few arguments must throw TypeError
-PASS Window interface: window must inherit property "screenX" with the proper type
-PASS Window interface: window must inherit property "screenLeft" with the proper type
-PASS Window interface: window must inherit property "screenY" with the proper type
-PASS Window interface: window must inherit property "screenTop" with the proper type
-PASS Window interface: window must inherit property "outerWidth" with the proper type
-PASS Window interface: window must inherit property "outerHeight" with the proper type
-PASS Window interface: window must inherit property "devicePixelRatio" with the proper type
-PASS Document interface: operation elementFromPoint(double, double)
-PASS Document interface: operation elementsFromPoint(double, double)
-FAIL Document interface: operation caretPositionFromPoint(double, double) assert_own_property: interface prototype object missing non-static operation expected property "caretPositionFromPoint" missing
-PASS Document interface: attribute scrollingElement
-FAIL Document interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Document interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Document interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Document interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Document interface: document must inherit property "elementFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementFromPoint(double, double) on document with too few arguments must throw TypeError
-PASS Document interface: document must inherit property "elementsFromPoint(double, double)" with the proper type
-PASS Document interface: calling elementsFromPoint(double, double) on document with too few arguments must throw TypeError
-FAIL Document interface: document must inherit property "caretPositionFromPoint(double, double)" with the proper type assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-FAIL Document interface: calling caretPositionFromPoint(double, double) on document with too few arguments must throw TypeError assert_inherits: property "caretPositionFromPoint" not found in prototype chain
-PASS Document interface: document must inherit property "scrollingElement" with the proper type
-FAIL Document interface: document must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: calling getBoxQuads(optional BoxQuadOptions) on document with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Document interface: document must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Document interface: document must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Document interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Element interface: operation getClientRects()
-PASS Element interface: operation getBoundingClientRect()
-FAIL Element interface: operation isVisible(optional IsVisibleOptions) assert_own_property: interface prototype object missing non-static operation expected property "isVisible" missing
-PASS Element interface: operation scrollIntoView(optional (boolean or ScrollIntoViewOptions))
-PASS Element interface: operation scroll(optional ScrollToOptions)
-PASS Element interface: operation scroll(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollTo(optional ScrollToOptions)
-PASS Element interface: operation scrollTo(unrestricted double, unrestricted double)
-PASS Element interface: operation scrollBy(optional ScrollToOptions)
-PASS Element interface: operation scrollBy(unrestricted double, unrestricted double)
-PASS Element interface: attribute scrollTop
-PASS Element interface: attribute scrollLeft
-PASS Element interface: attribute scrollWidth
-PASS Element interface: attribute scrollHeight
-PASS Element interface: attribute clientTop
-PASS Element interface: attribute clientLeft
-PASS Element interface: attribute clientWidth
-PASS Element interface: attribute clientHeight
-FAIL Element interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Element interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Element interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Element interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getClientRects()" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "getBoundingClientRect()" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "isVisible(optional IsVisibleOptions)" with the proper type assert_inherits: property "isVisible" not found in prototype chain
-FAIL Element interface: calling isVisible(optional IsVisibleOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "isVisible" not found in prototype chain
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollIntoView(optional (boolean or ScrollIntoViewOptions))" with the proper type
-PASS Element interface: calling scrollIntoView(optional (boolean or ScrollIntoViewOptions)) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scroll(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scroll(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scroll(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollTo(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTo(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollTo(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(optional ScrollToOptions)" with the proper type
-PASS Element interface: calling scrollBy(optional ScrollToOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollBy(unrestricted double, unrestricted double)" with the proper type
-PASS Element interface: calling scrollBy(unrestricted double, unrestricted double) on document.createElementNS("x", "y") with too few arguments must throw TypeError
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "scrollHeight" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientTop" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientLeft" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientWidth" with the proper type
-PASS Element interface: document.createElementNS("x", "y") must inherit property "clientHeight" with the proper type
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: calling getBoxQuads(optional BoxQuadOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Element interface: document.createElementNS("x", "y") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Element interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createElementNS("x", "y") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: operation getBoxQuads(optional BoxQuadOptions) assert_own_property: interface prototype object missing non-static operation expected property "getBoxQuads" missing
-FAIL Text interface: operation convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertQuadFromNode" missing
-FAIL Text interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertRectFromNode" missing
-FAIL Text interface: operation convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) assert_own_property: interface prototype object missing non-static operation expected property "convertPointFromNode" missing
-FAIL Text interface: document.createTextNode("x") must inherit property "getBoxQuads(optional BoxQuadOptions)" with the proper type assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: calling getBoxQuads(optional BoxQuadOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "getBoxQuads" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: calling convertQuadFromNode(DOMQuadInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertQuadFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertRectFromNode" not found in prototype chain
-FAIL Text interface: document.createTextNode("x") must inherit property "convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions)" with the proper type assert_inherits: property "convertPointFromNode" not found in prototype chain
-FAIL Text interface: calling convertPointFromNode(DOMPointInit, GeometryNode, optional ConvertCoordinateOptions) on document.createTextNode("x") with too few arguments must throw TypeError assert_inherits: property "convertPointFromNode" not found in prototype chain
-PASS Range interface: operation getClientRects()
-PASS Range interface: operation getBoundingClientRect()
-PASS Range interface: new Range() must inherit property "getClientRects()" with the proper type
-PASS Range interface: new Range() must inherit property "getBoundingClientRect()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index 6e18cc428..aa641df 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -27,6 +27,7 @@
 src/common/internal/util.ts
 src/common/internal/tree.ts
 src/common/internal/file_loader.ts
+src/common/util/colors.ts
 src/common/util/navigator_gpu.ts
 src/common/runtime/helper/sys.ts
 src/common/runtime/cmdline.ts
@@ -43,7 +44,6 @@
 src/common/tools/presubmit.ts
 src/common/tools/version.ts
 src/common/util/collect_garbage.ts
-src/common/util/colors.ts
 src/common/util/preprocessor.ts
 src/unittests/unit_test.ts
 src/demo/a.spec.ts
diff --git a/tools/android/io_benchmark/io_benchmark.cc b/tools/android/io_benchmark/io_benchmark.cc
index 232a8d5..bbdce53 100644
--- a/tools/android/io_benchmark/io_benchmark.cc
+++ b/tools/android/io_benchmark/io_benchmark.cc
@@ -39,10 +39,10 @@
 }
 
 std::vector<uint8_t> RandomData(size_t size, std::mt19937* engine) {
-  std::uniform_int_distribution<uint8_t> dist(0, 255);
+  std::uniform_int_distribution<uint32_t> dist(0, 255);
   std::vector<uint8_t> data(size);
   for (size_t i = 0; i < size; ++i)
-    data[i] = dist(*engine);
+    data[i] = static_cast<uint8_t>(dist(*engine));
 
   return data;
 }
diff --git a/tools/android/io_benchmark/sha_benchmark.cc b/tools/android/io_benchmark/sha_benchmark.cc
index 9bb0710..66e38c9 100644
--- a/tools/android/io_benchmark/sha_benchmark.cc
+++ b/tools/android/io_benchmark/sha_benchmark.cc
@@ -25,12 +25,12 @@
 std::vector<uint8_t> GenerateData(size_t size) {
   std::random_device device;
   std::mt19937 rng(device());
-  std::uniform_int_distribution<uint8_t> dist{};
+  std::uniform_int_distribution<uint32_t> dist{};
 
   std::vector<uint8_t> result;
   result.reserve(size);
   for (size_t i = 0; i < size; ++i) {
-    result.push_back(dist(rng));
+    result.push_back(static_cast<uint8_t>(dist(rng)));
   }
 
   return result;
diff --git a/tools/android/memconsumer/BUILD.gn b/tools/android/memconsumer/BUILD.gn
index 7d47045..7f82213 100644
--- a/tools/android/memconsumer/BUILD.gn
+++ b/tools/android/memconsumer/BUILD.gn
@@ -23,7 +23,6 @@
 
   deps = [
     ":memconsumer_apk_resources",
-    "//base:base_java",
     "//build/android:build_java",
   ]
 }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 2c8eba1..9d87c27 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -157,7 +157,7 @@
 
       'chromeos-amd64-generic-asan-rel': 'chromeos_amd64-generic_asan_reclient',
       'chromeos-amd64-generic-asan-rel (reclient shadow)': 'chromeos_amd64-generic_asan_reclient',
-      'chromeos-amd64-generic-cfi-thin-lto-rel': 'chromeos_amd64-generic_cfi_thin_lto',
+      'chromeos-amd64-generic-cfi-thin-lto-rel': 'chromeos_amd64-generic_cfi_thin_lto_reclient',
       'chromeos-amd64-generic-cfi-thin-lto-rel (reclient shadow)': 'chromeos_amd64-generic_cfi_thin_lto_reclient',
       'chromeos-amd64-generic-dbg': 'chromeos_amd64-generic_dbg_reclient',
       'chromeos-amd64-generic-dbg (reclient shadow)': 'chromeos_amd64-generic_dbg_reclient',
diff --git a/tools/mb/mb_config_expectations/chromium.chromiumos.json b/tools/mb/mb_config_expectations/chromium.chromiumos.json
index 59113ce..e1825a4fd 100644
--- a/tools/mb/mb_config_expectations/chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/chromium.chromiumos.json
@@ -53,7 +53,8 @@
       "is_chromeos_device": true,
       "ozone_platform_headless": true,
       "use_cfi_cast": true,
-      "use_goma": true,
+      "use_rbe": true,
+      "use_remoteexec": true,
       "use_thin_lto": true
     }
   },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 99ea6e5..8dc0ac7 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4801,11 +4801,6 @@
   <int value="3" label="Readout"/>
 </enum>
 
-<enum name="AssistantBetterOnboardingMode">
-  <int value="0" label="kDefault"/>
-  <int value="1" label="kEdu"/>
-</enum>
-
 <enum name="AssistantBetterOnboardingType">
   <int value="0" label="kUnspecified"/>
   <int value="1" label="kMath"/>
@@ -52744,6 +52739,7 @@
       label="OverlayScrollbarFlashAfterAnyScrollUpdate:enabled"/>
   <int value="-1907565048" label="HtmlBaseUsernameDetector:disabled"/>
   <int value="-1907342706" label="ReadItLaterInMenu:disabled"/>
+  <int value="-1906427432" label="WallpaperFastRefresh:disabled"/>
   <int value="-1905470520" label="FirmwareUpdaterApp:enabled"/>
   <int value="-1903365454" label="SyncPseudoUSSPreferences:disabled"/>
   <int value="-1899715534" label="GamepadPollingInterval:enabled"/>
@@ -56068,6 +56064,7 @@
   <int value="324631366" label="enable-drive-search-in-app-launcher"/>
   <int value="325489620" label="WebAppEnableManifestId:disabled"/>
   <int value="325907076" label="SanitizerAPI:enabled"/>
+  <int value="326414607" label="WallpaperFastRefresh:enabled"/>
   <int value="327045548" label="SafeSearchUrlReporting:enabled"/>
   <int value="328722396" label="NTPCondensedLayout:disabled"/>
   <int value="330138076" label="enable-clear-browsing-data-counters"/>
@@ -90041,6 +90038,7 @@
   <int value="1" label="Sheet is dismissed"/>
   <int value="2" label="Reauthentication failed"/>
   <int value="3" label="'Manage Passwords' was selected"/>
+  <int value="4" label="WebAuthn credential was selected"/>
 </enum>
 
 <enum name="TouchToFill.SubmissionReadiness">
@@ -90058,6 +90056,7 @@
   <int value="0" label="Selected Credential"/>
   <int value="1" label="Dismissed"/>
   <int value="2" label="Selected Manage Passwords"/>
+  <int value="3" label="Selected WebAuthn Credential"/>
 </enum>
 
 <enum name="TPM12CommandOrdinal">
diff --git a/tools/metrics/histograms/metadata/assistant/histograms.xml b/tools/metrics/histograms/metadata/assistant/histograms.xml
index 2d8e497..39497a3 100644
--- a/tools/metrics/histograms/metadata/assistant/histograms.xml
+++ b/tools/metrics/histograms/metadata/assistant/histograms.xml
@@ -35,7 +35,7 @@
 </variants>
 
 <histogram name="Assistant.BetterOnboarding.Click"
-    enum="AssistantBetterOnboardingType" expires_after="2022-05-01">
+    enum="AssistantBetterOnboardingType" expires_after="2023-05-01">
   <owner>xiaohuic@chromium.org</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>
@@ -43,16 +43,6 @@
   </summary>
 </histogram>
 
-<histogram name="Assistant.BetterOnboarding.Shown"
-    enum="AssistantBetterOnboardingMode" expires_after="2021-12-19">
-  <owner>xiaohuic@chromium.org</owner>
-  <owner>croissant-eng@chromium.org</owner>
-  <summary>
-    The number of times Assistant better onboarding UI is shown. The UI has a
-    few different modes recorded in the enum.
-  </summary>
-</histogram>
-
 <histogram name="Assistant.ButtonClickCount" enum="AssistantButtonId"
     expires_after="2023-03-21">
   <owner>xiaohuic@chromium.org</owner>
@@ -115,7 +105,7 @@
 </histogram>
 
 <histogram name="Assistant.Interaction.Resolution"
-    enum="AssistantInteractionResolution" expires_after="2021-07-22">
+    enum="AssistantInteractionResolution" expires_after="2023-05-01">
   <owner>xiaohuic@chromium.org</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>
@@ -169,7 +159,7 @@
 </histogram>
 
 <histogram name="Assistant.QuerySource" enum="AssistantQuerySource"
-    expires_after="2022-05-01">
+    expires_after="2023-05-01">
   <owner>xiaohuic@chromium.org</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>
@@ -206,7 +196,7 @@
 </histogram>
 
 <histogram name="Assistant.SetDspHotwordLocale" enum="BooleanSuccess"
-    expires_after="2022-05-01">
+    expires_after="2023-05-01">
   <owner>xiaohuic@chromium.org</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index 7f39c78..77c8d1a 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -2226,8 +2226,8 @@
   <owner>zmin@chromium.org</owner>
   <summary>
     Whether the machine is considered an enterprise user. An enterprise user is
-    either in a domain or is managed via MDM. This check is performed once at
-    start-up on Windows.
+    either in a domain, either local or cloud via AAD. This check is performed
+    once at start-up on Windows.
   </summary>
 </histogram>
 
@@ -2292,6 +2292,18 @@
   </summary>
 </histogram>
 
+<histogram name="EnterpriseCheck.IsManagedOrEnterpriseDevice"
+    enum="BooleanEnabled" expires_after="2022-08-21">
+  <owner>pastarmovj@chromium.org</owner>
+  <owner>rogerta@chromium.org</owner>
+  <owner>zmin@chromium.org</owner>
+  <summary>
+    Whether the machine is managed or part of an enterprise. This includes
+    devices that are either in a domain or managed via MDM. This check is
+    performed once at start-up on Windows.
+  </summary>
+</histogram>
+
 <histogram name="EnterpriseCheck.IsRunningOnManagedProfileDuration" units="ms"
     expires_after="2021-04-04">
   <owner>twellington@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml
index 02cdb7b..a87fc234 100644
--- a/tools/metrics/histograms/metadata/history/histograms.xml
+++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -957,25 +957,6 @@
   </token>
 </histogram>
 
-<histogram name="History.Clusters.WebUISessionDuration" units="ms"
-    expires_after="2022-11-30">
-  <owner>tommycli@chromium.org</owner>
-  <owner>chrome-journeys@google.com</owner>
-  <summary>
-    Records the amount of time the Journeys WebUI is open.
-
-    This timer is started when the Journeys WebUI is loaded. The Journeys WebUI
-    is loaded when either the user directly goes to the Journeys WebUI, or when
-    the user switches to the Journeys tab from a different tab.
-
-    The timer is stopped and the elapsed time recorded when either the whole
-    WebUI is closed, or if the user disables the Journeys preference, or if the
-    user switches tabs off the Journeys tab onto a different one.
-
-    Elapsed times longer than one hour are recorded as one hour.
-  </summary>
-</histogram>
-
 <histogram name="History.DatabaseAdvancedMetricsTime" units="ms"
     expires_after="M77">
   <owner>shess@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index af44d74..59ff3825 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -93,6 +93,13 @@
       summary="Determines if a page is shopping related or not"/>
 </variants>
 
+<variants name="PageContentAnnotationsStorageType">
+  <variant name="ModelAnnotations" summary="Model Annotations"/>
+  <variant name="RelatedSearches" summary="Related Searches"/>
+  <variant name="SearchMetadata" summary="Search Metadata"/>
+  <variant name="Unknown" summary="Unknown"/>
+</variants>
+
 <variants name="PageTextDumpEvent">
   <variant name="FinishedLoad" summary="finished load"/>
   <variant name="FirstLayout" summary="first layout"/>
@@ -666,6 +673,22 @@
 </histogram>
 
 <histogram
+    name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageMinMagnitudeForVisitNotFound.{PageContentAnnotationsStorageType}"
+    units="ms" expires_after="M106">
+  <owner>sophiechang@chromium.org</owner>
+  <owner>chrome-intelligence-core@google.com</owner>
+  <summary>
+    Records the magnitude of the visit times between the visit that
+    {PageContentAnnotationsStorageType} is supposed to be stored for and the
+    closest visit for the same URL if the specific visit, as identified by URL
+    and time, was not found when storing the {PageContentAnnotationsStorageType}
+    for a particular visit. This will be recorded at most once per page load.
+  </summary>
+  <token key="PageContentAnnotationsStorageType"
+      variants="PageContentAnnotationsStorageType"/>
+</histogram>
+
+<histogram
     name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageStatus"
     enum="OptimizationGuidePageContentAnnotationsStorageStatus"
     expires_after="2022-10-30">
@@ -673,13 +696,28 @@
   <owner>mcrouse@chromium.org</owner>
   <summary>
     Records the status of whether the content annotations were stored in History
-    Service when the page content has been annotated successfully. This will be
-    recorded multiple times per page load, for both the related searches as well
-    as the model annotations once the page has finished loading.
+    Service when the necessary data has been collected successfully. This will
+    be recorded multiple times per page load, for both the related searches as
+    well as the model annotations once the page has finished loading.
   </summary>
 </histogram>
 
 <histogram
+    name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageStatus.{PageContentAnnotationsStorageType}"
+    enum="OptimizationGuidePageContentAnnotationsStorageStatus"
+    expires_after="M106">
+  <owner>sophiechang@chromium.org</owner>
+  <owner>mcrouse@chromium.org</owner>
+  <summary>
+    Records the status of whether the {PageContentAnnotationsStorageType} were
+    stored in History Service when the data has been collected successfully.
+    This will record at most once per page load.
+  </summary>
+  <token key="PageContentAnnotationsStorageType"
+      variants="PageContentAnnotationsStorageType"/>
+</histogram>
+
+<histogram
     name="OptimizationGuide.PageContentAnnotationsService.ModelAvailable"
     enum="BooleanAvailable" expires_after="2022-10-30">
   <owner>robertogden@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index 03c00f8..5ababda 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -2869,85 +2869,6 @@
   <summary>Reports the result of an attempt to load an MHTML archive.</summary>
 </histogram>
 
-<histogram name="PageSerialization.ProblemDetection.LoadedCSSPercentage"
-    units="%" expires_after="M77">
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Percentage of loaded CSS elements in the main frame at the time of
-    serialization.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.ProblemDetection.LoadedImagePercentage"
-    units="%" expires_after="2021-06-25">
-  <owner>sclittle@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Percentage of loaded images in the main frame at the time of serialization.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.ProblemDetection.TotalCSSCount"
-    units="units" expires_after="M77">
-  <owner>dimich@chromium.org</owner>
-  <summary>
-    Total number of CSS elements in the main frame for serialization.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.ProblemDetection.TotalImageCount"
-    units="units" expires_after="M77">
-  <owner>dimich@chromium.org</owner>
-  <summary>Total number of images in the main frame for serialization.</summary>
-</histogram>
-
-<histogram name="PageSerialization.SerializationTime.CSSElement"
-    units="microseconds" expires_after="2020-12-01">
-  <owner>sclittle@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Time spent serializing a CSS element (including embedded &quot;sub&quot;-CSS
-    and images).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.SerializationTime.Html" units="microseconds"
-    expires_after="2020-12-01">
-  <owner>sclittle@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Time taken to generate HTML data from a frame's DOM and serialize it
-    (without sub-resources like CSS and images).
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
-<histogram name="PageSerialization.SerializationTime.ImageElement"
-    units="microseconds" expires_after="2020-12-01">
-  <owner>sclittle@chromium.org</owner>
-  <owner>offline-dev@chromium.org</owner>
-  <summary>
-    Time spent serializing an image element.
-
-    Warning: This metric may include reports from clients with low-resolution
-    clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports
-    will cause this metric to have an abnormal distribution. When considering
-    revising this histogram, see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES for the
-    solution.
-  </summary>
-</histogram>
-
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/scanning/histograms.xml b/tools/metrics/histograms/metadata/scanning/histograms.xml
index f9bde84..f6fdb32 100644
--- a/tools/metrics/histograms/metadata/scanning/histograms.xml
+++ b/tools/metrics/histograms/metadata/scanning/histograms.xml
@@ -126,7 +126,7 @@
 </histogram>
 
 <histogram name="Scanning.NumFilesCreated" units="files"
-    expires_after="2022-06-15">
+    expires_after="2022-12-15">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>Records the number of files created in a successful scan.</summary>
@@ -158,7 +158,7 @@
   </summary>
 </histogram>
 
-<histogram name="Scanning.ReadyTime" units="ms" expires_after="2022-06-15">
+<histogram name="Scanning.ReadyTime" units="ms" expires_after="2022-12-15">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
@@ -195,7 +195,7 @@
 </histogram>
 
 <histogram name="Scanning.ScanJobSettings.FileType"
-    enum="ScanJobSettingsFileType" expires_after="2022-06-15">
+    enum="ScanJobSettingsFileType" expires_after="2022-12-15">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
@@ -222,7 +222,7 @@
 </histogram>
 
 <histogram name="Scanning.ScanJobSettings.Source" enum="ScanJobSettingsSource"
-    expires_after="2022-06-15">
+    expires_after="2022-12-15">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml
index 0ca30f3..d898a30 100644
--- a/tools/metrics/histograms/metadata/search/histograms.xml
+++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -702,49 +702,6 @@
   </summary>
 </histogram>
 
-<histogram name="Search.ContextualSearchPrevious28DayCtr" units="%"
-    expires_after="M72">
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The CTR from the previous 28 day period for each user, expressed as a
-    percentage. Logged the first time the panel is closed in each new week.
-    Implemented for Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPrevious28DayImpressions" units="views"
-    expires_after="M72">
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of user impressions of the Bar from the previous 28 day period.
-    Logged the first time the panel is closed in each new week. Implemented for
-    Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPreviousWeekCtr" units="%"
-    expires_after="M72">
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The CTR from the previous week for each user, expressed as a percentage.
-    Logged the first time the panel is closed in each new week. Implemented for
-    Android.
-  </summary>
-</histogram>
-
-<histogram name="Search.ContextualSearchPreviousWeekImpressions" units="views"
-    expires_after="M72">
-  <owner>donnd@chromium.org</owner>
-  <owner>twellington@chromium.org</owner>
-  <summary>
-    The number of user impressions of the Bar from the previous week. Logged the
-    first time the panel is closed in each new week. Implemented for Android.
-  </summary>
-</histogram>
-
 <histogram name="Search.ContextualSearchPrivacyOptInPreferenceStateChange"
     enum="BooleanOptedIn" expires_after="2022-08-28">
   <owner>donnd@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index aa78e28..61e5a54 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -775,7 +775,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.EventRecordingState"
-    enum="StructuredMetricsEventRecordingState" expires_after="2022-04-24">
+    enum="StructuredMetricsEventRecordingState" expires_after="2022-11-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -807,7 +807,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.InternalError2"
-    enum="StructuredMetricsInternalError2" expires_after="2022-05-01">
+    enum="StructuredMetricsInternalError2" expires_after="2022-11-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -818,7 +818,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.KeyValidationState"
-    enum="StructuredMetricsKeyValidationState" expires_after="2022-04-24">
+    enum="StructuredMetricsKeyValidationState" expires_after="2022-11-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
@@ -830,7 +830,7 @@
 </histogram>
 
 <histogram name="UMA.StructuredMetrics.NumEventsInUpload" units="count"
-    expires_after="2022-04-24">
+    expires_after="2022-11-01">
   <owner>tby@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/variations/histograms.xml b/tools/metrics/histograms/metadata/variations/histograms.xml
index 0ef0f0ca..744029a 100644
--- a/tools/metrics/histograms/metadata/variations/histograms.xml
+++ b/tools/metrics/histograms/metadata/variations/histograms.xml
@@ -395,7 +395,7 @@
 </histogram>
 
 <histogram name="Variations.SafeModeCachedFlags.Streak.Crashes" units="crashes"
-    expires_after="2022-10-23">
+    expires_after="2023-05-01">
   <owner>hnakashima@chromium.org</owner>
   <owner>src/chrome/browser/flags/OWNERS</owner>
   <summary>
@@ -408,7 +408,7 @@
 </histogram>
 
 <histogram name="Variations.SafeModeCachedFlags.{Event}"
-    enum="VariationsSafeModeCachedFlagsBehavior" expires_after="2022-06-21">
+    enum="VariationsSafeModeCachedFlagsBehavior" expires_after="2023-05-01">
   <owner>hnakashima@chromium.org</owner>
   <owner>src/chrome/browser/flags/OWNERS</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 8dabfd95..84cd654 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "2f8e560a5df42a41b8b1658760f5d4570c7d9504",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/02f7958f6551a697b124256d643cee71e4e350a9/trace_processor_shell.exe"
+            "hash": "fa4c3731aaacd16bcfc760e4cd7c2241a1cfeca6",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/b539fc7f1e6403f2ed93b2264fd54bf40e9e5656/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "53031c26ec7ce0da672e6d59c32f6905c002eb0e",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/02f7958f6551a697b124256d643cee71e4e350a9/trace_processor_shell"
+            "hash": "1b5c0bb56511d8c850352095231b27086f55c474",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/c269336b2431b9488c13bd32463dd4ea3342bf91/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
             "full_remote_path": "perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "6b7c75037366bb10f21441af9748eabec2e1d608",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/02f7958f6551a697b124256d643cee71e4e350a9/trace_processor_shell"
+            "hash": "ea492ae68dcfb411e19a2eaab1575e728c2c72c4",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/f8b405298bd883ba95f7a14acfce230b37487ad3/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/resources/svgo_presubmit.py b/tools/resources/svgo_presubmit.py
index c9e5752..b9642f6 100644
--- a/tools/resources/svgo_presubmit.py
+++ b/tools/resources/svgo_presubmit.py
@@ -12,7 +12,7 @@
 
 def CheckOptimized(input_api, output_api):
   file_filter = lambda f: f.LocalPath().endswith('.svg') and \
-      f.LocalPath() not in BLOCKLIST
+      f.LocalPath().replace('\\', '/') not in BLOCKLIST
   svgs = input_api.AffectedFiles(file_filter=file_filter, include_deletes=False)
 
   if not svgs:
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h
index f36ee30..ab5963f 100644
--- a/ui/accessibility/ax_range.h
+++ b/ui/accessibility/ax_range.h
@@ -366,8 +366,12 @@
                              current_end_offset - start->text_offset())
                   : current_end_offset - start->text_offset();
 
-          range_text += start->GetText(embedded_object_behavior)
-                            .substr(start->text_offset(), characters_to_append);
+          std::u16string position_text =
+              start->GetText(embedded_object_behavior);
+          if (start->text_offset() < static_cast<int>(position_text.length())) {
+            range_text += position_text.substr(start->text_offset(),
+                                               characters_to_append);
+          }
 
           // To minimize user confusion, collapse all whitespace following any
           // line break unless it is a hard line break (<br> or a text node with
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index ea10a4f..6fa799ad 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -573,7 +573,6 @@
       [ "javatests/src/org/chromium/ui/base/ClipboardAndroidTestSupport.java" ]
 
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:jni_java",
     "//build/android:build_java",
@@ -592,7 +591,6 @@
     ":clipboard_java_test_support",
     ":ui_java",
     ":ui_java_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//content/public/test/android:content_java_test_support",
diff --git a/ui/base/cursor/cursor_factory.cc b/ui/base/cursor/cursor_factory.cc
index aaf59cec8..bc13490 100644
--- a/ui/base/cursor/cursor_factory.cc
+++ b/ui/base/cursor/cursor_factory.cc
@@ -134,7 +134,7 @@
     case mojom::CursorType::kNone:
       return {};
     case mojom::CursorType::kGrab:
-      return {"openhand", "grab"};
+      return {"openhand", "grab", "hand1"};
     case mojom::CursorType::kGrabbing:
       return {"closedhand", "grabbing", "hand2"};
     case mojom::CursorType::kCross:
diff --git a/ui/compositor/test/test_compositor_host_ozone.cc b/ui/compositor/test/test_compositor_host_ozone.cc
index 414da44..70cd276 100644
--- a/ui/compositor/test/test_compositor_host_ozone.cc
+++ b/ui/compositor/test/test_compositor_host_ozone.cc
@@ -56,12 +56,6 @@
   }
   void OnActivationChanged(bool active) override {}
   void OnMouseEnter() override {}
-  gfx::Rect ConvertRectToPixels(const gfx::Rect& rect) const override {
-    return rect;
-  }
-  gfx::Rect ConvertRectToDIP(const gfx::Rect& rect) const override {
-    return rect;
-  }
 
  private:
   gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
index 91b0861..c3755a91 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
@@ -38,8 +38,8 @@
 
 // Vendor ID for downstream, interim ChromeOS specific modifiers.
 #define DRM_FORMAT_MOD_VENDOR_CHROMEOS 0xf0
-// TODO(gurchetansingh) Remove once DRM_FORMAT_MOD_ARM_AFBC is used by all
-// kernels and allocators.
+// TODO(b/231167263) Remove once DRM_FORMAT_MOD_ARM_AFBC is used by all kernels
+// and allocators.
 #define DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC fourcc_mod_code(CHROMEOS, 1)
 
 namespace ui {
@@ -79,6 +79,18 @@
   return ss.str();
 }
 
+bool IsRockchipAfbc(uint64_t modifier) {
+  // TODO(b/231167263): Drop when kernel 4.4 is gone for RK3399.
+  if (modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) {
+    return true;
+  }
+
+  // Newer (and upstream) kernels use DRM_FORMAT_MOD_ARM_AFBC.
+  return modifier ==
+         DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+                                 AFBC_FORMAT_MOD_SPARSE | AFBC_FORMAT_MOD_YTR);
+}
+
 }  // namespace
 
 HardwareDisplayController::HardwareDisplayController(
@@ -299,11 +311,10 @@
   auto it = preferred_format_modifier_.find(fourcc_format);
   if (it != preferred_format_modifier_.end()) {
     uint64_t supported_modifier = it->second;
-    // AFBC for modeset buffers doesn't work correctly, as we can't fill it with
-    // a valid AFBC buffer (crbug.com/852675).
+    // AFBC for modeset buffers doesn't work correctly, as we can't fill them
+    // with a valid AFBC buffer (b/172227166).
     // For now, don't use AFBC for modeset buffers.
-    if (is_modeset &&
-        supported_modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) {
+    if (is_modeset && IsRockchipAfbc(supported_modifier)) {
       supported_modifier = DRM_FORMAT_MOD_LINEAR;
     }
     return std::vector<uint64_t>{supported_modifier};
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index d972fe4..ece1a64 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -293,10 +293,15 @@
     return;
   }
 
+  gfx::PointF pointer_location(location);
+  if (connection_->surface_submission_in_pixel_coordinates())
+    pointer_location.Scale(1.0f / window_->window_scale());
+
   DCHECK(data_offer_);
   int available_operations =
       DndActionsToDragOperations(data_offer_->source_actions());
-  int client_operations = window_->OnDragMotion(location, available_operations);
+  int client_operations =
+      window_->OnDragMotion(pointer_location, available_operations);
 
   data_offer_->SetDndActions(DragOperationsToDndActions(client_operations));
 }
@@ -468,10 +473,15 @@
     const gfx::PointF& location,
     std::unique_ptr<OSExchangeData> data) {
   DCHECK(window_);
+  {
+    gfx::PointF pointer_location(location);
+    if (connection_->surface_submission_in_pixel_coordinates())
+      pointer_location.Scale(1.0f / window_->window_scale());
 
-  window_->OnDragEnter(
-      location, std::move(data),
-      DndActionsToDragOperations(data_offer_->source_actions()));
+    window_->OnDragEnter(
+        pointer_location, std::move(data),
+        DndActionsToDragOperations(data_offer_->source_actions()));
+  }
   OnDragMotion(location);
 }
 
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
index f94209e..b586e75 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
@@ -90,12 +90,14 @@
 
 }  // namespace
 
-class MockDragHandlerDelegate : public WmDragHandler::Delegate {
+class MockDragFinishedCallback {
  public:
-  MOCK_METHOD1(OnDragLocationChanged, void(const gfx::Point& location));
-  MOCK_METHOD1(OnDragOperationChanged, void(DragOperation operation));
   MOCK_METHOD1(OnDragFinished, void(DragOperation operation));
-  MOCK_METHOD0(GetDragWidget, absl::optional<gfx::AcceleratedWidget>());
+
+  ui::WmDragHandler::DragFinishedCallback callback() {
+    return base::BindOnce(&MockDragFinishedCallback::OnDragFinished,
+                          base::Unretained(this));
+  }
 };
 
 class MockDropHandler : public WmDropHandler {
@@ -162,7 +164,7 @@
     server_.output()->SetRect({20, 30, 800, 600});
     WaylandDragDropTest::SetUp();
 
-    drag_handler_delegate_ = std::make_unique<MockDragHandlerDelegate>();
+    drag_finished_callback_ = std::make_unique<MockDragFinishedCallback>();
     drop_handler_ = std::make_unique<MockDropHandler>();
     SetWmDropHandler(window_.get(), drop_handler_.get());
   }
@@ -177,8 +179,8 @@
 
   MockDropHandler* drop_handler() { return drop_handler_.get(); }
 
-  MockDragHandlerDelegate* drag_handler() {
-    return drag_handler_delegate_.get();
+  MockDragFinishedCallback* drag_finished_callback() {
+    return drag_finished_callback_.get();
   }
 
   wl::MockSurface* GetMockSurface(uint32_t id) {
@@ -200,7 +202,8 @@
     os_exchange_data.SetString(sample_text_for_dnd());
     origin_window->StartDrag(
         os_exchange_data, operations, DragEventSource::kMouse, /*cursor=*/{},
-        /*can_grab_pointer=*/true, drag_handler_delegate_.get());
+        /*can_grab_pointer=*/true, drag_finished_callback_->callback(),
+        /*loation delegate=*/nullptr);
     Sync();
   }
 
@@ -234,7 +237,7 @@
           // If DnD was cancelled, or data was dropped where it was not
           // accepted, the operation result must be None (0).
           // Regression test for https://crbug.com/1136751.
-          EXPECT_CALL(*self->drag_handler(),
+          EXPECT_CALL(*self->drag_finished_callback(),
                       OnDragFinished(DragOperation::kNone))
               .Times(1);
 
@@ -254,7 +257,7 @@
 
  protected:
   std::unique_ptr<MockDropHandler> drop_handler_;
-  std::unique_ptr<MockDragHandlerDelegate> drag_handler_delegate_;
+  std::unique_ptr<MockDragFinishedCallback> drag_finished_callback_;
 };
 
 TEST_P(WaylandDataDragControllerTest, StartDrag) {
@@ -432,7 +435,7 @@
 
   // Consume the move event from pointer enter.
   EXPECT_CALL(*drop_handler_,
-              MockDragMotion(PointFNear(gfx::PointF(20, 20)), _, _));
+              MockDragMotion(PointFNear(gfx::PointF(10, 10)), _, _));
 
   gfx::Point entered_point(10, 10);
   // The server sends an enter event.
@@ -443,9 +446,9 @@
   Sync();
   ASSERT_EQ(drag_controller(), data_device()->drag_delegate_);
 
-  // In 2x window scale, we expect received coordinates to be multiplied.
+  // In 2x window scale, we expect received coordinates still be in DIP.
   EXPECT_CALL(*drop_handler_,
-              MockDragMotion(PointFNear(gfx::PointF(60, 60)), _, _));
+              MockDragMotion(PointFNear(gfx::PointF(30, 30)), _, _));
 
   // The server sends an motion event in DP.
   gfx::Point motion_point(30, 30);
@@ -491,25 +494,33 @@
       data_device_manager_->data_device()->CreateAndSendDataOffer();
   data_offer->OnOffer(kMimeTypeText,
                       ToClipboardData(std::string(kSampleTextForDragAndDrop)));
+  gfx::Point entered_point{800, 600};
+  {
+    gfx::PointF expected_position(entered_point);
+    expected_position.Scale(1.0f / kTripleScale);
 
-  EXPECT_CALL(*drop_handler_,
-              MockDragMotion(PointFNear(gfx::PointF(800, 600)), _, _));
+    EXPECT_CALL(*drop_handler_,
+                MockDragMotion(PointFNear(expected_position), _, _));
 
-  // The server sends an enter event at the bottom right corner of the window.
-  gfx::Point entered_point(800, 600);
-  data_device_manager_->data_device()->OnEnter(
-      1002, surface_->resource(), wl_fixed_from_int(entered_point.x()),
-      wl_fixed_from_int(entered_point.y()), data_offer);
-
+    // The server sends an enter event at the bottom right corner of the window.
+    data_device_manager_->data_device()->OnEnter(
+        1002, surface_->resource(), wl_fixed_from_int(entered_point.x()),
+        wl_fixed_from_int(entered_point.y()), data_offer);
+  }
   Sync();
 
-  EXPECT_CALL(*drop_handler_,
-              MockDragMotion(PointFNear(gfx::PointF(400, 300)), _, _))
-      .Times(::testing::AtLeast(1));
+  gfx::Point center_point{400, 300};
+  {
+    gfx::PointF expected_position(center_point);
+    expected_position.Scale(1.0f / kTripleScale);
 
-  // The server sends a motion event through the center of the output.
-  gfx::Point center(400, 300);
-  SendMotionEvent(data_device_manager_->data_device(), center);
+    EXPECT_CALL(*drop_handler_,
+                MockDragMotion(PointFNear(expected_position), _, _))
+        .Times(::testing::AtLeast(1));
+
+    // The server sends a motion event through the center of the output.
+    SendMotionEvent(data_device_manager_->data_device(), center_point);
+  }
   Sync();
 
   EXPECT_CALL(*drop_handler_,
@@ -802,7 +813,7 @@
   os_exchange_data.SetString(sample_text_for_dnd());
   window_2->StartDrag(os_exchange_data, DragDropTypes::DRAG_COPY,
                       DragEventSource::kMouse, {}, true,
-                      drag_handler_delegate_.get());
+                      drag_finished_callback_->callback(), nullptr);
   Sync();
 
   // Send wl_data_source::cancelled event. The drag controller is then
@@ -963,10 +974,10 @@
   EXPECT_CALL(*this, MockStartDrag(_, _, _)).Times(0);
 
   // Attempt to start drag session and ensure it fails.
-  bool result_1 = window_->StartDrag(os_exchange_data, DragDropTypes::DRAG_COPY,
-                                     DragEventSource::kMouse, /*cursor=*/{},
-                                     /*can_grab_pointer=*/true,
-                                     drag_handler_delegate_.get());
+  bool result_1 = window_->StartDrag(
+      os_exchange_data, DragDropTypes::DRAG_COPY, DragEventSource::kMouse,
+      /*cursor=*/{},
+      /*can_grab_pointer=*/true, drag_finished_callback_->callback(), nullptr);
   EXPECT_FALSE(result_1);
   Mock::VerifyAndClearExpectations(drop_handler_.get());
   Mock::VerifyAndClearExpectations(this);
@@ -983,20 +994,20 @@
     SendPointerButton(window_.get(), &delegate_, BTN_LEFT, /*pressed=*/false);
 
     EXPECT_CALL(*drop_handler_, OnDragLeave).Times(1);
-    EXPECT_CALL(*drag_handler_delegate_,
+    EXPECT_CALL(*drag_finished_callback_,
                 OnDragFinished(Eq(DragOperation::kNone)))
         .Times(1);
     Sync();
   }));
   EXPECT_CALL(*this, MockStartDrag(_, _, _)).Times(1);
-  bool result_2 = window_->StartDrag(os_exchange_data, DragDropTypes::DRAG_COPY,
-                                     DragEventSource::kMouse, /*cursor=*/{},
-                                     /*can_grab_pointer=*/true,
-                                     drag_handler_delegate_.get());
+  bool result_2 = window_->StartDrag(
+      os_exchange_data, DragDropTypes::DRAG_COPY, DragEventSource::kMouse,
+      /*cursor=*/{},
+      /*can_grab_pointer=*/true, drag_finished_callback_->callback(), nullptr);
   // TODO(crbug.com/1022722): Double-check if this should return false instead.
   EXPECT_TRUE(result_2);
   Mock::VerifyAndClearExpectations(drop_handler_.get());
-  Mock::VerifyAndClearExpectations(drag_handler_delegate_.get());
+  Mock::VerifyAndClearExpectations(drag_finished_callback_.get());
   Mock::VerifyAndClearExpectations(this);
   EXPECT_FALSE(drag_controller()->origin_window_);
   EXPECT_FALSE(drag_controller()->nested_dispatcher_);
@@ -1062,7 +1073,8 @@
   EXPECT_CALL(*this, MockStartDrag(_, _, _)).Times(0);
   bool drag_started = window_->StartDrag(
       os_exchange_data, DragDropTypes::DRAG_COPY, DragEventSource::kTouch,
-      /*cursor=*/{}, /*can_grab_pointer=*/true, drag_handler_delegate_.get());
+      /*cursor=*/{}, /*can_grab_pointer=*/true,
+      drag_finished_callback_->callback(), nullptr);
   EXPECT_FALSE(drag_started);
   Mock::VerifyAndClearExpectations(drop_handler_.get());
   Mock::VerifyAndClearExpectations(this);
@@ -1081,7 +1093,8 @@
   EXPECT_CALL(*this, MockStartDrag(_, _, Eq(mouse_press_serial))).Times(1);
   bool success = window_->StartDrag(
       os_exchange_data, DragDropTypes::DRAG_COPY, DragEventSource::kMouse,
-      /*cursor=*/{}, /*can_grab_pointer=*/true, drag_handler_delegate_.get());
+      /*cursor=*/{}, /*can_grab_pointer=*/true,
+      drag_finished_callback_->callback(), nullptr);
   EXPECT_TRUE(success);
   Mock::VerifyAndClearExpectations(drop_handler_.get());
   Mock::VerifyAndClearExpectations(this);
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
index 1eda2fc9..6948a36 100644
--- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -812,20 +812,14 @@
 void WaylandToplevelWindow::SetSizeConstraints() {
   DCHECK(delegate());
 
-  min_size_ = delegate()->GetMinimumSizeForWindow();
-  max_size_ = delegate()->GetMaximumSizeForWindow();
+  auto min_size_dip = delegate()->GetMinimumSizeForWindow();
+  auto max_size_dip = delegate()->GetMaximumSizeForWindow();
 
-  if (min_size_.has_value()) {
-    auto min_size_dip =
-        gfx::ScaleToRoundedSize(min_size_.value(), 1.0f / window_scale());
-    shell_toplevel_->SetMinSize(min_size_dip.width(), min_size_dip.height());
-  }
+  if (min_size_dip.has_value())
+    shell_toplevel_->SetMinSize(min_size_dip->width(), min_size_dip->height());
 
-  if (max_size_.has_value()) {
-    auto max_size_dip =
-        gfx::ScaleToRoundedSize(max_size_.value(), 1.0f / window_scale());
-    shell_toplevel_->SetMaxSize(max_size_dip.width(), max_size_dip.height());
-  }
+  if (max_size_dip.has_value())
+    shell_toplevel_->SetMaxSize(max_size_dip->width(), max_size_dip->height());
 
   connection()->ScheduleFlush();
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
index ac02c77..cf687fd1 100644
--- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
+++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -182,7 +182,7 @@
 
   WmMoveResizeHandler* AsWmMoveResizeHandler();
 
-  // Propagates the |min_size_| and |max_size_| to the ShellToplevel.
+  // Propagates the minimum size and maximum size to the ShellToplevel.
   void SetSizeConstraints();
 
   // If current state is not PlatformWindowState::kNormal, stores the current
@@ -237,10 +237,6 @@
   // Title of the ShellToplevel.
   std::u16string window_title_;
 
-  // Max and min sizes of the WaylandToplevelWindow window.
-  absl::optional<gfx::Size> min_size_;
-  absl::optional<gfx::Size> max_size_;
-
   wl::Object<zaura_surface> aura_surface_;
   // |gtk_surface1_| is the optional GTK surface that provides better
   // integration with the desktop shell.
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
index 3d95c22..e44265e 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -196,19 +196,21 @@
   root_surface_->RemoveEnteredOutput(output_id);
 }
 
-bool WaylandWindow::StartDrag(const ui::OSExchangeData& data,
-                              int operations,
-                              mojom::DragEventSource source,
-                              gfx::NativeCursor cursor,
-                              bool can_grab_pointer,
-                              WmDragHandler::Delegate* delegate) {
+bool WaylandWindow::StartDrag(
+    const ui::OSExchangeData& data,
+    int operations,
+    mojom::DragEventSource source,
+    gfx::NativeCursor cursor,
+    bool can_grab_pointer,
+    WmDragHandler::DragFinishedCallback drag_finished_callback,
+    WmDragHandler::LocationDelegate* location_delegate) {
   if (!connection_->data_drag_controller()->StartSession(data, operations,
                                                          source)) {
     return false;
   }
 
-  DCHECK(!drag_handler_delegate_);
-  drag_handler_delegate_ = delegate;
+  DCHECK(drag_finished_callback_.is_null());
+  drag_finished_callback_ = std::move(drag_finished_callback);
 
   base::RunLoop drag_loop(base::RunLoop::Type::kNestableTasksAllowed);
   drag_loop_quit_closure_ = drag_loop.QuitClosure();
@@ -269,7 +271,7 @@
 }
 
 void WaylandWindow::PrepareForShutdown() {
-  if (drag_handler_delegate_)
+  if (drag_finished_callback_)
     OnDragSessionClose(DragOperation::kNone);
 }
 
@@ -527,8 +529,7 @@
     return;
 
   // TODO(crbug.com/1102857): get the real event modifier here.
-  drop_handler->OnDragEnter(ToRootWindowPixel(point), std::move(data),
-                            operation,
+  drop_handler->OnDragEnter(point, std::move(data), operation,
                             /*modifiers=*/0);
 }
 
@@ -538,7 +539,7 @@
     return 0;
 
   // TODO(crbug.com/1102857): get the real event modifier here.
-  return drop_handler->OnDragMotion(ToRootWindowPixel(point), operation,
+  return drop_handler->OnDragMotion(point, operation,
                                     /*modifiers=*/0);
 }
 
@@ -558,9 +559,8 @@
 }
 
 void WaylandWindow::OnDragSessionClose(DragOperation operation) {
-  DCHECK(drag_handler_delegate_);
-  drag_handler_delegate_->OnDragFinished(operation);
-  drag_handler_delegate_ = nullptr;
+  DCHECK(drag_finished_callback_);
+  std::move(drag_finished_callback_).Run(operation);
   connection()->event_source()->ResetPointerFlags();
   std::move(drag_loop_quit_closure_).Run();
 }
@@ -971,18 +971,24 @@
     const gfx::Rect& bounds_px) {
   gfx::Rect adjusted_bounds_px = bounds_px;
   if (const auto min_size = delegate_->GetMinimumSizeForWindow()) {
-    if (min_size->width() > 0 && adjusted_bounds_px.width() < min_size->width())
-      adjusted_bounds_px.set_width(min_size->width());
-    if (min_size->height() > 0 &&
-        adjusted_bounds_px.height() < min_size->height())
-      adjusted_bounds_px.set_height(min_size->height());
+    gfx::Size min_size_in_px =
+        delegate()->ConvertRectToPixels(gfx::Rect(*min_size)).size();
+    if (min_size_in_px.width() > 0 &&
+        adjusted_bounds_px.width() < min_size_in_px.width())
+      adjusted_bounds_px.set_width(min_size_in_px.width());
+    if (min_size_in_px.height() > 0 &&
+        adjusted_bounds_px.height() < min_size_in_px.height())
+      adjusted_bounds_px.set_height(min_size_in_px.height());
   }
   if (const auto max_size = delegate_->GetMaximumSizeForWindow()) {
-    if (max_size->width() > 0 && adjusted_bounds_px.width() > max_size->width())
-      adjusted_bounds_px.set_width(max_size->width());
-    if (max_size->height() > 0 &&
-        adjusted_bounds_px.height() > max_size->height())
-      adjusted_bounds_px.set_height(max_size->height());
+    gfx::Size max_size_in_px =
+        delegate()->ConvertRectToPixels(gfx::Rect(*max_size)).size();
+    if (max_size_in_px.width() > 0 &&
+        adjusted_bounds_px.width() > max_size_in_px.width())
+      adjusted_bounds_px.set_width(max_size_in_px.width());
+    if (max_size_in_px.height() > 0 &&
+        adjusted_bounds_px.height() > max_size_in_px.height())
+      adjusted_bounds_px.set_height(max_size_in_px.height());
   }
   return adjusted_bounds_px;
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h
index 843585db..7223874 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.h
+++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -162,7 +162,8 @@
                  mojom::DragEventSource source,
                  gfx::NativeCursor cursor,
                  bool can_grab_pointer,
-                 WmDragHandler::Delegate* delegate) override;
+                 WmDragHandler::DragFinishedCallback drag_finished_callback,
+                 WmDragHandler::LocationDelegate* delegate) override;
   void CancelDrag() override;
 
   // PlatformWindow
@@ -493,7 +494,7 @@
   // AcceleratedWidget for this window. This will be unique even over time.
   gfx::AcceleratedWidget accelerated_widget_;
 
-  WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
+  WmDragHandler::DragFinishedCallback drag_finished_callback_;
 
   base::OnceClosure drag_loop_quit_closure_;
 
diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc
index 39f2565..a5ab6853 100644
--- a/ui/ozone/platform/x11/x11_window.cc
+++ b/ui/ozone/platform/x11/x11_window.cc
@@ -1396,11 +1396,17 @@
 }
 
 absl::optional<gfx::Size> X11Window::GetMinimumSizeForXWindow() {
-  return platform_window_delegate_->GetMinimumSizeForWindow();
+  if (auto max_size = platform_window_delegate_->GetMinimumSizeForWindow())
+    return platform_window_delegate_->ConvertRectToPixels(gfx::Rect(*max_size))
+        .size();
+  return absl::nullopt;
 }
 
 absl::optional<gfx::Size> X11Window::GetMaximumSizeForXWindow() {
-  return platform_window_delegate_->GetMaximumSizeForWindow();
+  if (auto max_size = platform_window_delegate_->GetMaximumSizeForWindow())
+    return platform_window_delegate_->ConvertRectToPixels(gfx::Rect(*max_size))
+        .size();
+  return absl::nullopt;
 }
 
 SkPath X11Window::GetWindowMaskForXWindow() {
@@ -1426,16 +1432,19 @@
   x11_window_move_client_->EndMoveLoop();
 }
 
-bool X11Window::StartDrag(const OSExchangeData& data,
-                          int operations,
-                          mojom::DragEventSource source,
-                          gfx::NativeCursor cursor,
-                          bool can_grab_pointer,
-                          WmDragHandler::Delegate* delegate) {
+bool X11Window::StartDrag(
+    const OSExchangeData& data,
+    int operations,
+    mojom::DragEventSource source,
+    gfx::NativeCursor cursor,
+    bool can_grab_pointer,
+    WmDragHandler::DragFinishedCallback drag_finished_callback,
+    WmDragHandler::LocationDelegate* location_delegate) {
   DCHECK(drag_drop_client_);
-  DCHECK(!drag_handler_delegate_);
+  DCHECK(!drag_location_delegate_);
 
-  drag_handler_delegate_ = delegate;
+  drag_finished_callback_ = std::move(drag_finished_callback);
+  drag_location_delegate_ = location_delegate;
   drag_drop_client_->InitDrag(operations, &data);
   allowed_drag_operations_ = 0;
   notified_enter_ = false;
@@ -1449,7 +1458,7 @@
     return false;
 
   drag_loop_.reset();
-  drag_handler_delegate_ = nullptr;
+  drag_location_delegate_ = nullptr;
   drag_drop_client_->CleanupDrag();
   return dropped;
 }
@@ -1459,8 +1468,8 @@
 }
 
 absl::optional<gfx::AcceleratedWidget> X11Window::GetDragWidget() {
-  DCHECK(drag_handler_delegate_);
-  return drag_handler_delegate_->GetDragWidget();
+  DCHECK(drag_location_delegate_);
+  return drag_location_delegate_->GetDragWidget();
 }
 
 int X11Window::UpdateDrag(const gfx::Point& screen_point) {
@@ -1490,21 +1499,22 @@
 
   XDragDropClient* source_client =
       XDragDropClient::GetForWindow(target_current_context->source_window());
+  gfx::PointF local_point_in_dip =
+      platform_window_delegate_->ConvertScreenPointToLocalDIP(screen_point);
   if (!notified_enter_) {
-    drop_handler->OnDragEnter(gfx::PointF(screen_point), std::move(data),
+    drop_handler->OnDragEnter(local_point_in_dip, std::move(data),
                               suggested_operations,
                               GetKeyModifiers(source_client));
     notified_enter_ = true;
   }
   allowed_drag_operations_ = drop_handler->OnDragMotion(
-      gfx::PointF(screen_point), suggested_operations,
-      GetKeyModifiers(source_client));
+      local_point_in_dip, suggested_operations, GetKeyModifiers(source_client));
   return allowed_drag_operations_;
 }
 
 void X11Window::UpdateCursor(DragOperation negotiated_operation) {
-  DCHECK(drag_handler_delegate_);
-  drag_handler_delegate_->OnDragOperationChanged(negotiated_operation);
+  DCHECK(drag_location_delegate_);
+  drag_location_delegate_->OnDragOperationChanged(negotiated_operation);
 }
 
 void X11Window::OnBeginForeignDrag(x11::Window window) {
@@ -1541,17 +1551,16 @@
 }
 
 void X11Window::EndDragLoop() {
-  DCHECK(drag_handler_delegate_);
-
-  drag_handler_delegate_->OnDragFinished(
-      PreferredDragOperation(allowed_drag_operations_));
+  DCHECK(!drag_finished_callback_.is_null());
+  std::move(drag_finished_callback_)
+      .Run(PreferredDragOperation(allowed_drag_operations_));
   drag_loop_->EndMoveLoop();
 }
 
 void X11Window::OnMouseMovement(const gfx::Point& screen_point,
                                 int flags,
                                 base::TimeTicks event_time) {
-  drag_handler_delegate_->OnDragLocationChanged(screen_point);
+  drag_location_delegate_->OnDragLocationChanged(screen_point);
   drag_drop_client_->HandleMouseMovement(screen_point, flags, event_time);
 }
 
diff --git a/ui/ozone/platform/x11/x11_window.h b/ui/ozone/platform/x11/x11_window.h
index 674c918..0a94e0e 100644
--- a/ui/ozone/platform/x11/x11_window.h
+++ b/ui/ozone/platform/x11/x11_window.h
@@ -177,13 +177,14 @@
   bool RunMoveLoop(const gfx::Vector2d& drag_offset) override;
   void EndMoveLoop() override;
 
-  // WmDragHandler
+  // WmDragHandler:
   bool StartDrag(const OSExchangeData& data,
                  int operations,
                  mojom::DragEventSource source,
                  gfx::NativeCursor cursor,
                  bool can_grab_pointer,
-                 WmDragHandler::Delegate* delegate) override;
+                 WmDragHandler::DragFinishedCallback drag_finished_callback,
+                 WmDragHandler::LocationDelegate* delegate) override;
   void CancelDrag() override;
 
   // XDragDropClient::Delegate
@@ -336,7 +337,8 @@
 
   // Handles XDND events going through this window.
   std::unique_ptr<XDragDropClient> drag_drop_client_;
-  WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
+  WmDragHandler::DragFinishedCallback drag_finished_callback_;
+  WmDragHandler::LocationDelegate* drag_location_delegate_ = nullptr;
 
   // Run loop used while dragging from this window.
   std::unique_ptr<X11MoveLoop> drag_loop_;
diff --git a/ui/platform_window/platform_window_delegate.cc b/ui/platform_window/platform_window_delegate.cc
index 6c47db4e..ea10ab5 100644
--- a/ui/platform_window/platform_window_delegate.cc
+++ b/ui/platform_window/platform_window_delegate.cc
@@ -6,6 +6,7 @@
 
 #include "base/notreached.h"
 #include "third_party/skia/include/core/SkPath.h"
+#include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace ui {
@@ -59,4 +60,9 @@
   return rect_in_pixels;
 }
 
+gfx::PointF PlatformWindowDelegate::ConvertScreenPointToLocalDIP(
+    const gfx::Point& screen_in_pixels) const {
+  return gfx::PointF(screen_in_pixels);
+}
+
 }  // namespace ui
diff --git a/ui/platform_window/platform_window_delegate.h b/ui/platform_window/platform_window_delegate.h
index fc04b12..1bae07b 100644
--- a/ui/platform_window/platform_window_delegate.h
+++ b/ui/platform_window/platform_window_delegate.h
@@ -19,6 +19,7 @@
 namespace gfx {
 class Rect;
 class Size;
+class PointF;
 }  // namespace gfx
 
 class SkPath;
@@ -101,7 +102,7 @@
 
   virtual void OnActivationChanged(bool active) = 0;
 
-  // Requests size constraints for the PlatformWindow.
+  // Requests size constraints for the PlatformWindow in DIP.
   virtual absl::optional<gfx::Size> GetMinimumSizeForWindow();
   virtual absl::optional<gfx::Size> GetMaximumSizeForWindow();
 
@@ -139,8 +140,14 @@
   // Enables or disables frame rate throttling.
   virtual void SetFrameRateThrottleEnabled(bool enabled);
 
+  // Convert gfx::Rect in pixels to DIP in screen, and vice versa.
   virtual gfx::Rect ConvertRectToPixels(const gfx::Rect& rect_in_dp) const;
   virtual gfx::Rect ConvertRectToDIP(const gfx::Rect& rect_in_pixells) const;
+
+  // Convert gfx::Point in screen pixels to dip in the window's local
+  // coordinate.
+  virtual gfx::PointF ConvertScreenPointToLocalDIP(
+      const gfx::Point& screen_in_pixels) const;
 };
 
 }  // namespace ui
diff --git a/ui/platform_window/wm/wm_drag_handler.cc b/ui/platform_window/wm/wm_drag_handler.cc
index 7278eb4..303ae57 100644
--- a/ui/platform_window/wm/wm_drag_handler.cc
+++ b/ui/platform_window/wm/wm_drag_handler.cc
@@ -13,7 +13,7 @@
 
 DEFINE_UI_CLASS_PROPERTY_KEY(WmDragHandler*, kWmDragHandlerKey, nullptr)
 
-WmDragHandler::Delegate::~Delegate() = default;
+WmDragHandler::LocationDelegate::~LocationDelegate() = default;
 
 bool WmDragHandler::ShouldReleaseCaptureForDrag(
     ui::OSExchangeData* data) const {
diff --git a/ui/platform_window/wm/wm_drag_handler.h b/ui/platform_window/wm/wm_drag_handler.h
index 9ba9d9d9..47f7b464 100644
--- a/ui/platform_window/wm/wm_drag_handler.h
+++ b/ui/platform_window/wm/wm_drag_handler.h
@@ -5,6 +5,7 @@
 #ifndef UI_PLATFORM_WINDOW_WM_WM_DRAG_HANDLER_H_
 #define UI_PLATFORM_WINDOW_WM_WM_DRAG_HANDLER_H_
 
+#include "base/callback.h"
 #include "base/component_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
@@ -20,21 +21,25 @@
 
 class COMPONENT_EXPORT(WM) WmDragHandler {
  public:
-  // During the drag operation, the handler may send updates
-  class Delegate {
+  // Notifies when the drag operation finished.
+  using DragFinishedCallback =
+      base::OnceCallback<void(mojom::DragOperation operation)>;
+
+  // A delegate class for a platform on which chrome manages a drag image and
+  // needs to receive the drag location. This can be null if the platform itself
+  // manages the drag image.
+  class LocationDelegate {
    public:
     // Called every time when the drag location has changed.
     virtual void OnDragLocationChanged(const gfx::Point& screen_point_px) = 0;
     // Called when the currently negotiated operation has changed.
     virtual void OnDragOperationChanged(mojom::DragOperation operation) = 0;
-    // Called once when the operation has finished.
-    virtual void OnDragFinished(mojom::DragOperation operation) = 0;
     // DragWidget (if any) should be ignored when finding top window and
     // dispatching mouse events.
     virtual absl::optional<gfx::AcceleratedWidget> GetDragWidget() = 0;
 
    protected:
-    virtual ~Delegate();
+    virtual ~LocationDelegate();
   };
 
   // Starts dragging |data|. Whereas, |operations| is a bitmask of
@@ -42,8 +47,11 @@
   // the drag source. The destination sets the resulting operation when the drop
   // action is performed. |source| indicates the source event type triggering
   // the drag, and |can_grab_pointer| indicates whether the implementation can
-  // grab the mouse pointer (some platforms may need this). In progress updates
-  // on the drag operation come back through the |delegate|.
+  // grab the mouse pointer (some platforms may need this).In progress updates
+  // on the drag operation come back through the |location_delegate| on the
+  // platform that chrome needs manages a drag image). This can be null if the
+  // platform manages a drag image. |drag_finished_callback| is called when drag
+  // operation finishes.
   //
   // This method runs a nested message loop, returning when the drag operation
   // is done. Care must be taken when calling this as it's entirely possible
@@ -56,7 +64,8 @@
                          mojom::DragEventSource source,
                          gfx::NativeCursor cursor,
                          bool can_grab_pointer,
-                         Delegate* delegate) = 0;
+                         DragFinishedCallback drag_finished_callback,
+                         LocationDelegate* location_delegate) = 0;
 
   // Cancels the drag.
   virtual void CancelDrag() = 0;
diff --git a/ui/platform_window/wm/wm_drop_handler.h b/ui/platform_window/wm/wm_drop_handler.h
index 2096843..f76472db 100644
--- a/ui/platform_window/wm/wm_drop_handler.h
+++ b/ui/platform_window/wm/wm_drop_handler.h
@@ -20,7 +20,7 @@
 class COMPONENT_EXPORT(WM) WmDropHandler {
  public:
   // Notifies that drag has entered the window.
-  // |point| is in the coordinate space of the PlatformWindow.
+  // |point| is in the coordinate space of the PlatformWindow in DIP.
   // |operation| contains bitmask of ui::DragDropTypes suggested by the source.
   // |modifiers| contains bitmask of ui::EventFlags that accompany the event.
   virtual void OnDragEnter(const gfx::PointF& point,
@@ -29,7 +29,7 @@
                            int modifiers) = 0;
 
   // Notifies that drag location has changed.
-  // |point| is in the coordinate space of the PlatformWindow.
+  // |point| is in the coordinate space of the PlatformWindow in DIP.
   // |operation| contains bitmask of ui::DragDropTypes suggested by the source.
   // |modifiers| contains bitmask of ui::EventFlags that accompany the event.
   // Returns one of ui::DragDropTypes values selected by the client.
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 0877f321..bf88dbb 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -859,6 +859,12 @@
         ]
         public_deps += [ "//ui/base/dragdrop/mojom:mojom_shared" ]
       }
+      if (is_linux) {
+        sources += [
+          "widget/desktop_aura/desktop_drag_drop_client_ozone_linux.cc",
+          "widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h",
+        ]
+      }
       if (use_atk) {
         sources += [
           "accessibility/view_ax_platform_node_delegate_auralinux.cc",
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc
index 4ef64e16..4671220 100644
--- a/ui/views/controls/table/table_view.cc
+++ b/ui/views/controls/table/table_view.cc
@@ -207,20 +207,26 @@
   return scroll_view;
 }
 
+// static
+Builder<ScrollView> TableView::CreateScrollViewBuilderWithTable(
+    Builder<TableView>&& table) {
+  auto scroll_view = ScrollView::CreateScrollViewWithBorder();
+  auto* scroll_view_ptr = scroll_view.get();
+  return Builder<ScrollView>(std::move(scroll_view))
+      .SetContents(std::move(table).CustomConfigure(base::BindOnce(
+          [](ScrollView* scroll_view, TableView* table_view) {
+            table_view->CreateHeaderIfNecessary(scroll_view);
+          },
+          scroll_view_ptr)));
+}
+
 void TableView::Init(ui::TableModel* model,
                      const std::vector<ui::TableColumn>& columns,
                      TableTypes table_type,
                      bool single_selection) {
-  columns_ = columns;
-  table_type_ = table_type;
-  single_selection_ = single_selection;
-
-  for (const auto& column : columns) {
-    VisibleColumn visible_column;
-    visible_column.column = column;
-    visible_columns_.push_back(visible_column);
-  }
-
+  SetColumns(columns);
+  SetTableType(table_type);
+  SetSingleSelection(single_selection);
   SetModel(model);
 }
 
@@ -244,6 +250,38 @@
   }
 }
 
+void TableView::SetColumns(const std::vector<ui::TableColumn>& columns) {
+  columns_ = columns;
+  visible_columns_.clear();
+  for (const auto& column : columns) {
+    VisibleColumn visible_column;
+    visible_column.column = column;
+    visible_columns_.push_back(visible_column);
+  }
+}
+
+void TableView::SetTableType(TableTypes table_type) {
+  if (table_type_ == table_type)
+    return;
+  table_type_ = table_type;
+  OnPropertyChanged(&table_type_, PropertyEffects::kPropertyEffectsLayout);
+}
+
+TableTypes TableView::GetTableType() const {
+  return table_type_;
+}
+
+void TableView::SetSingleSelection(bool single_selection) {
+  if (single_selection_ == single_selection)
+    return;
+  single_selection_ = single_selection;
+  OnPropertyChanged(&single_selection_, PropertyEffects::kPropertyEffectsPaint);
+}
+
+bool TableView::GetSingleSelection() const {
+  return single_selection_;
+}
+
 void TableView::SetGrouper(TableGrouper* grouper) {
   grouper_ = grouper;
   SortItemsAndUpdateMapping(/*schedule_paint=*/true);
@@ -377,6 +415,17 @@
              ui::ListSelectionModel::kUnselectedIndex;
 }
 
+void TableView::SetObserver(TableViewObserver* observer) {
+  if (observer_ == observer)
+    return;
+  observer_ = observer;
+  OnPropertyChanged(&observer_, PropertyEffects::kPropertyEffectsNone);
+}
+
+TableViewObserver* TableView::GetObserver() const {
+  return observer_;
+}
+
 const TableView::VisibleColumn& TableView::GetVisibleColumn(int index) {
   DCHECK(index >= 0 && index < static_cast<int>(visible_columns_.size()));
   return visible_columns_[index];
@@ -428,10 +477,6 @@
   OnPropertyChanged(&select_on_remove_, kPropertyEffectsNone);
 }
 
-TableTypes TableView::GetTableType() const {
-  return table_type_;
-}
-
 bool TableView::GetSortOnPaint() const {
   return sort_on_paint_;
 }
@@ -1833,9 +1878,11 @@
 ADD_READONLY_PROPERTY_METADATA(bool, HasFocusIndicator)
 ADD_PROPERTY_METADATA(int, ActiveVisibleColumnIndex)
 ADD_READONLY_PROPERTY_METADATA(bool, IsSorted)
+ADD_PROPERTY_METADATA(TableViewObserver*, Observer)
 ADD_READONLY_PROPERTY_METADATA(int, RowHeight)
+ADD_PROPERTY_METADATA(bool, SingleSelection)
 ADD_PROPERTY_METADATA(bool, SelectOnRemove)
-ADD_READONLY_PROPERTY_METADATA(TableTypes, TableType)
+ADD_PROPERTY_METADATA(TableTypes, TableType)
 ADD_PROPERTY_METADATA(bool, SortOnPaint)
 END_METADATA
 
diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h
index 6540096..726353c 100644
--- a/ui/views/controls/table/table_view.h
+++ b/ui/views/controls/table/table_view.h
@@ -14,6 +14,7 @@
 #include "ui/base/models/table_model.h"
 #include "ui/base/models/table_model_observer.h"
 #include "ui/gfx/font_list.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/view.h"
 #include "ui/views/views_export.h"
 
@@ -119,6 +120,11 @@
   static std::unique_ptr<ScrollView> CreateScrollViewWithTable(
       std::unique_ptr<TableView> table);
 
+  // Returns a new Builder<ScrollView> that contains the |table| constructed
+  // from the given Builder<TableView>.
+  static Builder<ScrollView> CreateScrollViewBuilderWithTable(
+      Builder<TableView>&& table);
+
   // Initialize the table with the appropriate data.
   void Init(ui::TableModel* model,
             const std::vector<ui::TableColumn>& columns,
@@ -132,6 +138,14 @@
   void SetModel(ui::TableModel* model);
   ui::TableModel* model() const { return model_; }
 
+  void SetColumns(const std::vector<ui::TableColumn>& columns);
+
+  void SetTableType(TableTypes table_type);
+  TableTypes GetTableType() const;
+
+  void SetSingleSelection(bool single_selection);
+  bool GetSingleSelection() const;
+
   // Sets the TableGrouper. TableView does not own |grouper| (common use case is
   // to have TableModel implement TableGrouper).
   void SetGrouper(TableGrouper* grouper);
@@ -163,9 +177,16 @@
   // Returns whether an active row and column have been set.
   bool GetHasFocusIndicator() const;
 
+  // These functions are deprecated. Favor calling the equivalent functions
+  // below.
   void set_observer(TableViewObserver* observer) { observer_ = observer; }
   TableViewObserver* observer() const { return observer_; }
 
+  // The following are equivalent to the above, but are named for compatibility
+  // with metadata properties and view builder.
+  void SetObserver(TableViewObserver* observer);
+  TableViewObserver* GetObserver() const;
+
   int GetActiveVisibleColumnIndex() const;
 
   void SetActiveVisibleColumnIndex(int index);
@@ -216,8 +237,6 @@
   // Returns the proper ax sort direction.
   ax::mojom::SortDirection GetFirstSortDescriptorDirection() const;
 
-  TableTypes GetTableType() const;
-
   // Updates the relative bounds of the virtual accessibility children created
   // in RebuildVirtualAccessibilityChildren(). This function is public so that
   // the table's |header_| can trigger an update when its visible bounds are
@@ -529,6 +548,24 @@
   base::WeakPtrFactory<TableView> weak_factory_;
 };
 
+BEGIN_VIEW_BUILDER(VIEWS_EXPORT, TableView, View)
+VIEW_BUILDER_PROPERTY(int, ActiveVisibleColumnIndex)
+VIEW_BUILDER_PROPERTY(const std::vector<ui::TableColumn>&,
+                      Columns,
+                      std::vector<ui::TableColumn>)
+VIEW_BUILDER_PROPERTY(ui::TableModel*, Model)
+VIEW_BUILDER_PROPERTY(TableTypes, TableType)
+VIEW_BUILDER_PROPERTY(bool, SingleSelection)
+VIEW_BUILDER_PROPERTY(TableGrouper*, Grouper)
+VIEW_BUILDER_PROPERTY(TableViewObserver*, Observer)
+VIEW_BUILDER_PROPERTY(bool, SelectOnRemove)
+VIEW_BUILDER_PROPERTY(bool, SortOnPaint)
+VIEW_BUILDER_METHOD(SetColumnVisibility, int, bool)
+VIEW_BUILDER_METHOD(SetVisibleColumnWidth, int, int)
+END_VIEW_BUILDER
+
 }  // namespace views
 
+DEFINE_VIEW_BUILDER(VIEWS_EXPORT, views::TableView)
+
 #endif  // UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_H_
diff --git a/ui/views/examples/designer_example.cc b/ui/views/examples/designer_example.cc
index b897bd8..989aabd 100644
--- a/ui/views/examples/designer_example.cc
+++ b/ui/views/examples/designer_example.cc
@@ -495,22 +495,14 @@
                                   &DesignerExample::CreateView,
                                   base::Unretained(this)))
                               .SetText(u"Add"),
-                          Builder<ScrollView>()
-                              .CustomConfigure(base::BindOnce(
-                                  [](DesignerExample* designer_example,
-                                     ScrollView* scroll_view) {
-                                    std::vector<ui::TableColumn> columns = {
-                                        MakeColumn(0, u"Name", true),
-                                        MakeColumn(1, u"Value", false)};
-                                    auto inspector =
-                                        std::make_unique<TableView>(
-                                            designer_example, columns,
-                                            views::TEXT_ONLY, true);
-                                    designer_example->inspector_ =
-                                        scroll_view->SetContents(
-                                            std::move(inspector));
-                                  },
-                                  base::Unretained(this)))
+                          TableView::CreateScrollViewBuilderWithTable(
+                              Builder<TableView>()
+                                  .CopyAddressTo(&inspector_)
+                                  .SetColumns({MakeColumn(0, u"Name", true),
+                                               MakeColumn(1, u"Value", false)})
+                                  .SetModel(this)
+                                  .SetTableType(views::TEXT_ONLY)
+                                  .SetSingleSelection(true))
                               .SetPreferredSize(gfx::Size(250, 400)))))
       .BuildChildren();
   grab_handles_.Initialize(designer_panel_);
diff --git a/ui/views/examples/table_example.cc b/ui/views/examples/table_example.cc
index 1308b78..114d8a4a 100644
--- a/ui/views/examples/table_example.cc
+++ b/ui/views/examples/table_example.cc
@@ -20,6 +20,7 @@
 #include "ui/views/examples/examples_window.h"
 #include "ui/views/layout/flex_layout.h"
 #include "ui/views/layout/flex_layout_types.h"
+#include "ui/views/layout/flex_layout_view.h"
 #include "ui/views/view_class_properties.h"
 
 using base::ASCIIToUTF16;
@@ -28,11 +29,17 @@
 
 namespace {
 
-ui::TableColumn TestTableColumn(int id, const std::string& title) {
+ui::TableColumn TestTableColumn(
+    int id,
+    const std::u16string& title,
+    ui::TableColumn::Alignment alignment = ui::TableColumn::LEFT,
+    float percent = 0.0) {
   ui::TableColumn column;
   column.id = id;
-  column.title = ASCIIToUTF16(title.c_str());
+  column.title = title;
   column.sortable = true;
+  column.alignment = alignment;
+  column.percent = percent;
   return column;
 }
 
@@ -54,50 +61,54 @@
       ->SetOrientation(LayoutOrientation::kVertical);
   observer_.Observe(container);
 
-  std::vector<ui::TableColumn> columns;
-  columns.push_back(TestTableColumn(0, "Fruit"));
-  columns[0].percent = 1;
-  columns.push_back(TestTableColumn(1, "Color"));
-  columns.push_back(TestTableColumn(2, "Origin"));
-  columns.push_back(TestTableColumn(3, "Price"));
-  columns.back().alignment = ui::TableColumn::RIGHT;
-
   auto full_flex = FlexSpecification(MinimumFlexSizeRule::kScaleToZero,
                                      MaximumFlexSizeRule::kUnbounded)
                        .WithWeight(1);
 
-  // Make table
-  auto table = std::make_unique<TableView>(this, columns, ICON_AND_TEXT, true);
-  table->SetGrouper(this);
-  table->set_observer(this);
-  table_ = table.get();
-  container
-      ->AddChildView(TableView::CreateScrollViewWithTable(std::move(table)))
-      ->SetProperty(views::kFlexBehaviorKey, full_flex);
-
-  auto* button_panel = container->AddChildView(std::make_unique<View>());
-  button_panel->SetLayoutManager(std::make_unique<views::FlexLayout>())
-      ->SetOrientation(LayoutOrientation::kHorizontal);
-
-  const auto make_checkbox = [&](std::u16string label, int id) {
-    auto* const checkbox =
-        button_panel->AddChildView(std::make_unique<Checkbox>(
-            std::move(label), Button::PressedCallback()));
-    checkbox->SetCallback(base::BindRepeating(
-        [](TableView* table, int id, Checkbox* checkbox) {
-          table->SetColumnVisibility(id, checkbox->GetChecked());
-        },
-        base::Unretained(table_), id, checkbox));
-    checkbox->SetChecked(true);
-    return checkbox;
+  const auto make_checkbox = [](const std::u16string& label, int id,
+                                raw_ptr<TableView>* table,
+                                raw_ptr<Checkbox>* checkbox,
+                                FlexSpecification full_flex) {
+    return Builder<Checkbox>()
+        .CopyAddressTo(checkbox)
+        .SetText(label)
+        .SetCallback(base::BindRepeating(
+            [](int id, raw_ptr<TableView>* table, raw_ptr<Checkbox>* checkbox) {
+              (*table)->SetColumnVisibility(id, (*checkbox)->GetChecked());
+            },
+            id, table, checkbox))
+        .SetChecked(true)
+        .SetProperty(kFlexBehaviorKey, full_flex);
   };
-  column1_visible_checkbox_ = make_checkbox(u"Fruit column visible", 0);
-  column2_visible_checkbox_ = make_checkbox(u"Color column visible", 1);
-  column3_visible_checkbox_ = make_checkbox(u"Origin column visible", 2);
-  column4_visible_checkbox_ = make_checkbox(u"Price column visible", 3);
 
-  for (View* child : button_panel->children())
-    child->SetProperty(views::kFlexBehaviorKey, full_flex);
+  // Make table
+  Builder<View>(container)
+      .AddChildren(
+          TableView::CreateScrollViewBuilderWithTable(
+              Builder<TableView>()
+                  .CopyAddressTo(&table_)
+                  .SetModel(this)
+                  .SetTableType(ICON_AND_TEXT)
+                  .SetColumns(
+                      {TestTableColumn(0, u"Fruit", ui::TableColumn::LEFT, 1.0),
+                       TestTableColumn(1, u"Color"),
+                       TestTableColumn(2, u"Origin"),
+                       TestTableColumn(3, u"Price", ui::TableColumn::RIGHT)})
+                  .SetGrouper(this)
+                  .SetObserver(this))
+              .SetProperty(kFlexBehaviorKey, full_flex),
+          Builder<FlexLayoutView>()
+              .SetOrientation(LayoutOrientation::kHorizontal)
+              .AddChildren(
+                  make_checkbox(u"Fruit column visible", 0, &table_,
+                                &column1_visible_checkbox_, full_flex),
+                  make_checkbox(u"Color column visible", 1, &table_,
+                                &column2_visible_checkbox_, full_flex),
+                  make_checkbox(u"Origin column visible", 2, &table_,
+                                &column3_visible_checkbox_, full_flex),
+                  make_checkbox(u"Price column visible", 3, &table_,
+                                &column4_visible_checkbox_, full_flex)))
+      .BuildChildren();
 }
 
 int TableExample::RowCount() {
diff --git a/ui/views/metadata/view_factory.h b/ui/views/metadata/view_factory.h
index b4e49aa8..61a6fdf 100644
--- a/ui/views/metadata/view_factory.h
+++ b/ui/views/metadata/view_factory.h
@@ -58,7 +58,18 @@
   }
 
   Builder& CustomConfigure(ConfigureCallback configure_callback) & {
-    configure_callback_ = std::move(configure_callback);
+    // Allow multiple configure callbacks by chaining them.
+    if (configure_callback_) {
+      configure_callback_ = base::BindOnce(
+          [](ConfigureCallback current_callback,
+             ConfigureCallback previous_callback, ViewClass_* root_view) {
+            std::move(current_callback).Run(root_view);
+            std::move(previous_callback).Run(root_view);
+          },
+          std::move(configure_callback), std::move(configure_callback_));
+    } else {
+      configure_callback_ = std::move(configure_callback);
+    }
     return *static_cast<Builder*>(this);
   }
 
diff --git a/ui/views/metadata/view_factory_unittest.cc b/ui/views/metadata/view_factory_unittest.cc
index b291a0c..597dc94 100644
--- a/ui/views/metadata/view_factory_unittest.cc
+++ b/ui/views/metadata/view_factory_unittest.cc
@@ -237,3 +237,20 @@
   EXPECT_EQ(ok_button, view->children()[0]);
   EXPECT_EQ(cancel_button, view->children()[1]);
 }
+
+TEST_F(ViewFactoryTest, TestCustomConfigureChaining) {
+  int callback_count = 0;
+  std::unique_ptr<views::View> view =
+      views::Builder<views::View>()
+          .CustomConfigure(
+              base::BindOnce([](int* callback_count,
+                                views::View* view) { ++(*callback_count); },
+                             &callback_count))
+          .CustomConfigure(
+              base::BindOnce([](int* callback_count,
+                                views::View* view) { ++(*callback_count); },
+                             &callback_count))
+          .Build();
+  // Make sure both callbacks have been called.
+  EXPECT_EQ(callback_count, 2);
+}
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
index 7eb7029..4ef847d4 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
@@ -5,13 +5,10 @@
 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h"
 
 #include <memory>
-#include <string>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
 #include "ui/aura/client/capture_client.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/window.h"
@@ -24,7 +21,6 @@
 #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
 #include "ui/base/layout.h"
 #include "ui/compositor/layer.h"
-#include "ui/display/screen.h"
 #include "ui/ozone/public/ozone_platform.h"
 #include "ui/platform_window/platform_window_delegate.h"
 #include "ui/views/controls/image_view.h"
@@ -35,13 +31,6 @@
 
 using ::ui::mojom::DragOperation;
 
-aura::Window* GetTargetWindow(aura::Window* root_window,
-                              const gfx::Point& point) {
-  gfx::Point root_location(point);
-  root_window->GetHost()->ConvertScreenInPixelsToDIP(&root_location);
-  return root_window->GetEventHandlerForPoint(root_location);
-}
-
 // The minimum alpha required so we would treat the pixel as visible.
 constexpr uint32_t kMinAlpha = 32;
 
@@ -187,7 +176,10 @@
 
   const bool drag_succeeded = drag_handler_->StartDrag(
       *data.get(), allowed_operations, source, cursor_client->GetCursor(),
-      !source_window->HasCapture(), this);
+      !source_window->HasCapture(),
+      base::BindOnce(&DesktopDragDropClientOzone::OnDragFinished,
+                     weak_factory_.GetWeakPtr()),
+      GetLocationDelegate());
 
   if (!alive)
     return DragOperation::kNone;
@@ -322,73 +314,24 @@
   current_drag_info_ = aura::client::DragUpdateInfo();
 }
 
-void DesktopDragDropClientOzone::OnDragLocationChanged(
-    const gfx::Point& screen_point_px) {
-  DCHECK(drag_context_);
-
-  if (!drag_context_->widget)
-    return;
-
-  const bool dispatch_mouse_event = !drag_context_->last_screen_location_px;
-  drag_context_->last_screen_location_px = screen_point_px;
-  if (dispatch_mouse_event) {
-    // Post a task to dispatch mouse movement event when control returns to the
-    // message loop. This allows smoother dragging since the events are
-    // dispatched without waiting for the drag widget updates.
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&DesktopDragDropClientOzone::UpdateDragWidgetLocation,
-                       weak_factory_.GetWeakPtr()));
-  }
-}
-
-void DesktopDragDropClientOzone::OnDragOperationChanged(
-    DragOperation operation) {
-  aura::client::CursorClient* cursor_client =
-      aura::client::GetCursorClient(root_window_);
-  if (!cursor_client)
-    return;
-
-  ui::mojom::CursorType cursor_type = ui::mojom::CursorType::kNull;
-  switch (operation) {
-    case DragOperation::kNone:
-      cursor_type = ui::mojom::CursorType::kDndNone;
-      break;
-    case DragOperation::kMove:
-      cursor_type = ui::mojom::CursorType::kDndMove;
-      break;
-    case DragOperation::kCopy:
-      cursor_type = ui::mojom::CursorType::kDndCopy;
-      break;
-    case DragOperation::kLink:
-      cursor_type = ui::mojom::CursorType::kDndLink;
-      break;
-  }
-  cursor_client->SetCursor(cursor_type);
+ui::WmDragHandler::LocationDelegate*
+DesktopDragDropClientOzone::GetLocationDelegate() {
+  return nullptr;
 }
 
 void DesktopDragDropClientOzone::OnDragFinished(DragOperation operation) {
   drag_operation_ = operation;
 }
 
-absl::optional<gfx::AcceleratedWidget>
-DesktopDragDropClientOzone::GetDragWidget() {
-  DCHECK(drag_context_);
-  if (drag_context_->widget)
-    return drag_context_->widget->GetNativeWindow()
-        ->GetHost()
-        ->GetAcceleratedWidget();
-  return absl::nullopt;
-}
-
 std::unique_ptr<ui::DropTargetEvent>
 DesktopDragDropClientOzone::UpdateTargetAndCreateDropEvent(
-    const gfx::PointF& location,
+    const gfx::PointF& root_location,
     int modifiers) {
   DCHECK(data_to_drop_);
 
-  const gfx::Point point(location.x(), location.y());
-  aura::Window* window = GetTargetWindow(root_window_, point);
+  aura::Window* window =
+      root_window_->GetEventHandlerForPoint(gfx::ToFlooredPoint(root_location));
+
   if (!window) {
     ResetDragDropTarget(true);
     return nullptr;
@@ -406,8 +349,6 @@
   if (!drag_drop_delegate_)
     return nullptr;
 
-  gfx::Point root_location(location.x(), location.y());
-  root_window_->GetHost()->ConvertScreenInPixelsToDIP(&root_location);
   gfx::PointF target_location(root_location);
   aura::Window::ConvertPointToTarget(root_window_, window, &target_location);
 
@@ -420,21 +361,6 @@
   return event;
 }
 
-void DesktopDragDropClientOzone::UpdateDragWidgetLocation() {
-  if (!drag_context_)
-    return;
-
-  float scale_factor =
-      ui::GetScaleFactorForNativeView(drag_context_->widget->GetNativeWindow());
-  gfx::Point scaled_point = gfx::ScaleToRoundedPoint(
-      *drag_context_->last_screen_location_px, 1.f / scale_factor);
-  drag_context_->widget->SetBounds(
-      gfx::Rect(scaled_point - drag_context_->offset, drag_context_->size));
-  drag_context_->widget->StackAtTop();
-
-  drag_context_->last_screen_location_px.reset();
-}
-
 void DesktopDragDropClientOzone::ResetDragDropTarget(bool send_exit) {
   if (drag_drop_delegate_) {
     if (send_exit)
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h
index 2427bae8..30c7365 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h
@@ -18,6 +18,7 @@
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/buildflags.h"
 #include "ui/platform_window/wm/wm_drag_handler.h"
 #include "ui/platform_window/wm/wm_drop_handler.h"
 #include "ui/views/views_export.h"
@@ -37,7 +38,6 @@
 
 class VIEWS_EXPORT DesktopDragDropClientOzone
     : public aura::client::DragDropClient,
-      public ui::WmDragHandler::Delegate,
       public ui::WmDropHandler,
       public aura::WindowObserver {
  public:
@@ -50,7 +50,7 @@
 
   ~DesktopDragDropClientOzone() override;
 
- private:
+ protected:
   friend class DesktopDragDropClientOzoneTest;
 
   // Holds data related to the drag operation started by this client.
@@ -67,6 +67,7 @@
     // The offset of |drag_widget_| relative to the mouse position.
     gfx::Vector2d offset;
 
+#if BUILDFLAG(IS_LINUX)
     // The last received drag location.  The drag widget is moved asynchronously
     // so its position is updated when the UI thread has time for that.  When
     // the first change to the location happens, a call to UpdateDragWidget()
@@ -74,7 +75,9 @@
     // more times until the posted task is executed, but no more than a single
     // call to UpdateDragWidget() is scheduled at any time; this optional is set
     // means that the task is scheduled.
+    // This is used on a platform where chrome manages a drag image (e.g. x11).
     absl::optional<gfx::Point> last_screen_location_px;
+#endif
   };
 
   // aura::client::DragDropClient
@@ -105,11 +108,10 @@
   // aura::WindowObserver
   void OnWindowDestroyed(aura::Window* window) override;
 
-  // ui::WmDragHandler::Delegate
-  void OnDragLocationChanged(const gfx::Point& screen_point_px) override;
-  void OnDragOperationChanged(ui::mojom::DragOperation operation) override;
-  void OnDragFinished(ui::mojom::DragOperation operation) override;
-  absl::optional<gfx::AcceleratedWidget> GetDragWidget() override;
+  // Returns a WmDragHandler::LocationDelegate passed to `StartDrag`.
+  virtual ui::WmDragHandler::LocationDelegate* GetLocationDelegate();
+
+  void OnDragFinished(ui::mojom::DragOperation operation);
 
   // Returns a DropTargetEvent to be passed to the DragDropDelegate.
   // Updates the delegate if needed, which in its turn calls their
@@ -123,14 +125,16 @@
   // Updates |drag_drop_delegate_| along with |window|.
   void UpdateDragDropDelegate(aura::Window* window);
 
-  // Updates |drag_widget_| so it is aligned with the last drag location.
-  void UpdateDragWidgetLocation();
-
   // Resets |drag_drop_delegate_|.
   // |send_exit| controls whether to call delegate's OnDragExited() before
   // resetting.
   void ResetDragDropTarget(bool send_exit);
 
+  DragContext* drag_context() { return drag_context_.get(); }
+
+  aura::Window* root_window() { return root_window_; }
+
+ private:
   aura::Window* const root_window_;
 
   ui::WmDragHandler* const drag_handler_;
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.cc
new file mode 100644
index 0000000..d6f6a8b
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.cc
@@ -0,0 +1,104 @@
+// 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 "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h"
+
+#include "base/bind.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "ui/aura/client/cursor_client.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
+#include "ui/base/data_transfer_policy/data_transfer_policy_controller.h"
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
+#include "ui/base/layout.h"
+#include "ui/views/widget/widget.h"
+
+namespace views {
+
+DesktopDragDropClientOzoneLinux::DesktopDragDropClientOzoneLinux(
+    aura::Window* root_window,
+    ui::WmDragHandler* drag_handler)
+    : DesktopDragDropClientOzone(root_window, drag_handler) {}
+
+DesktopDragDropClientOzoneLinux::~DesktopDragDropClientOzoneLinux() = default;
+
+ui::WmDragHandler::LocationDelegate*
+DesktopDragDropClientOzoneLinux::GetLocationDelegate() {
+  return this;
+}
+
+void DesktopDragDropClientOzoneLinux::OnDragLocationChanged(
+    const gfx::Point& screen_point_px) {
+  DCHECK(drag_context());
+
+  if (!drag_context()->widget)
+    return;
+  const bool dispatch_mouse_event = !drag_context()->last_screen_location_px;
+  drag_context()->last_screen_location_px = screen_point_px;
+  if (dispatch_mouse_event) {
+    // Post a task to dispatch mouse movement event when control returns to the
+    // message loop. This allows smoother dragging since the events are
+    // dispatched without waiting for the drag widget updates.
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &DesktopDragDropClientOzoneLinux::UpdateDragWidgetLocation,
+            weak_factory_.GetWeakPtr()));
+  }
+}
+
+void DesktopDragDropClientOzoneLinux::OnDragOperationChanged(
+    ui::mojom::DragOperation operation) {
+  aura::client::CursorClient* cursor_client =
+      aura::client::GetCursorClient(root_window());
+  if (!cursor_client)
+    return;
+
+  ui::mojom::CursorType cursor_type = ui::mojom::CursorType::kNull;
+  switch (operation) {
+    case ui::mojom::DragOperation::kNone:
+      cursor_type = ui::mojom::CursorType::kDndNone;
+      break;
+    case ui::mojom::DragOperation::kMove:
+      cursor_type = ui::mojom::CursorType::kDndMove;
+      break;
+    case ui::mojom::DragOperation::kCopy:
+      cursor_type = ui::mojom::CursorType::kDndCopy;
+      break;
+    case ui::mojom::DragOperation::kLink:
+      cursor_type = ui::mojom::CursorType::kDndLink;
+      break;
+  }
+  cursor_client->SetCursor(cursor_type);
+}
+
+absl::optional<gfx::AcceleratedWidget>
+DesktopDragDropClientOzoneLinux::GetDragWidget() {
+  DCHECK(drag_context());
+  if (drag_context()->widget)
+    return drag_context()
+        ->widget->GetNativeWindow()
+        ->GetHost()
+        ->GetAcceleratedWidget();
+  return absl::nullopt;
+}
+
+void DesktopDragDropClientOzoneLinux::UpdateDragWidgetLocation() {
+  if (!drag_context())
+    return;
+
+  float scale_factor = ui::GetScaleFactorForNativeView(
+      drag_context()->widget->GetNativeWindow());
+  gfx::Point scaled_point = gfx::ScaleToRoundedPoint(
+      *drag_context()->last_screen_location_px, 1.f / scale_factor);
+  drag_context()->widget->SetBounds(
+      gfx::Rect(scaled_point - drag_context()->offset, drag_context()->size));
+  drag_context()->widget->StackAtTop();
+
+  drag_context()->last_screen_location_px.reset();
+}
+
+}  // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h
new file mode 100644
index 0000000..3bc3a19
--- /dev/null
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h
@@ -0,0 +1,51 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_OZONE_LINUX_H_
+#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_OZONE_LINUX_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/buildflags.h"
+#include "ui/platform_window/wm/wm_drag_handler.h"
+#include "ui/views/views_export.h"
+#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h"
+
+namespace views {
+
+class VIEWS_EXPORT DesktopDragDropClientOzoneLinux
+    : public DesktopDragDropClientOzone,
+      public ui::WmDragHandler::LocationDelegate {
+ public:
+  DesktopDragDropClientOzoneLinux(aura::Window* root_window,
+                                  ui::WmDragHandler* drag_handler);
+
+  DesktopDragDropClientOzoneLinux(const DesktopDragDropClientOzoneLinux&) =
+      delete;
+  DesktopDragDropClientOzoneLinux& operator=(
+      const DesktopDragDropClientOzoneLinux&) = delete;
+
+  ~DesktopDragDropClientOzoneLinux() override;
+
+ private:
+  // DesktopdragDropClientOzone::
+  ui::WmDragHandler::LocationDelegate* GetLocationDelegate() override;
+
+  // ui::WmDragHandler::LocationDelegate:
+  void OnDragLocationChanged(const gfx::Point& screen_point_px) override;
+  void OnDragOperationChanged(ui::mojom::DragOperation operation) override;
+  absl::optional<gfx::AcceleratedWidget> GetDragWidget() override;
+
+  // Updates |drag_widget_| so it is aligned with the last drag location.
+  void UpdateDragWidgetLocation();
+
+  base::WeakPtrFactory<DesktopDragDropClientOzoneLinux> weak_factory_{this};
+};
+
+}  // namespace views
+
+#endif  // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_OZONE_H_
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
index d2da68e7..1facfb2 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
@@ -102,8 +102,9 @@
                  DragEventSource source,
                  gfx::NativeCursor cursor,
                  bool can_grab_pointer,
-                 WmDragHandler::Delegate* delegate) override {
-    drag_handler_delegate_ = delegate;
+                 WmDragHandler::DragFinishedCallback callback,
+                 WmDragHandler::LocationDelegate* delegate) override {
+    drag_finished_callback_ = std::move(callback);
     source_data_ = std::make_unique<OSExchangeData>(data.provider().Clone());
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
@@ -150,7 +151,7 @@
   }
 
   void CloseDrag(DragOperation operation) {
-    drag_handler_delegate_->OnDragFinished(operation);
+    std::move(drag_finished_callback_).Run(operation);
     drag_loop_quit_closure_.Run();
   }
 
@@ -163,7 +164,7 @@
   }
 
  private:
-  WmDragHandler::Delegate* drag_handler_delegate_ = nullptr;
+  WmDragHandler::DragFinishedCallback drag_finished_callback_;
   std::unique_ptr<ui::OSExchangeData> source_data_;
   base::RepeatingClosure drag_loop_quit_closure_;
   int modifiers_ = 0;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
index 8c5adaac..f7310ba 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
@@ -14,6 +14,7 @@
 #include "ui/aura/scoped_window_targeter.h"
 #include "ui/base/buildflags.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/ozone/buildflags.h"
 #include "ui/platform_window/extensions/x11_extension_delegate.h"
 #include "ui/views/views_export.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h"
@@ -99,7 +100,7 @@
   void OnLostMouseGrab() override;
 #if BUILDFLAG(USE_ATK)
   bool OnAtkKeyEvent(AtkKeyEventStruct* atk_key_event, bool transient) override;
-#endif
+#endif  // BUILDFLAG(USE_ATK)
   bool IsOverrideRedirect() const override;
   gfx::Rect GetGuessedFullScreenSizeInPx() const override;
 
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
index c9cbac0..426bffc 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/containers/contains.h"
+#include "base/notreached.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "third_party/skia/include/core/SkPath.h"
@@ -39,6 +40,10 @@
 #include "ui/wm/core/window_util.h"
 #include "ui/wm/public/window_move_client.h"
 
+#if BUILDFLAG(IS_LINUX)
+#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_linux.h"
+#endif
+
 DEFINE_UI_CLASS_PROPERTY_TYPE(views::DesktopWindowTreeHostPlatform*)
 
 namespace views {
@@ -307,7 +312,11 @@
 DesktopWindowTreeHostPlatform::CreateDragDropClient() {
   ui::WmDragHandler* drag_handler = ui::GetWmDragHandler(*(platform_window()));
   std::unique_ptr<DesktopDragDropClientOzone> drag_drop_client =
+#if BUILDFLAG(IS_LINUX)
+      std::make_unique<DesktopDragDropClientOzoneLinux>(window(), drag_handler);
+#else
       std::make_unique<DesktopDragDropClientOzone>(window(), drag_handler);
+#endif  // BUILDFLAG(IS_LINUX)
   // Set a class property key, which allows |drag_drop_client| to be used for
   // drop action.
   SetWmDropHandler(platform_window(), drag_drop_client.get());
@@ -845,14 +854,12 @@
 
 absl::optional<gfx::Size>
 DesktopWindowTreeHostPlatform::GetMinimumSizeForWindow() {
-  return ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize()))
-      .size();
+  return native_widget_delegate_->GetMinimumSize();
 }
 
 absl::optional<gfx::Size>
 DesktopWindowTreeHostPlatform::GetMaximumSizeForWindow() {
-  return ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize()))
-      .size();
+  return native_widget_delegate_->GetMaximumSize();
 }
 
 SkPath DesktopWindowTreeHostPlatform::GetWindowMaskForWindowShapeInPixels() {
@@ -891,6 +898,19 @@
   return ToDIPRect(rect_in_pixels);
 }
 
+gfx::PointF DesktopWindowTreeHostPlatform::ConvertScreenPointToLocalDIP(
+    const gfx::Point& screen_in_pixels) const {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // lacros should not use this.
+  NOTREACHED();
+#endif
+  // TODO(crbug.com/1318279): DIP should use gfx::PointF. Fix this as
+  // a part of cleanup work(crbug.com/1318279).
+  gfx::Point local_dip(screen_in_pixels);
+  ConvertScreenInPixelsToDIP(&local_dip);
+  return gfx::PointF(local_dip);
+}
+
 void DesktopWindowTreeHostPlatform::OnWorkspaceChanged() {
   OnHostWorkspaceChanged();
 }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
index 846869ae7..247ee38 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h
@@ -151,6 +151,8 @@
       override;
   gfx::Rect ConvertRectToPixels(const gfx::Rect& rect_in_dip) const override;
   gfx::Rect ConvertRectToDIP(const gfx::Rect& rect_in_pixels) const override;
+  gfx::PointF ConvertScreenPointToLocalDIP(
+      const gfx::Point& screen_in_pixels) const override;
 
   // ui::WorkspaceExtensionDelegate:
   void OnWorkspaceChanged() override;
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn
index 0d36737..82df8ae 100644
--- a/ui/webui/resources/cr_components/BUILD.gn
+++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -390,12 +390,10 @@
 
 group("polymer3_elements") {
   public_deps = [
-    "customize_themes:web_components",
     "iph_bubble:web_components",
     "localized_link:web_components",
     "managed_dialog:web_components",
     "managed_footnote:web_components",
-    "most_visited:web_components",
   ]
 
   if (is_chromeos_ash) {
diff --git a/ui/webui/resources/cr_components/certificate_manager/BUILD.gn b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
index a33d1f1..d49d464 100644
--- a/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
+++ b/ui/webui/resources/cr_components/certificate_manager/BUILD.gn
@@ -5,6 +5,7 @@
 import("//crypto/features.gni")
 import("//tools/grit/preprocess_if_expr.gni")
 import("//tools/polymer/html_to_js.gni")
+import("//tools/polymer/html_to_wrapper.gni")
 import("//tools/typescript/ts_library.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 import("certificate_manager.gni")
@@ -19,7 +20,7 @@
   out_dir = preprocess_folder
   composite = true
   tsconfig_base = "tsconfig_base.json"
-  in_files = web_component_files + non_web_component_files
+  in_files = ts_files + css_wrapper_files + html_wrapper_files
   definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
 
   deps = [
@@ -32,24 +33,31 @@
   ]
 }
 
-html_to_js("web_components") {
+html_to_js("css_wrapper_files") {
   visibility = [ ":preprocess_generated" ]
-  js_files = web_component_files
+  js_files = css_wrapper_files
+}
+
+html_to_wrapper("html_wrapper_files") {
+  in_files = html_files
 }
 
 preprocess_if_expr("preprocess_src") {
   visibility = [ ":build_ts" ]
   in_folder = "."
   out_folder = preprocess_folder_tmp
-  in_files = non_web_component_files
+  in_files = ts_files
 }
 
 preprocess_if_expr("preprocess_generated") {
   visibility = [ ":build_ts" ]
-  deps = [ ":web_components" ]
+  deps = [
+    ":css_wrapper_files",
+    ":html_wrapper_files",
+  ]
   in_folder = target_gen_dir
   out_folder = preprocess_folder_tmp
-  in_files = web_component_files
+  in_files = html_wrapper_files + css_wrapper_files
 }
 
 generate_grd("build_grdp") {
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 78287ac7..8180f7a 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
@@ -15,13 +15,14 @@
 import './certificate_shared_css.js';
 
 import {PaperSpinnerLiteElement} from 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrCheckboxElement} from '../../cr_elements/cr_checkbox/cr_checkbox.m.js';
 import {CrDialogElement} from '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 import {loadTimeData} from '../../js/load_time_data.m.js';
 
+import {getTemplate} from './ca_trust_edit_dialog.html.js';
 import {CaTrustInfo, CertificatesBrowserProxy, CertificatesBrowserProxyImpl, CertificateSubnode, NewCertificateSubNode} from './certificates_browser_proxy.js';
 
 export interface CaTrustEditDialogElement {
@@ -43,7 +44,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 fc8723f..a187d4d8 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
@@ -10,13 +10,14 @@
 import '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrDialogElement} from '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import {assertNotReached} from '../../js/assert_ts.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 import {loadTimeData} from '../../js/load_time_data.m.js';
 
+import {getTemplate} from './certificate_delete_confirmation_dialog.html.js';
 import {CertificatesBrowserProxyImpl, CertificateSubnode, CertificateType} from './certificates_browser_proxy.js';
 
 export interface CertificateDeleteConfirmationDialogElement {
@@ -36,7 +37,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_entry.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_entry.ts
index 7250cc3..75c4088e 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_entry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_entry.ts
@@ -11,11 +11,12 @@
 import './certificate_shared_css.js';
 import './certificate_subentry.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrPolicyIndicatorType} from '../../cr_elements/policy/cr_policy_indicator_behavior.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 
+import {getTemplate} from './certificate_entry.html.js';
 import {CertificatesOrgGroup, CertificateType} from './certificates_browser_proxy.js';
 
 const CertificateEntryElementBase = I18nMixin(PolymerElement);
@@ -26,7 +27,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 5974094..f78935e 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list.ts
@@ -11,12 +11,13 @@
 import './certificate_entry.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {assertNotReached} from '../../js/assert_ts.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 import {loadTimeData} from '../../js/load_time_data.m.js';
 
+import {getTemplate} from './certificate_list.html.js';
 import {CertificateAction, CertificateActionEvent} from './certificate_manager_types.js';
 import {CertificatesBrowserProxyImpl, CertificatesError, CertificatesImportError, CertificatesOrgGroup, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js';
 
@@ -37,7 +38,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.gni b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.gni
index eceefb82..93aecc8 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.gni
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.gni
@@ -4,7 +4,8 @@
 
 import("//build/config/chromeos/ui_mode.gni")
 
-web_component_files = [
+# Files holding a Polymer element definition AND have an equivalent .html file.
+_web_component_files = [
   "ca_trust_edit_dialog.ts",
   "certificate_delete_confirmation_dialog.ts",
   "certificate_entry.ts",
@@ -12,24 +13,39 @@
   "certificate_manager.ts",
   "certificate_password_decryption_dialog.ts",
   "certificate_password_encryption_dialog.ts",
-  "certificate_shared_css.ts",
   "certificate_subentry.ts",
   "certificates_error_dialog.ts",
 ]
 
 if (is_chromeos_ash) {
-  web_component_files += [
+  _web_component_files += [
     "certificate_provisioning_details_dialog.ts",
     "certificate_provisioning_entry.ts",
     "certificate_provisioning_list.ts",
   ]
 }
 
-non_web_component_files = [
+# Files that are passed as input to html_to_wrapper().
+html_files = []
+foreach(f, _web_component_files) {
+  html_files += [ string_replace(f, ".ts", ".html") ]
+}
+
+# Files that are generated by html_to_wrapper().
+html_wrapper_files = []
+foreach(f, html_files) {
+  html_wrapper_files += [ f + ".ts" ]
+}
+
+_non_web_component_files = [
   "certificate_manager_types.ts",
   "certificates_browser_proxy.ts",
 ]
 
 if (is_chromeos_ash) {
-  non_web_component_files += [ "certificate_provisioning_browser_proxy.ts" ]
+  _non_web_component_files += [ "certificate_provisioning_browser_proxy.ts" ]
 }
+
+ts_files = _web_component_files + _non_web_component_files
+
+css_wrapper_files = [ "certificate_shared_css.ts" ]
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 9cb5f8a7..bd8b812 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
@@ -16,15 +16,17 @@
 import './certificates_error_dialog.js';
 // <if expr="chromeos_ash">
 import './certificate_provisioning_list.js';
+
 // </if>
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {focusWithoutInk} from '../../js/cr/ui/focus_without_ink.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 import {loadTimeData} from '../../js/load_time_data.m.js';
 import {WebUIListenerMixin} from '../../js/web_ui_listener_mixin.js';
 
+import {getTemplate} from './certificate_manager.html.js';
 import {CertificateAction, CertificateActionEvent} from './certificate_manager_types.js';
 import {CertificatesBrowserProxyImpl, CertificatesError, CertificatesImportError, CertificatesOrgGroup, CertificateSubnode, CertificateType, NewCertificateSubNode} from './certificates_browser_proxy.js';
 
@@ -36,6 +38,10 @@
     return 'certificate-manager';
   }
 
+  static get template() {
+    return getTemplate();
+  }
+
   static get properties() {
     return {
       selected: {
@@ -271,10 +277,6 @@
       loadTimeData.getString('certificateManagerOthers'),
     ];
   }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
 }
 
 declare global {
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 c42db59..4549a1b 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
@@ -11,12 +11,13 @@
 import '../../cr_elements/cr_input/cr_input.m.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {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';
 
+import {getTemplate} from './certificate_password_decryption_dialog.html.js';
 import {CertificatesBrowserProxyImpl} from './certificates_browser_proxy.js';
 
 export interface CertificatePasswordDecryptionDialogElement {
@@ -36,7 +37,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 bf89a12a..38d6bd9 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
@@ -12,12 +12,13 @@
 import '../../cr_elements/shared_vars_css.m.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {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';
 
+import {getTemplate} from './certificate_password_encryption_dialog.html.js';
 import {CertificatesBrowserProxyImpl} from './certificates_browser_proxy.js';
 
 export interface CertificatePasswordEncryptionDialogElement {
@@ -37,7 +38,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 53cf602..6cb8d99 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
@@ -10,12 +10,13 @@
 import '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrDialogElement} from '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 
 import {CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js';
+import {getTemplate} from './certificate_provisioning_details_dialog.html.js';
 
 export interface CertificateProvisioningDetailsDialogElement {
   $: {
@@ -34,7 +35,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 59fed70..91a3e279 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
@@ -12,7 +12,7 @@
 import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrActionMenuElement} from '../../cr_elements/cr_action_menu/cr_action_menu.js';
 import {CrLazyRenderElement} from '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js';
@@ -20,6 +20,7 @@
 
 import {CertificateProvisioningViewDetailsActionEvent} from './certificate_manager_types.js';
 import {CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js';
+import {getTemplate} from './certificate_provisioning_entry.html.js';
 
 export interface CertificateProvisioningEntryElement {
   $: {
@@ -37,7 +38,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 713225a..70f6550 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
@@ -11,7 +11,7 @@
 import './certificate_provisioning_details_dialog.js';
 import './certificate_provisioning_entry.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {focusWithoutInk} from '../../js/cr/ui/focus_without_ink.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
@@ -19,6 +19,7 @@
 
 import {CertificateProvisioningViewDetailsActionEvent} from './certificate_manager_types.js';
 import {CertificateProvisioningBrowserProxyImpl, CertificateProvisioningProcess} from './certificate_provisioning_browser_proxy.js';
+import {getTemplate} from './certificate_provisioning_list.html.js';
 
 const CertificateProvisioningListElementBase =
     WebUIListenerMixin(I18nMixin(PolymerElement));
@@ -30,7 +31,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
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 03f073a..0af6f210 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.ts
@@ -13,7 +13,7 @@
 import '../../cr_elements/icons.m.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrActionMenuElement} from '../../cr_elements/cr_action_menu/cr_action_menu.js';
 import {CrLazyRenderElement} from '../../cr_elements/cr_lazy_render/cr_lazy_render.m.js';
@@ -21,6 +21,7 @@
 import {I18nMixin} from '../../js/i18n_mixin.js';
 
 import {CertificateAction, CertificateActionEvent} from './certificate_manager_types.js';
+import {getTemplate} from './certificate_subentry.html.js';
 import {CertificatesBrowserProxy, CertificatesBrowserProxyImpl, CertificatesError, CertificateSubnode, CertificateType} from './certificates_browser_proxy.js';
 
 export interface CertificateSubentryElement {
@@ -38,7 +39,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
index f53069a6..fbbe882f 100644
--- a/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
+++ b/ui/webui/resources/cr_components/certificate_manager/certificates_error_dialog.ts
@@ -10,13 +10,14 @@
 import '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import './certificate_shared_css.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CrDialogElement} from '../../cr_elements/cr_dialog/cr_dialog.m.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 import {loadTimeData} from '../../js/load_time_data.m.js';
 
 import {CertificatesError, CertificatesImportError} from './certificates_browser_proxy.js';
+import {getTemplate} from './certificates_error_dialog.html.js';
 
 interface CertificatesErrorDialogElement {
   $: {
@@ -33,7 +34,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
diff --git a/ui/webui/resources/cr_components/customize_themes/BUILD.gn b/ui/webui/resources/cr_components/customize_themes/BUILD.gn
index afdbf931..4e8b44d 100644
--- a/ui/webui/resources/cr_components/customize_themes/BUILD.gn
+++ b/ui/webui/resources/cr_components/customize_themes/BUILD.gn
@@ -4,19 +4,13 @@
 
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//tools/grit/preprocess_if_expr.gni")
-import("//tools/polymer/html_to_js.gni")
+import("//tools/polymer/html_to_wrapper.gni")
 import("//tools/typescript/ts_library.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
+import("customize_themes.gni")
 
 assert(!is_android && !is_ios)
 
-group("web_components") {
-  public_deps = [
-    ":mojom_webui_js",
-    ":web_components_local",
-  ]
-}
-
 mojom("mojom") {
   sources = [ "customize_themes.mojom" ]
 
@@ -28,11 +22,8 @@
   webui_module_path = "chrome://resources/cr_components/customize_themes/"
 }
 
-html_to_js("web_components_local") {
-  js_files = [
-    "customize_themes.ts",
-    "theme_icon.ts",
-  ]
+html_to_wrapper("html_wrapper_files") {
+  in_files = html_files
 }
 
 # Output folder used to hold preprocess_if_expr() output.
@@ -46,12 +37,7 @@
   out_dir = preprocess_folder
   composite = true
   tsconfig_base = "tsconfig_base.json"
-  in_files = [
-    "browser_proxy.ts",
-    "customize_themes.ts",
-    "customize_themes.mojom-webui.js",
-    "theme_icon.ts",
-  ]
+  in_files = ts_files + html_wrapper_files + mojo_files
 
   deps = [
     "//third_party/polymer/v3_0:library",
@@ -66,19 +52,16 @@
 }
 
 preprocess_if_expr("preprocess_src") {
-  in_folder = "./"
+  in_folder = "."
   out_folder = preprocess_folder_tmp
-  in_files = [ "browser_proxy.ts" ]
+  in_files = ts_files
 }
 
 preprocess_if_expr("preprocess_generated") {
-  deps = [ ":web_components_local" ]
+  deps = [ ":html_wrapper_files" ]
   in_folder = target_gen_dir
   out_folder = preprocess_folder_tmp
-  in_files = [
-    "customize_themes.ts",
-    "theme_icon.ts",
-  ]
+  in_files = html_wrapper_files
 }
 
 copy("copy_mojom") {
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.gni b/ui/webui/resources/cr_components/customize_themes/customize_themes.gni
new file mode 100644
index 0000000..9677cc6e
--- /dev/null
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.gni
@@ -0,0 +1,27 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Files holding a Polymer element definition AND have an equivalent .html file.
+_web_component_files = [
+  "customize_themes.ts",
+  "theme_icon.ts",
+]
+
+# Files that are passed as input to html_to_wrapper().
+html_files = []
+foreach(f, _web_component_files) {
+  html_files += [ string_replace(f, ".ts", ".html") ]
+}
+
+# Files that are generated by html_to_wrapper().
+html_wrapper_files = []
+foreach(f, html_files) {
+  html_wrapper_files += [ f + ".ts" ]
+}
+
+_non_web_component_files = [ "browser_proxy.ts" ]
+
+mojo_files = [ "customize_themes.mojom-webui.js" ]
+
+ts_files = _web_component_files + _non_web_component_files
diff --git a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
index 71347da..5a8ba09c 100644
--- a/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
+++ b/ui/webui/resources/cr_components/customize_themes/customize_themes.ts
@@ -14,13 +14,14 @@
 
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 import {DomRepeat} from 'chrome://resources/polymer/v3_0/polymer/lib/elements/dom-repeat.js';
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {assert} from '../../js/assert.m.js';
 import {hexColorToSkColor, skColorToRgba} from '../../js/color_utils.js';
 import {I18nMixin} from '../../js/i18n_mixin.js';
 
 import {CustomizeThemesBrowserProxyImpl} from './browser_proxy.js';
+import {getTemplate} from './customize_themes.html.js';
 import {ChromeTheme, CustomizeThemesClientCallbackRouter, CustomizeThemesHandlerInterface, Theme, ThemeType} from './customize_themes.mojom-webui.js';
 import {ThemeIconElement} from './theme_icon.js';
 
@@ -44,6 +45,10 @@
     return 'cr-customize-themes';
   }
 
+  static get template() {
+    return getTemplate();
+  }
+
   static get properties() {
     return {
       /**
@@ -230,10 +235,6 @@
   private onManagedDialogClosed_() {
     this.showManagedThemeDialog_ = false;
   }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
 }
 
 declare global {
diff --git a/ui/webui/resources/cr_components/customize_themes/theme_icon.ts b/ui/webui/resources/cr_components/customize_themes/theme_icon.ts
index b77fa963..29c05a55 100644
--- a/ui/webui/resources/cr_components/customize_themes/theme_icon.ts
+++ b/ui/webui/resources/cr_components/customize_themes/theme_icon.ts
@@ -4,7 +4,9 @@
 
 import '../../cr_elements/shared_vars_css.m.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './theme_icon.html.js';
 
 /**
  * Represents a theme. Displayed as a circle with each half colored based on
@@ -18,7 +20,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 }
 
diff --git a/ui/webui/resources/cr_components/most_visited/BUILD.gn b/ui/webui/resources/cr_components/most_visited/BUILD.gn
index d41ce59..b89c7b3 100644
--- a/ui/webui/resources/cr_components/most_visited/BUILD.gn
+++ b/ui/webui/resources/cr_components/most_visited/BUILD.gn
@@ -3,9 +3,10 @@
 # found in the LICENSE file.
 
 import("//mojo/public/tools/bindings/mojom.gni")
-import("//tools/polymer/html_to_js.gni")
+import("//tools/polymer/html_to_wrapper.gni")
 import("//tools/typescript/ts_library.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
+import("most_visited.gni")
 
 assert(!is_android && !is_ios)
 
@@ -22,15 +23,8 @@
   webui_module_path = "chrome://resources/cr_components/most_visited/"
 }
 
-html_to_js("web_components_local") {
-  js_files = [ "most_visited.ts" ]
-}
-
-group("web_components") {
-  public_deps = [
-    ":mojom_webui_js",
-    ":web_components_local",
-  ]
+html_to_wrapper("html_wrapper_files") {
+  in_files = html_files
 }
 
 copy("copy_mojom") {
@@ -40,10 +34,7 @@
 }
 
 copy("copy_src") {
-  sources = [
-    "browser_proxy.ts",
-    "window_proxy.ts",
-  ]
+  sources = ts_files
   outputs = [ "$target_gen_dir/{{source_file_part}}" ]
 }
 
@@ -51,10 +42,7 @@
   grd_prefix = "cr_components_most_visited"
   out_grd = "$target_gen_dir/resources.grdp"
 
-  deps = [
-    ":build_ts",
-    ":mojom_webui_js",
-  ]
+  deps = [ ":build_ts" ]
   manifest_files = [ "$target_gen_dir/tsconfig.manifest" ]
   resource_path_prefix = "cr_components/most_visited"
 }
@@ -64,12 +52,7 @@
   out_dir = preprocess_folder
   composite = true
   tsconfig_base = "tsconfig_base.json"
-  in_files = [
-    "browser_proxy.ts",
-    "most_visited.ts",
-    "most_visited.mojom-webui.js",
-    "window_proxy.ts",
-  ]
+  in_files = ts_files + html_wrapper_files + mojo_files
   deps = [
     "//third_party/polymer/v3_0:library",
     "//ui/webui/resources:library",
@@ -78,6 +61,6 @@
   extra_deps = [
     ":copy_mojom",
     ":copy_src",
-    ":web_components_local",
+    ":html_wrapper_files",
   ]
 }
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.gni b/ui/webui/resources/cr_components/most_visited/most_visited.gni
new file mode 100644
index 0000000..5d87a5c
--- /dev/null
+++ b/ui/webui/resources/cr_components/most_visited/most_visited.gni
@@ -0,0 +1,27 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Files holding a Polymer element definition AND have an equivalent .html file.
+_web_component_files = [ "most_visited.ts" ]
+
+# Files that are passed as input to html_to_wrapper().
+html_files = []
+foreach(f, _web_component_files) {
+  html_files += [ string_replace(f, ".ts", ".html") ]
+}
+
+# Files that are generated by html_to_wrapper().
+html_wrapper_files = []
+foreach(f, html_files) {
+  html_wrapper_files += [ f + ".ts" ]
+}
+
+_non_web_component_files = [
+  "browser_proxy.ts",
+  "window_proxy.ts",
+]
+
+mojo_files = [ "most_visited.mojom-webui.js" ]
+
+ts_files = _web_component_files + _non_web_component_files
diff --git a/ui/webui/resources/cr_components/most_visited/most_visited.ts b/ui/webui/resources/cr_components/most_visited/most_visited.ts
index 614f979..f10b010 100644
--- a/ui/webui/resources/cr_components/most_visited/most_visited.ts
+++ b/ui/webui/resources/cr_components/most_visited/most_visited.ts
@@ -25,9 +25,10 @@
 import {TextDirection} from 'chrome://resources/mojo/mojo/public/mojom/base/text_direction.mojom-webui.js';
 import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
 import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js';
-import {DomRepeat, DomRepeatEvent, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {DomRepeat, DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {MostVisitedBrowserProxy} from './browser_proxy.js';
+import {getTemplate} from './most_visited.html.js';
 import {MostVisitedInfo, MostVisitedPageCallbackRouter, MostVisitedPageHandlerRemote, MostVisitedTheme, MostVisitedTile} from './most_visited.mojom-webui.js';
 import {MostVisitedWindowProxy} from './window_proxy.js';
 
@@ -88,6 +89,10 @@
     return 'cr-most-visited';
   }
 
+  static get template() {
+    return getTemplate();
+  }
+
   static get properties() {
     return {
       theme: Object,
@@ -833,10 +838,6 @@
         this.tiles_.slice(0, assert(this.maxVisibleTiles_)),
         this.windowProxy_.now());
   }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
 }
 
 declare global {
diff --git a/url/BUILD.gn b/url/BUILD.gn
index 506d34ee..f1e7275d 100644
--- a/url/BUILD.gn
+++ b/url/BUILD.gn
@@ -131,7 +131,6 @@
   android_library("url_java") {
     sources = [ "android/java/src/org/chromium/url/IDNStringUtil.java" ]
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//build/android:build_java",
     ]
@@ -155,7 +154,6 @@
   android_library("origin_java") {
     sources = [ "android/java/src/org/chromium/url/Origin.java" ]
     deps = [
-      "//base:base_java",
       "//base:jni_java",
       "//mojo/public/java:bindings_java",
       "//mojo/public/mojom/base:base_java",
@@ -299,7 +297,6 @@
         [ "android/javatests/src/org/chromium/url/GURLJavaTestHelper.java" ]
     deps = [
       ":gurl_java",
-      "//base:base_java",
       "//base:base_java_test_support",
       "//base:jni_java",
       "//build/android:build_java",
@@ -370,7 +367,6 @@
       ":gurl_java",
       ":gurl_junit_shadows",
       ":gurl_junit_test_support",
-      "//base:base_java",
       "//base:base_java_test_support",
       "//base:base_junit_test_support",
       "//base/test:test_support_java",
diff --git a/weblayer/browser/autofill_assistant/weblayer_dependencies.cc b/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
index 10ad755a..358a556 100644
--- a/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
+++ b/weblayer/browser/autofill_assistant/weblayer_dependencies.cc
@@ -35,6 +35,20 @@
       new WebLayerDependencies(env, jstatic_dependencies)));
 }
 
+static ScopedJavaLocalRef<jobject>
+JNI_WebLayerAssistantStaticDependencies_GetJavaProfile(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& java_web_contents) {
+  content::WebContents* web_contents =
+      content::WebContents::FromJavaWebContents(java_web_contents);
+  if (!web_contents) {
+    return nullptr;
+  }
+  return ScopedJavaLocalRef<jobject>(
+      ProfileImpl::FromBrowserContext(web_contents->GetBrowserContext())
+          ->GetJavaProfile());
+}
+
 WebLayerDependencies::WebLayerDependencies(
     JNIEnv* env,
     const JavaParamRef<jobject>& jstatic_dependencies)
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn
index da76ba4..00790e1 100644
--- a/weblayer/browser/java/BUILD.gn
+++ b/weblayer/browser/java/BUILD.gn
@@ -379,7 +379,6 @@
     ":java",
     ":test_interfaces_java",
     ":weblayer_test_resources",
-    "//base:base_java",
     "//base:jni_java",
     "//build/android:build_java",
     "//components/android_autofill/browser:java",
@@ -412,7 +411,6 @@
   testonly = true
   deps = [
     ":java",
-    "//base:base_java",
     "//build/android:build_java",
     "//components/payments/content/android:java",
     "//components/payments/content/android:junit_test_support",
@@ -442,7 +440,6 @@
   deps = [
     ":java",
     ":junit_test_support",
-    "//base:base_java",
     "//base:base_java_test_support",
     "//base:base_junit_test_support",
     "//build/android:build_java",
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java b/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java
index cdf2823..5e17f9f 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantDependencies.java
@@ -24,7 +24,8 @@
  */
 public class WebLayerAssistantDependencies
         extends WebLayerAssistantStaticDependencies implements AssistantDependencies {
-    public WebLayerAssistantDependencies(Activity activity) {
+    public WebLayerAssistantDependencies(Activity activity, WebContents webContents) {
+        super(webContents);
         maybeUpdateDependencies(activity);
     }
 
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java b/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java
index 825a7b8..6504e82b 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/autofill_assistant/WebLayerAssistantStaticDependencies.java
@@ -27,6 +27,7 @@
 import org.chromium.components.favicon.LargeIconBridge;
 import org.chromium.components.image_fetcher.ImageFetcher;
 import org.chromium.content_public.browser.BrowserContextHandle;
+import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.util.AccessibilityUtil;
 import org.chromium.weblayer_private.ProfileImpl;
@@ -38,15 +39,21 @@
  */
 @JNINamespace("weblayer")
 public class WebLayerAssistantStaticDependencies implements AssistantStaticDependencies {
+    private final WebContents mWebContents;
+
+    WebLayerAssistantStaticDependencies(WebContents webContents) {
+        mWebContents = webContents;
+    }
+
     @Override
     public long createNative() {
         return WebLayerAssistantStaticDependenciesJni.get().init(
-                new WebLayerAssistantStaticDependencies());
+                new WebLayerAssistantStaticDependencies(mWebContents));
     }
 
     @Override
     public AssistantDependencies createDependencies(Activity activity) {
-        return new WebLayerAssistantDependencies(activity);
+        return new WebLayerAssistantDependencies(activity, mWebContents);
     }
 
     @Override
@@ -93,8 +100,7 @@
 
     @Override
     public BrowserContextHandle getBrowserContext() {
-        // TODO(b/222671580): Implement
-        return null;
+        return WebLayerAssistantStaticDependenciesJni.get().getJavaProfile(mWebContents);
     }
 
     @Override
@@ -138,5 +144,7 @@
     @NativeMethods
     interface Natives {
         long init(AssistantStaticDependencies staticDependencies);
+
+        ProfileImpl getJavaProfile(WebContents webContents);
     }
 }
diff --git a/weblayer/public/javatests/BUILD.gn b/weblayer/public/javatests/BUILD.gn
index 36fdd8b..ab2d4d6 100644
--- a/weblayer/public/javatests/BUILD.gn
+++ b/weblayer/public/javatests/BUILD.gn
@@ -12,7 +12,6 @@
     "org/chromium/weblayer/WebViewCompatibilityHelperTest.java",
   ]
   deps = [
-    "//base:base_java",
     "//base:base_java_test_support",
     "//build/android:build_java",
     "//third_party/android_support_test_runner:runner_java",
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn
index 6cb4d8c79..4ba433e 100644
--- a/weblayer/shell/android/BUILD.gn
+++ b/weblayer/shell/android/BUILD.gn
@@ -236,7 +236,6 @@
     "//android_webview:locale_pak_assets",
     "//android_webview:pak_file_assets",
     "//android_webview:weblayer_webview_assets",
-    "//base:base_java",
     "//build/android:build_java",
     "//weblayer:locale_pak_assets",
     "//weblayer/browser/java",